97 lines
2.2 KiB
Go
97 lines
2.2 KiB
Go
|
// +build windows
|
||
|
|
||
|
package dragdrop
|
||
|
|
||
|
import (
|
||
|
"unsafe"
|
||
|
|
||
|
"golang.org/x/text/encoding/unicode"
|
||
|
"opslag.de/schobers/geom"
|
||
|
"opslag.de/schobers/zntg/ui"
|
||
|
)
|
||
|
|
||
|
/*
|
||
|
#cgo LDFLAGS: -lole32 -luuid
|
||
|
|
||
|
#include <Windows.h>
|
||
|
#include <oleidl.h>
|
||
|
#include <stdint.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
extern uint32_t RegisterHandler(void* windowHandle);
|
||
|
*/
|
||
|
import "C"
|
||
|
|
||
|
//export clearFiles
|
||
|
func clearFiles(handle uint32) {
|
||
|
handler := handlers[handle]
|
||
|
handler.Files = nil
|
||
|
handlers[handle] = handler
|
||
|
}
|
||
|
|
||
|
//export addFile
|
||
|
func addFile(handle uint32, pathNative *C.wchar_t, pathNativeLength C.UINT) {
|
||
|
pathBytes := C.GoBytes(unsafe.Pointer(pathNative), C.int(pathNativeLength)*C.sizeof_wchar_t)
|
||
|
decoder := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder()
|
||
|
path, err := decoder.Bytes(pathBytes)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
handler := handlers[handle]
|
||
|
handler.Files = append(handler.Files, string(path))
|
||
|
handlers[handle] = handler
|
||
|
}
|
||
|
|
||
|
//export onDragEnter
|
||
|
func onDragEnter(handle uint32, x, y C.LONG) {
|
||
|
invokeHandler(handle, func(target ui.DragDropEventTarget, files []string) {
|
||
|
target.DragEnter(pos(x, y), files)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
//export onDragOver
|
||
|
func onDragOver(handle uint32, x, y C.LONG) {
|
||
|
invokeHandler(handle, func(target ui.DragDropEventTarget, _ []string) {
|
||
|
target.DragMove(pos(x, y))
|
||
|
})
|
||
|
}
|
||
|
|
||
|
//export onDragLeave
|
||
|
func onDragLeave(handle uint32) {
|
||
|
invokeHandler(handle, func(target ui.DragDropEventTarget, _ []string) {
|
||
|
target.DragLeave()
|
||
|
})
|
||
|
}
|
||
|
|
||
|
//export onDrop
|
||
|
func onDrop(handle uint32, x, y C.LONG) {
|
||
|
invokeHandler(handle, func(target ui.DragDropEventTarget, files []string) {
|
||
|
target.Drop(pos(x, y), files)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
type handler struct {
|
||
|
Target ui.DragDropEventTarget
|
||
|
Files []string
|
||
|
}
|
||
|
|
||
|
var handlers map[uint32]handler = map[uint32]handler{}
|
||
|
|
||
|
func invokeHandler(handle uint32, invoke func(ui.DragDropEventTarget, []string)) {
|
||
|
handler := handlers[handle]
|
||
|
invoke(handler.Target, handler.Files)
|
||
|
}
|
||
|
|
||
|
func pos(x, y C.LONG) geom.PointF32 { return geom.Pt(int(x), int(y)).ToF32() }
|
||
|
|
||
|
type provider struct{}
|
||
|
|
||
|
func (p provider) Register(windowHandle uintptr, target ui.DragDropEventTarget) {
|
||
|
handle := C.RegisterHandler(unsafe.Pointer(windowHandle))
|
||
|
handlers[uint32(handle)] = handler{target, nil}
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
ui.DefaultDragDropProvider = provider{}
|
||
|
}
|