io/system: add ActionInputOp to register window move gesture areas

The app.Window.Perform(ActionMove) is the wrong abstraction for
initiating a move gesture: Windows needs to know the move gesture
area at pointer move, and macOS needs to know the pointer button
down event that triggers the move gesture. This change replaces
Perform(ActionMove) with a new system.ActionInputOp that marks an
area movable.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2022-06-25 19:03:50 +02:00
parent b53cdfef8d
commit 3f38e67ce0
10 changed files with 85 additions and 35 deletions
+21
View File
@@ -13,6 +13,7 @@ import (
"gioui.org/io/key"
"gioui.org/io/pointer"
"gioui.org/io/semantic"
"gioui.org/io/system"
"gioui.org/io/transfer"
)
@@ -97,6 +98,7 @@ type areaNode struct {
id SemanticID
content semanticContent
}
action system.Action
}
type areaKind uint8
@@ -256,6 +258,12 @@ func (c *pointerCollector) keyInputOp(op key.InputOp) {
})
}
func (c *pointerCollector) actionInputOp(act system.Action) {
areaID := c.currentArea()
area := &c.q.areas[areaID]
area.action = act
}
func (c *pointerCollector) inputOp(op pointer.InputOp, events *handlerEvents) {
areaID := c.currentArea()
area := &c.q.areas[areaID]
@@ -424,6 +432,19 @@ func (q *pointerQueue) semanticIDFor(content semanticContent) SemanticID {
return id.id
}
func (q *pointerQueue) ActionAt(pos f32.Point) (system.Action, bool) {
for i := len(q.hitTree) - 1; i >= 0; i-- {
n := &q.hitTree[i]
hit, _ := q.hit(n.area, pos)
if !hit {
continue
}
area := q.areas[n.area]
return area.action, area.action != 0
}
return 0, false
}
func (q *pointerQueue) SemanticAt(pos f32.Point) (SemanticID, bool) {
q.assignSemIDs()
for i := len(q.hitTree) - 1; i >= 0; i-- {
+8
View File
@@ -27,6 +27,7 @@ import (
"gioui.org/io/pointer"
"gioui.org/io/profile"
"gioui.org/io/semantic"
"gioui.org/io/system"
"gioui.org/io/transfer"
"gioui.org/op"
)
@@ -276,6 +277,10 @@ func min(p1, p2 image.Point) image.Point {
return m
}
func (q *Router) ActionAt(p f32.Point) (system.Action, bool) {
return q.pointer.queue.ActionAt(p)
}
func (q *Router) ClickFocus() {
focus := q.key.queue.focus
if focus == nil {
@@ -444,6 +449,9 @@ func (q *Router) collect() {
Data: encOp.Refs[2].(io.ReadCloser),
}
pc.offerOp(op, &q.handlers)
case ops.TypeActionInput:
act := system.Action(encOp.Data[1])
pc.actionInputOp(act)
// Key ops.
case ops.TypeKeyFocus:
+15
View File
@@ -2,8 +2,17 @@ package system
import (
"strings"
"gioui.org/internal/ops"
"gioui.org/op"
)
// ActionAreaOp makes the current clip area available for
// system gestures.
//
// Note: only ActionMove is supported.
type ActionInputOp Action
// Action is a set of window decoration actions.
type Action uint
@@ -31,6 +40,12 @@ const (
ActionMove
)
func (op ActionInputOp) Add(o *op.Ops) {
data := ops.Write(&o.Internal, ops.TypeActionInputLen)
data[0] = byte(ops.TypeActionInput)
data[1] = byte(op)
}
func (a Action) String() string {
var buf strings.Builder
for b := Action(1); a != 0; b <<= 1 {