mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
widget: [API] separate state changes from Draggable.Layout to Update
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+35
-46
@@ -17,18 +17,44 @@ type Draggable struct {
|
|||||||
// Type contains the MIME type and matches transfer.SourceOp.
|
// Type contains the MIME type and matches transfer.SourceOp.
|
||||||
Type string
|
Type string
|
||||||
|
|
||||||
handle struct{}
|
handle struct{}
|
||||||
drag gesture.Drag
|
drag gesture.Drag
|
||||||
click f32.Point
|
click f32.Point
|
||||||
pos f32.Point
|
pos f32.Point
|
||||||
requested bool
|
|
||||||
request string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Draggable) Layout(gtx layout.Context, w, drag layout.Widget) layout.Dimensions {
|
func (d *Draggable) Layout(gtx layout.Context, w, drag layout.Widget) layout.Dimensions {
|
||||||
if gtx.Queue == nil {
|
if gtx.Queue == nil {
|
||||||
return w(gtx)
|
return w(gtx)
|
||||||
}
|
}
|
||||||
|
dims := w(gtx)
|
||||||
|
|
||||||
|
stack := clip.Rect{Max: dims.Size}.Push(gtx.Ops)
|
||||||
|
d.drag.Add(gtx.Ops)
|
||||||
|
transfer.SourceOp{
|
||||||
|
Tag: &d.handle,
|
||||||
|
Type: d.Type,
|
||||||
|
}.Add(gtx.Ops)
|
||||||
|
stack.Pop()
|
||||||
|
|
||||||
|
if drag != nil && d.drag.Pressed() {
|
||||||
|
rec := op.Record(gtx.Ops)
|
||||||
|
op.Offset(d.pos.Round()).Add(gtx.Ops)
|
||||||
|
drag(gtx)
|
||||||
|
op.Defer(gtx.Ops, rec.Stop())
|
||||||
|
}
|
||||||
|
|
||||||
|
return dims
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dragging returns whether d is being dragged.
|
||||||
|
func (d *Draggable) Dragging() bool {
|
||||||
|
return d.drag.Dragging()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the draggable and returns the MIME type for which the Draggable was
|
||||||
|
// requested to offer data, if any
|
||||||
|
func (d *Draggable) Update(gtx layout.Context) (mime string, requested bool) {
|
||||||
pos := d.pos
|
pos := d.pos
|
||||||
for _, ev := range d.drag.Events(gtx.Metric, gtx.Queue, gesture.Both) {
|
for _, ev := range d.drag.Events(gtx.Metric, gtx.Queue, gesture.Both) {
|
||||||
switch ev.Kind {
|
switch ev.Kind {
|
||||||
@@ -42,48 +68,11 @@ func (d *Draggable) Layout(gtx layout.Context, w, drag layout.Widget) layout.Dim
|
|||||||
d.pos = pos
|
d.pos = pos
|
||||||
|
|
||||||
for _, ev := range gtx.Queue.Events(&d.handle) {
|
for _, ev := range gtx.Queue.Events(&d.handle) {
|
||||||
switch e := ev.(type) {
|
if e, ok := ev.(transfer.RequestEvent); ok {
|
||||||
case transfer.RequestEvent:
|
return e.Type, true
|
||||||
d.requested = true
|
|
||||||
d.request = e.Type
|
|
||||||
case transfer.CancelEvent:
|
|
||||||
d.requested = false
|
|
||||||
d.request = ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return "", false
|
||||||
dims := w(gtx)
|
|
||||||
|
|
||||||
stack := clip.Rect{Max: dims.Size}.Push(gtx.Ops)
|
|
||||||
d.drag.Add(gtx.Ops)
|
|
||||||
transfer.SourceOp{
|
|
||||||
Tag: &d.handle,
|
|
||||||
Type: d.Type,
|
|
||||||
}.Add(gtx.Ops)
|
|
||||||
stack.Pop()
|
|
||||||
|
|
||||||
if drag != nil && d.drag.Pressed() {
|
|
||||||
rec := op.Record(gtx.Ops)
|
|
||||||
op.Offset(pos.Round()).Add(gtx.Ops)
|
|
||||||
drag(gtx)
|
|
||||||
op.Defer(gtx.Ops, rec.Stop())
|
|
||||||
}
|
|
||||||
|
|
||||||
return dims
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dragging returns whether d is being dragged.
|
|
||||||
func (d *Draggable) Dragging() bool {
|
|
||||||
return d.drag.Dragging()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Requested returns the MIME type, if any, for which the Draggable was requested to offer data.
|
|
||||||
func (d *Draggable) Requested() (mime string, requested bool) {
|
|
||||||
mime = d.request
|
|
||||||
requested = d.requested
|
|
||||||
d.requested = false
|
|
||||||
d.request = ""
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offer the data ready for a drop. Must be called after being Requested.
|
// Offer the data ready for a drop. Must be called after being Requested.
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func ExampleDraggable_Layout() {
|
|||||||
drag.Layout(gtx, w, w)
|
drag.Layout(gtx, w, w)
|
||||||
// drag must respond with an Offer event when requested.
|
// drag must respond with an Offer event when requested.
|
||||||
// Use the drag method for this.
|
// Use the drag method for this.
|
||||||
if m, ok := drag.Requested(); ok {
|
if m, ok := drag.Update(gtx); ok {
|
||||||
drag.Offer(gtx.Ops, m, offer{Data: "hello world"})
|
drag.Offer(gtx.Ops, m, offer{Data: "hello world"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user