forked from joejulian/gio
03016f0c69
This patch adds internal Drag and Drop support to app.Windows. The new package io/transfer adds the ability to define draggable and droppable targets, which are leveraged by the new widget.Draggable type. The API is generic and could handle future use cases, such as external Drag and Drop. Updates gio#153 Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
87 lines
1.6 KiB
Go
87 lines
1.6 KiB
Go
package widget
|
|
|
|
import (
|
|
"image"
|
|
"testing"
|
|
|
|
"gioui.org/f32"
|
|
"gioui.org/io/pointer"
|
|
"gioui.org/io/router"
|
|
"gioui.org/io/transfer"
|
|
"gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/op/clip"
|
|
)
|
|
|
|
func TestDraggable(t *testing.T) {
|
|
var r router.Router
|
|
gtx := layout.Context{
|
|
Constraints: layout.Exact(image.Pt(100, 100)),
|
|
Queue: &r,
|
|
Ops: new(op.Ops),
|
|
}
|
|
|
|
drag := &Draggable{
|
|
Type: "file",
|
|
}
|
|
defer pointer.PassOp{}.Push(gtx.Ops).Pop()
|
|
dims := drag.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
return layout.Dimensions{Size: gtx.Constraints.Min}
|
|
}, nil)
|
|
stack := clip.Rect{Max: dims.Size}.Push(gtx.Ops)
|
|
transfer.TargetOp{
|
|
Tag: drag,
|
|
Type: drag.Type,
|
|
}.Add(gtx.Ops)
|
|
stack.Pop()
|
|
|
|
r.Frame(gtx.Ops)
|
|
r.Queue(
|
|
pointer.Event{
|
|
Position: f32.Pt(10, 10),
|
|
Type: pointer.Press,
|
|
},
|
|
pointer.Event{
|
|
Position: f32.Pt(20, 10),
|
|
Type: pointer.Move,
|
|
},
|
|
pointer.Event{
|
|
Position: f32.Pt(20, 10),
|
|
Type: pointer.Release,
|
|
},
|
|
)
|
|
ofr := &offer{data: "hello"}
|
|
drag.Offer(gtx.Ops, "file", ofr)
|
|
r.Frame(gtx.Ops)
|
|
|
|
evs := r.Events(drag)
|
|
if len(evs) != 1 {
|
|
t.Fatalf("expected 1 event, got %d", len(evs))
|
|
}
|
|
ev := evs[0].(transfer.DataEvent)
|
|
ev.Open = nil
|
|
if got, want := ev.Type, "file"; got != want {
|
|
t.Errorf("expected %v; got %v", got, want)
|
|
}
|
|
if ofr.closed {
|
|
t.Error("offer closed prematurely")
|
|
}
|
|
r.Frame(gtx.Ops)
|
|
if !ofr.closed {
|
|
t.Error("offer was not closed")
|
|
}
|
|
}
|
|
|
|
// offer satisfies io.ReadCloser for use in data transfers.
|
|
type offer struct {
|
|
data string
|
|
closed bool
|
|
}
|
|
|
|
func (*offer) Read([]byte) (int, error) { return 0, nil }
|
|
|
|
func (o *offer) Close() error {
|
|
o.closed = true
|
|
return nil
|
|
}
|