github.com/jmigpin/editor@v1.6.0/driver/windriver/dnd.go (about) 1 //go:build windows 2 3 package windriver 4 5 import ( 6 "fmt" 7 "image" 8 "strings" 9 10 "github.com/jmigpin/editor/util/uiutil/event" 11 "golang.org/x/sys/windows" 12 ) 13 14 // Drag and drop manager. 15 type DndMan struct { 16 } 17 18 func NewDndMan() *DndMan { 19 return &DndMan{} 20 } 21 22 func (m *DndMan) HandleDrop(hDrop uintptr) (interface{}, bool, error) { 23 //dropped, p := m.dropPoint(hDrop) 24 //if !dropped { 25 // ev := m.buildPositionEvent(hDrop, p) 26 // return ev, true, nil 27 //} else { 28 // ev := m.buildDropEvent(hDrop, p) 29 // return ev, true, nil 30 //} 31 //return nil, false, nil 32 33 // always dropping 34 _, p := m.dropPoint(hDrop) 35 ev := m.buildDropEvent(hDrop, p) 36 return ev, true, nil 37 } 38 39 //---------- 40 41 func (m *DndMan) buildPositionEvent(hDrop uintptr, p image.Point) interface{} { 42 //fmt.Printf("reply %v\n", action) 43 types := []event.DndType{event.TextURLListDndT} 44 appReplyFn := func(action event.DndAction) { 45 // TODO: post msg to msg loop? saying the action somehow 46 //m.positionReply(action) 47 } 48 return &event.DndPosition{p, types, appReplyFn} 49 } 50 51 //---------- 52 53 func (m *DndMan) buildDropEvent(hDrop uintptr, p image.Point) interface{} { 54 appReqFn := func(typ event.DndType) ([]byte, error) { 55 u := FilesDropped(hDrop) 56 if len(u) == 0 { 57 return nil, fmt.Errorf("no files dropped") 58 } 59 b := []byte(strings.Join(u, "\n")) 60 return b, nil 61 } 62 appReplyFn := func(v bool) { 63 // TODO: true or false 64 _DragFinish(hDrop) 65 } 66 return &event.DndDrop{p, appReplyFn, appReqFn} 67 } 68 69 //---------- 70 71 func (m *DndMan) dropPoint(hDrop uintptr) (bool, image.Point) { 72 p := _Point{} 73 dropped := _DragQueryPoint(hDrop, &p) 74 return dropped, p.ToImagePoint() 75 } 76 77 //---------- 78 79 func FilesDropped(hDrop uintptr) []string { 80 // http://delphidabbler.com/articles?article=11 81 82 // find the number of files dropped 83 res := _DragQueryFileW(hDrop, 0xffffffff, nil, 0) 84 n := int(res) 85 // find the sizes of the buffers needed 86 sizes := make([]int, n) 87 for i := 0; i < n; i++ { 88 size := _DragQueryFileW(hDrop, uint32(i), nil, 0) 89 sizes[i] = int(size) 90 } 91 // fetch the filenames 92 names := make([]string, n) 93 for i := 0; i < n; i++ { 94 u := make([]uint16, sizes[i]+1) // +1 is the nil terminator 95 _ = _DragQueryFileW(hDrop, uint32(i), &u[0], uint32(len(u))) 96 names[i] = windows.UTF16ToString(u) 97 } 98 return names 99 }