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  }