gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/widget/dnd_test.go (about) 1 package widget 2 3 import ( 4 "image" 5 "testing" 6 7 "gioui.org/f32" 8 "gioui.org/io/event" 9 "gioui.org/io/input" 10 "gioui.org/io/pointer" 11 "gioui.org/io/transfer" 12 "gioui.org/layout" 13 "gioui.org/op" 14 "gioui.org/op/clip" 15 ) 16 17 func TestDraggable(t *testing.T) { 18 var r input.Router 19 gtx := layout.Context{ 20 Constraints: layout.Exact(image.Pt(100, 100)), 21 Source: r.Source(), 22 Ops: new(op.Ops), 23 } 24 25 drag := &Draggable{ 26 Type: "file", 27 } 28 tgt := new(int) 29 defer pointer.PassOp{}.Push(gtx.Ops).Pop() 30 dims := drag.Layout(gtx, func(gtx layout.Context) layout.Dimensions { 31 return layout.Dimensions{Size: gtx.Constraints.Min} 32 }, nil) 33 stack := clip.Rect{Max: dims.Size}.Push(gtx.Ops) 34 event.Op(gtx.Ops, tgt) 35 stack.Pop() 36 37 drag.Update(gtx) 38 r.Event(transfer.TargetFilter{Target: tgt, Type: drag.Type}) 39 r.Frame(gtx.Ops) 40 r.Queue( 41 pointer.Event{ 42 Position: f32.Pt(10, 10), 43 Kind: pointer.Press, 44 }, 45 pointer.Event{ 46 Position: f32.Pt(20, 10), 47 Kind: pointer.Move, 48 }, 49 pointer.Event{ 50 Position: f32.Pt(20, 10), 51 Kind: pointer.Release, 52 }, 53 ) 54 ofr := &offer{data: "hello"} 55 drag.Update(gtx) 56 r.Event(transfer.TargetFilter{Target: tgt, Type: drag.Type}) 57 drag.Offer(gtx, "file", ofr) 58 59 e, ok := r.Event(transfer.TargetFilter{Target: tgt, Type: drag.Type}) 60 if !ok { 61 t.Fatalf("expected event") 62 } 63 ev := e.(transfer.DataEvent) 64 if got, want := ev.Type, "file"; got != want { 65 t.Errorf("expected %v; got %v", got, want) 66 } 67 if ofr.closed { 68 t.Error("offer closed prematurely") 69 } 70 e, ok = r.Event(transfer.TargetFilter{Target: tgt, Type: drag.Type}) 71 if !ok { 72 t.Fatalf("expected event") 73 } 74 if _, ok := e.(transfer.CancelEvent); !ok { 75 t.Fatalf("expected transfer.CancelEvent event") 76 } 77 r.Frame(gtx.Ops) 78 if !ofr.closed { 79 t.Error("offer was not closed") 80 } 81 } 82 83 // offer satisfies io.ReadCloser for use in data transfers. 84 type offer struct { 85 data string 86 closed bool 87 } 88 89 func (*offer) Read([]byte) (int, error) { return 0, nil } 90 91 func (o *offer) Close() error { 92 o.closed = true 93 return nil 94 }