zntg/addons/dragdrop/dragdrop_windows.go

97 lines
2.2 KiB
Go
Raw Normal View History

// +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{}
}