More work on the DnD kitten
This commit is contained in:
parent
a0a81dbe88
commit
3165a47579
4 changed files with 57 additions and 9 deletions
|
|
@ -13,6 +13,7 @@ import (
|
||||||
|
|
||||||
"github.com/emmansun/base64"
|
"github.com/emmansun/base64"
|
||||||
"github.com/kovidgoyal/imaging"
|
"github.com/kovidgoyal/imaging"
|
||||||
|
"github.com/kovidgoyal/kitty/tools/icons"
|
||||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||||
"github.com/kovidgoyal/kitty/tools/utils"
|
"github.com/kovidgoyal/kitty/tools/utils"
|
||||||
"github.com/kovidgoyal/kitty/tools/utils/streaming_base64"
|
"github.com/kovidgoyal/kitty/tools/utils/streaming_base64"
|
||||||
|
|
@ -53,11 +54,15 @@ type drag_status struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func find_drag_image(drag_sources map[string]*drag_source) image.Image {
|
func find_drag_image(drag_sources map[string]*drag_source) image.Image {
|
||||||
|
all_paths := []string{}
|
||||||
for mime, ds := range drag_sources {
|
for mime, ds := range drag_sources {
|
||||||
if strings.HasPrefix(mime, "image/") && ds.path != "" {
|
if ds.path != "" {
|
||||||
q, err := imaging.Open(ds.path)
|
all_paths = append(all_paths, ds.path)
|
||||||
if err == nil {
|
if strings.HasPrefix(mime, "image/") {
|
||||||
return q
|
q, err := imaging.Open(ds.path)
|
||||||
|
if err == nil {
|
||||||
|
return q
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -67,6 +72,7 @@ func find_drag_image(drag_sources map[string]*drag_source) image.Image {
|
||||||
for _, path := range q {
|
for _, path := range q {
|
||||||
if path != "" {
|
if path != "" {
|
||||||
uri_list = append(uri_list, path)
|
uri_list = append(uri_list, path)
|
||||||
|
all_paths = append(all_paths, path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +83,47 @@ func find_drag_image(drag_sources map[string]*drag_source) image.Image {
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Try to generate an image based preview using the machinery from the choose-files kitten
|
for _, path := range all_paths {
|
||||||
|
_ = path
|
||||||
|
// TODO: Try to generate an image based preview using the machinery from the choose-files kitten
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dnd *dnd) set_drag_image_text() (err error) {
|
||||||
|
icon := ""
|
||||||
|
from_path := func(path string) bool {
|
||||||
|
if st, err := os.Lstat(path); err == nil {
|
||||||
|
ans := strings.TrimSpace(icons.IconForFileWithMode(path, st.Mode(), true))
|
||||||
|
if ans != "" {
|
||||||
|
icon = ans
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, ds := range dnd.drag_sources {
|
||||||
|
if ds.path != "" && from_path(ds.path) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if icon == "" {
|
||||||
|
if ds := dnd.drag_sources["text/uri-list"]; ds != nil && len(ds.data) > 0 {
|
||||||
|
if q, err := parse_uri_list(string(ds.data)); err == nil {
|
||||||
|
for _, path := range q {
|
||||||
|
if path != "" && from_path(path) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if icon != "" {
|
||||||
|
cmd := DC{Type: 'p', X: -1, Xp: 6, Yp: 1, Payload: []byte(icon)}
|
||||||
|
dnd.lp.QueueDnDData(cmd)
|
||||||
|
cmd.Payload = nil
|
||||||
|
dnd.lp.QueueDnDData(cmd)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +133,7 @@ func (dnd *dnd) set_drag_image() (err error) {
|
||||||
img = find_drag_image(dnd.drag_sources)
|
img = find_drag_image(dnd.drag_sources)
|
||||||
}
|
}
|
||||||
if img == nil {
|
if img == nil {
|
||||||
return
|
return dnd.set_drag_image_text()
|
||||||
}
|
}
|
||||||
num_channels := utils.IfElse(imaging.IsOpaque(img), 3, 4)
|
num_channels := utils.IfElse(imaging.IsOpaque(img), 3, 4)
|
||||||
sz := dnd.opts.DragThumbnailSize
|
sz := dnd.opts.DragThumbnailSize
|
||||||
|
|
|
||||||
|
|
@ -1357,8 +1357,8 @@ drag_add_image(Window *w, unsigned idx, int fmt, int width, int height, int opac
|
||||||
img.opacity = opacity;
|
img.opacity = opacity;
|
||||||
base64_init_stream_decoder(&img.base64_state);
|
base64_init_stream_decoder(&img.base64_state);
|
||||||
}
|
}
|
||||||
if (img.capacity < sz + img.sz) {
|
if (img.capacity < MAX(32, sz + img.sz)) {
|
||||||
size_t newcap = MAX(img.capacity * 2, sz + img.sz);
|
size_t newcap = MAX(img.capacity * 2, MAX(32, sz + img.sz));
|
||||||
uint8_t *tmp = realloc(img.data, newcap);
|
uint8_t *tmp = realloc(img.data, newcap);
|
||||||
if (!tmp) abrt(ENOMEM);
|
if (!tmp) abrt(ENOMEM);
|
||||||
img.data = tmp;
|
img.data = tmp;
|
||||||
|
|
|
||||||
|
|
@ -1108,7 +1108,7 @@ func IconForFileWithMode(path string, mode fs.FileMode, follow_symlinks bool) st
|
||||||
return string(FOLDER)
|
return string(FOLDER)
|
||||||
case fs.ModeSymlink:
|
case fs.ModeSymlink:
|
||||||
if follow_symlinks {
|
if follow_symlinks {
|
||||||
if dest, err := os.Readlink(path); err == nil {
|
if dest, err := filepath.EvalSymlinks(path); err == nil {
|
||||||
if st, err := os.Stat(dest); err == nil {
|
if st, err := os.Stat(dest); err == nil {
|
||||||
if st.IsDir() {
|
if st.IsDir() {
|
||||||
return string(SYMLINK_TO_DIR)
|
return string(SYMLINK_TO_DIR)
|
||||||
|
|
|
||||||
|
|
@ -699,6 +699,8 @@ func (self *Loop) QueueDnDData(cmd DndCommand) IdType {
|
||||||
dest := make([]byte, base64.RawStdEncoding.EncodedLen(len(payload)))
|
dest := make([]byte, base64.RawStdEncoding.EncodedLen(len(payload)))
|
||||||
base64.RawStdEncoding.Encode(dest, utils.UnsafeStringToBytes(payload))
|
base64.RawStdEncoding.Encode(dest, utils.UnsafeStringToBytes(payload))
|
||||||
payload = utils.UnsafeBytesToString(dest)
|
payload = utils.UnsafeBytesToString(dest)
|
||||||
|
} else {
|
||||||
|
payload = string(cmd.Payload)
|
||||||
}
|
}
|
||||||
const chunk_size = 4096
|
const chunk_size = 4096
|
||||||
var ans IdType
|
var ans IdType
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue