mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 18:35:34 +00:00
ui/pointer: expand documentation
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -24,7 +24,7 @@ Drawing a colored square:
|
|||||||
import "gioui.org/ui/paint"
|
import "gioui.org/ui/paint"
|
||||||
|
|
||||||
var w app.Window
|
var w app.Window
|
||||||
var ops ui.Ops
|
ops := new(ui.Ops)
|
||||||
...
|
...
|
||||||
ops.Reset()
|
ops.Reset()
|
||||||
paint.ColorOp{Color: ...}.Add(ops)
|
paint.ColorOp{Color: ...}.Add(ops)
|
||||||
@@ -38,7 +38,7 @@ mutable state stack and execution flow can be controlled with macros.
|
|||||||
|
|
||||||
The StackOp saves the current state to the state stack and restores it later:
|
The StackOp saves the current state to the state stack and restores it later:
|
||||||
|
|
||||||
var ops ui.Ops
|
ops := new(ui.Ops)
|
||||||
var stack ui.StackOp
|
var stack ui.StackOp
|
||||||
// Save the current state, in particular the transform.
|
// Save the current state, in particular the transform.
|
||||||
stack.Push(ops)
|
stack.Push(ops)
|
||||||
@@ -50,7 +50,7 @@ The StackOp saves the current state to the state stack and restores it later:
|
|||||||
|
|
||||||
The MacroOp records a list of operations to be executed later:
|
The MacroOp records a list of operations to be executed later:
|
||||||
|
|
||||||
var ops ui.Ops
|
ops := new(ui.Ops)
|
||||||
var macro ui.MacroOp
|
var macro ui.MacroOp
|
||||||
macro.Record()
|
macro.Record()
|
||||||
// Record operations by adding them.
|
// Record operations by adding them.
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ The following example marks a handler ready for key input:
|
|||||||
import gioui.org/ui/input
|
import gioui.org/ui/input
|
||||||
import gioui.org/ui/key
|
import gioui.org/ui/key
|
||||||
|
|
||||||
var ops ui.Ops
|
ops := new(ui.Ops)
|
||||||
var h *Handler = ...
|
var h *Handler = ...
|
||||||
key.HandlerOp{Key: h}.Add(ops)
|
key.HandlerOp{Key: h}.Add(ops)
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -1,7 +1,8 @@
|
|||||||
// SPDX-License-Identifier: Unlicense OR MIT
|
// SPDX-License-Identifier: Unlicense OR MIT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Package key implements key and text input handling.
|
Package key implements key and text events and
|
||||||
|
operations.
|
||||||
|
|
||||||
The HandlerOp operations is used for declaring key
|
The HandlerOp operations is used for declaring key
|
||||||
input handlers. Use the Queue interface from package
|
input handlers. Use the Queue interface from package
|
||||||
@@ -28,7 +29,7 @@ type HandlerOp struct {
|
|||||||
// be hidden.
|
// be hidden.
|
||||||
type HideInputOp struct{}
|
type HideInputOp struct{}
|
||||||
|
|
||||||
// FocusEvent is sent when a handler gains or looses
|
// FocusEvent is sent when a handler gains or loses
|
||||||
// focus.
|
// focus.
|
||||||
type FocusEvent struct {
|
type FocusEvent struct {
|
||||||
Focus bool
|
Focus bool
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
// SPDX-License-Identifier: Unlicense OR MIT
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package pointer implements pointer events and operations.
|
||||||
|
A pointer is either a mouse controlled cursor or a touch
|
||||||
|
object such as a finger.
|
||||||
|
|
||||||
|
The HandlerOp operation is used to declare a handler ready
|
||||||
|
for pointer events. Use a Queue from package input to
|
||||||
|
receive events.
|
||||||
|
|
||||||
|
Areas
|
||||||
|
|
||||||
|
The area operations are used for specifying the area where
|
||||||
|
subsequent HandlerOps are active.
|
||||||
|
|
||||||
|
For example, to set up a rectangular hit area:
|
||||||
|
|
||||||
|
var ops ui.Ops
|
||||||
|
var h *Handler = ...
|
||||||
|
|
||||||
|
r := image.Rectangle{...}
|
||||||
|
pointer.RectAreaOp{Rect: r}.Add(ops)
|
||||||
|
pointer.HandlerOp{Key: h}.Add(ops)
|
||||||
|
|
||||||
|
Note that areas compound: the effective area of multiple area
|
||||||
|
operations is the intersection of the areas.
|
||||||
|
|
||||||
|
Matching events
|
||||||
|
|
||||||
|
StackOp operations and input handlers form an implicit tree.
|
||||||
|
Each stack operation is a node, and each input handler is associated
|
||||||
|
with the most recent node.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
ops := new(ui.Ops)
|
||||||
|
var stack ui.StackOp
|
||||||
|
var h1, h2 *Handler
|
||||||
|
|
||||||
|
stack.Push(ops)
|
||||||
|
pointer.HandlerOp{Key: h1}.Add(Ops)
|
||||||
|
stack.Pop()
|
||||||
|
|
||||||
|
stack.Push(ops)
|
||||||
|
pointer.HandlerOp{Key: h2}.Add(ops)
|
||||||
|
stack.Pop()
|
||||||
|
|
||||||
|
implies a tree of two inner nodes, each with one pointer handler.
|
||||||
|
|
||||||
|
When determining which handlers match an Event, only handlers whose
|
||||||
|
areas contain the event position are considered. The matching
|
||||||
|
proceeds as follows.
|
||||||
|
|
||||||
|
First, the foremost matching handler is included. If the handler
|
||||||
|
has pass-through enabled, this step is repeated.
|
||||||
|
|
||||||
|
Then, all matching handlers from the current node and all parent
|
||||||
|
nodes are included.
|
||||||
|
|
||||||
|
In the example above, all events will go to h2 only even though both
|
||||||
|
handlers have the same area (the entire screen).
|
||||||
|
|
||||||
|
Pass-through
|
||||||
|
|
||||||
|
The PassOp operations controls the pass-through setting. A handler's
|
||||||
|
pass-through setting is recorded along with the HandlerOp.
|
||||||
|
|
||||||
|
Pass-through handlers are useful for overlay widgets such as a hidden
|
||||||
|
side drawer. When the user touches the side, both the (transparent)
|
||||||
|
drawer handle and the interface below should receive pointer events.
|
||||||
|
|
||||||
|
Disambiguation
|
||||||
|
|
||||||
|
When more than one handler matches a pointer event, the input queue
|
||||||
|
follows a set of rules for distributing the event.
|
||||||
|
|
||||||
|
As long as the pointer has not received a Press event, all
|
||||||
|
matching handlers receive all events.
|
||||||
|
|
||||||
|
When a pointer is pressed, the set of matching handlers is
|
||||||
|
recorded. The set is not updated according to the pointer position
|
||||||
|
and hit areas. Rather, handlers stay in the matching set until they
|
||||||
|
no longer appear in a HandlerOp or when another handler in the set
|
||||||
|
grabs the pointer.
|
||||||
|
|
||||||
|
A handler can exclude all other handler from its matching sets
|
||||||
|
by setting the Grab flag in its HandlerOp. The Grab flag is sticky
|
||||||
|
and stays in effect until the handler no longer appears in any
|
||||||
|
matching sets.
|
||||||
|
|
||||||
|
The losing handlers are notified by a Cancel event.
|
||||||
|
|
||||||
|
For multiple grabbing handlers, the foremost handler wins.
|
||||||
|
|
||||||
|
Priorities
|
||||||
|
|
||||||
|
Handlers know their position in a matching set of a pointer through
|
||||||
|
event priorities. The Shared and Foremost are for matching sets with
|
||||||
|
multiple handlers; the Grabbed priority indicate exclusive access.
|
||||||
|
|
||||||
|
Priorities are useful for deferred gesture matching.
|
||||||
|
|
||||||
|
Consider a scrollable list of clickable elements. When the user touches an
|
||||||
|
element, it is unknown whether the gesture is a click on the element
|
||||||
|
or a drag (scroll) of the list. While the click handler might light up
|
||||||
|
the element in anticipation of a click, the scrolling handler does not
|
||||||
|
scroll on finger movements with lower than Grabbed priority.
|
||||||
|
|
||||||
|
Should the user release the finger, the click handler registers a click.
|
||||||
|
|
||||||
|
However, if the finger moves beyond a threshold, the scrolling handler
|
||||||
|
determines that the gesture is a drag and sets its Grab flag. The
|
||||||
|
click handler receives a Cancel (removing the highlight) and further
|
||||||
|
movements for the scroll handler has priority Grabbed, scrolling the
|
||||||
|
list.
|
||||||
|
*/
|
||||||
|
package pointer
|
||||||
+46
-2
@@ -13,22 +13,45 @@ import (
|
|||||||
"gioui.org/ui/internal/opconst"
|
"gioui.org/ui/internal/opconst"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Event is a pointer event.
|
||||||
type Event struct {
|
type Event struct {
|
||||||
Type Type
|
Type Type
|
||||||
Source Source
|
Source Source
|
||||||
|
// PointerID is the id for the pointer and can be used
|
||||||
|
// to track a particular pointer from Press to
|
||||||
|
// Release or Cancel.
|
||||||
PointerID ID
|
PointerID ID
|
||||||
|
// Priority is the priority of the receiving handler
|
||||||
|
// for this event.
|
||||||
Priority Priority
|
Priority Priority
|
||||||
|
// Time is when the event was received. The
|
||||||
|
// timestamp is relative to an undefined base.
|
||||||
Time time.Duration
|
Time time.Duration
|
||||||
|
// Hit is set when the event was within the registered
|
||||||
|
// area for the handler. Hit can be false when a pointer
|
||||||
|
// was pressed within the hit area, and then dragged
|
||||||
|
// outside it.
|
||||||
Hit bool
|
Hit bool
|
||||||
|
// Position is the position of the event, relative to
|
||||||
|
// the current transformation, as set by ui.TransformOp.
|
||||||
Position f32.Point
|
Position f32.Point
|
||||||
|
// Scroll is the scroll amount, if any.
|
||||||
Scroll f32.Point
|
Scroll f32.Point
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RectAreaOp updates the hit area to the intersection
|
||||||
|
// of the current hit area with a rectangular area.
|
||||||
type RectAreaOp struct {
|
type RectAreaOp struct {
|
||||||
|
// Rect defines the rectangle. The current transform
|
||||||
|
// is applied to it.
|
||||||
Rect image.Rectangle
|
Rect image.Rectangle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EllipseAreaOp updates the hit area to the intersection
|
||||||
|
// of the current hit area with an elliptical area.
|
||||||
type EllipseAreaOp struct {
|
type EllipseAreaOp struct {
|
||||||
|
// Rect is the bounds for the ellipse. The current transform
|
||||||
|
// is applied to the rectangle.
|
||||||
Rect image.Rectangle
|
Rect image.Rectangle
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,40 +61,61 @@ type areaOp struct {
|
|||||||
rect image.Rectangle
|
rect image.Rectangle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandlerOp declares an input handler ready for pointer
|
||||||
|
// events.
|
||||||
type HandlerOp struct {
|
type HandlerOp struct {
|
||||||
Key input.Key
|
Key input.Key
|
||||||
|
// Grab, if set, request that the handler get
|
||||||
|
// Grabbed priority.
|
||||||
Grab bool
|
Grab bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// PassOp change the current event pass-through
|
// PassOp sets the pass-through mode.
|
||||||
// setting.
|
|
||||||
type PassOp struct {
|
type PassOp struct {
|
||||||
Pass bool
|
Pass bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ID uint16
|
type ID uint16
|
||||||
|
|
||||||
|
// Type of an Event.
|
||||||
type Type uint8
|
type Type uint8
|
||||||
|
|
||||||
|
// Priority of an Event.
|
||||||
type Priority uint8
|
type Priority uint8
|
||||||
|
|
||||||
|
// Source of an Event.
|
||||||
type Source uint8
|
type Source uint8
|
||||||
|
|
||||||
// Must match input.areaKind
|
// Must match input.areaKind
|
||||||
type areaKind uint8
|
type areaKind uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Cancel is sent when the current gesture is interrupted
|
||||||
|
// by other handlers or the system.
|
||||||
Cancel Type = iota
|
Cancel Type = iota
|
||||||
|
// Press of a pointer.
|
||||||
Press
|
Press
|
||||||
|
// Release of a pointer.
|
||||||
Release
|
Release
|
||||||
|
// Move of a pointer.
|
||||||
Move
|
Move
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Mouse generated event.
|
||||||
Mouse Source = iota
|
Mouse Source = iota
|
||||||
|
// Touch generated event.
|
||||||
Touch
|
Touch
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Shared priority is for handlers that
|
||||||
|
// are part of a matching set larger than 1.
|
||||||
Shared Priority = iota
|
Shared Priority = iota
|
||||||
|
// Foremost is like Shared, but the handler is
|
||||||
|
// the foremost in the matching set.
|
||||||
Foremost
|
Foremost
|
||||||
|
// Grabbed is used for matching sets of size 1.
|
||||||
Grabbed
|
Grabbed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user