Files
kitty/kittens/dnd/render.go
2026-04-23 08:51:28 +05:30

121 lines
3.4 KiB
Go

package dnd
import (
"fmt"
"strings"
"github.com/kovidgoyal/kitty/tools/tui/loop"
"github.com/kovidgoyal/kitty/tools/wcswidth"
)
var _ = fmt.Print
func (dnd *dnd) render_screen() error {
lp := dnd.lp
if !dnd.in_test_mode {
lp.StartAtomicUpdate()
defer lp.EndAtomicUpdate()
}
lp.ClearScreen()
dnd.copy_button_region, dnd.move_button_region = button_region{}, button_region{}
if dnd.drag_started {
lp.Println("Dragging data...")
return nil
}
if dnd.drop_status.reading_data {
lp.Println("Reading dropped data, please wait...")
return nil
}
y := 0
sz, _ := lp.ScreenSize()
render_paragraph := func(text string) {
for _, line := range paragraph_as_lines(text, int(sz.WidthCells)) {
lp.Println(line)
y++
}
}
next_line := func() {
lp.Println()
y++
}
if dnd.drop_status.in_window {
if dnd.drop_status.action == 0 {
render_paragraph("A drag is active. Drop it into one of the boxes below to perform that action on the dragged data. Available MIME types in the drag:")
next_line()
render_paragraph(strings.Join(dnd.drop_status.offered_mimes, " "))
} else {
render_paragraph("The drag can be dropped. Supported MIME types:")
next_line()
render_paragraph(strings.Join(dnd.drop_status.accepted_mimes, " "))
}
} else {
// Neither active drag nor drop over window
if dnd.allow_drags {
render_paragraph(`Start dragging anywhere in this window to initiate a drag and drop. If you start the drag in one of the Copy or Move boxes below, only that action will be allowed when dropping, otherwise, the drop destination can pick either copy or move.`)
next_line()
}
if dnd.allow_drops {
if dnd.data_has_been_dropped {
render_paragraph(`Data has been successfully dropped. You can drop more data or press Esc to quit.`)
} else {
render_paragraph(`Drag some data from another application into this window to transfer the files here.`)
}
}
}
frame_width, padding_width := 4, 8
text_width := len("copymove")
scale := 5
for scale > 1 && frame_width+padding_width+text_width*scale > int(sz.WidthCells) {
scale--
}
height := scale + 4
boxy := 1 + max(0, int(sz.HeightCells)-height)
lp.MoveCursorTo(1, boxy)
lp.ClearToEndOfScreen()
render_box := func(x int, text string, r *button_region) {
width := scale*wcswidth.Stringwidth(text) + 6
r.left = x - 1
r.top = boxy - 1
r.width = width
r.height = height
lp.MoveCursorTo(x, boxy)
for i := range height {
lp.SaveCursorPosition()
switch i {
case 0:
lp.QueueWriteString("╭")
lp.QueueWriteString(strings.Repeat("─", width-2))
lp.QueueWriteString("╮")
case height - 1:
lp.QueueWriteString("╰")
lp.QueueWriteString(strings.Repeat("─", width-2))
lp.QueueWriteString("╯")
default:
lp.QueueWriteString("│")
if i == 2 {
lp.MoveCursorHorizontally(2)
lp.DrawSizedText(text, loop.SizedText{Scale: scale})
}
lp.MoveCursorTo(x+width-1, boxy+i)
lp.QueueWriteString("│")
}
lp.RestoreCursorPosition()
lp.MoveCursorVertically(1)
}
}
const fg = 32
if dnd.drop_status.action == copy_on_drop {
lp.Printf("\x1b[%dm", fg)
}
render_box(1, "Copy", &dnd.copy_button_region)
lp.QueueWriteString("\x1b[39m")
box_width := 6 + len("move")*scale
if dnd.drop_status.action == move_on_drop {
lp.Printf("\x1b[%dm", fg)
}
render_box(1+int(sz.WidthCells)-box_width, "Move", &dnd.move_button_region)
lp.QueueWriteString("\x1b[39m")
return nil
}