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  }