chore(v2): vendor dependencies for offline/China builds
go mod vendor pins onnxruntime_go v1.12.1, Gio and the rest into v2/vendor so go run/build work without hitting proxy.golang.org (blocked/slow in China). Verified: CGO_ENABLED=1 go build -mod=vendor ./internal/spike and GOOS=windows go build -mod=vendor ./internal/ui both pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+118
@@ -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 [event.Op] operation is used to declare a handler ready for pointer
|
||||
events.
|
||||
|
||||
# Hit areas
|
||||
|
||||
Clip operations from package [op/clip] are used for specifying
|
||||
hit areas where handlers may receive events.
|
||||
|
||||
For example, to set up a handler with a rectangular hit area:
|
||||
|
||||
r := image.Rectangle{...}
|
||||
area := clip.Rect(r).Push(ops)
|
||||
event.Op{Tag: h}.Add(ops)
|
||||
area.Pop()
|
||||
|
||||
Note that hit areas behave similar to painting: the effective area of a stack
|
||||
of multiple area operations is the intersection of the areas.
|
||||
|
||||
BUG: Clip operations other than clip.Rect and clip.Ellipse are approximated
|
||||
with their bounding boxes.
|
||||
|
||||
# Matching events
|
||||
|
||||
Areas form an implicit tree, with input handlers as leaves. The children of
|
||||
an area is every area and handler added between its Push and corresponding Pop.
|
||||
|
||||
For example:
|
||||
|
||||
ops := new(op.Ops)
|
||||
var h1, h2 *Handler
|
||||
|
||||
area := clip.Rect(...).Push(ops)
|
||||
event.Op(Ops, h1)
|
||||
area.Pop()
|
||||
|
||||
area := clip.Rect(...).Push(ops)
|
||||
event.Op(Ops, h2)
|
||||
area.Pop()
|
||||
|
||||
implies a tree of two inner nodes, each with one pointer handler attached.
|
||||
|
||||
The matching proceeds as follows.
|
||||
|
||||
First, the foremost area that contains the event is found. Only areas whose
|
||||
parent areas all contain the event is considered.
|
||||
|
||||
Then, every handler attached to the area is matched with the event.
|
||||
|
||||
If all attached handlers are marked pass-through or if no handlers are
|
||||
attached, the matching repeats with the next foremost (sibling) area. Otherwise
|
||||
the matching repeats with the parent area.
|
||||
|
||||
In the example above, all events will go to h2 because it and h1 are siblings
|
||||
and none are pass-through.
|
||||
|
||||
# Pass-through
|
||||
|
||||
The PassOp operations controls the pass-through setting. All handlers added
|
||||
inside one or more PassOp scopes are marked pass-through.
|
||||
|
||||
Pass-through is useful for overlay widgets. Consider a hidden side drawer: when
|
||||
the user touches the side, both the (transparent) drawer handle and the
|
||||
interface below should receive pointer events. This effect is achieved by
|
||||
marking the drawer handle pass-through.
|
||||
|
||||
# Disambiguation
|
||||
|
||||
When more than one handler matches a pointer event, the event 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 InputOp 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 InputOp. 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 priority is 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
|
||||
+409
@@ -0,0 +1,409 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
package pointer
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gioui.org/f32"
|
||||
"gioui.org/internal/ops"
|
||||
"gioui.org/io/event"
|
||||
"gioui.org/io/key"
|
||||
"gioui.org/op"
|
||||
)
|
||||
|
||||
// Event is a pointer event.
|
||||
type Event struct {
|
||||
Kind Kind
|
||||
Source Source
|
||||
// PointerID is the id for the pointer and can be used
|
||||
// to track a particular pointer from Press to
|
||||
// Release. Populated for Press, Release, Move, Drag,
|
||||
// Enter, Leave, and Cancel; Scroll events are not
|
||||
// bound to a tracked pointer and leave it zero.
|
||||
PointerID ID
|
||||
// Priority is the priority of the receiving handler
|
||||
// for this event.
|
||||
Priority Priority
|
||||
// Time is when the event was received. The
|
||||
// timestamp is relative to an undefined base.
|
||||
Time time.Duration
|
||||
// Buttons are the set of pressed mouse buttons for this event.
|
||||
Buttons Buttons
|
||||
// Position is the coordinates of the event in the local coordinate
|
||||
// system of the receiving tag. The transformation from global window
|
||||
// coordinates to local coordinates is performed by the inverse of
|
||||
// the effective transformation of the tag.
|
||||
Position f32.Point
|
||||
// Scroll is the scroll amount, if any.
|
||||
Scroll f32.Point
|
||||
// Modifiers is the set of active modifiers when
|
||||
// the mouse button was pressed.
|
||||
Modifiers key.Modifiers
|
||||
}
|
||||
|
||||
// PassOp sets the pass-through mode. InputOps added while the pass-through
|
||||
// mode is set don't block events to siblings.
|
||||
type PassOp struct{}
|
||||
|
||||
// PassStack represents a PassOp on the pass stack.
|
||||
type PassStack struct {
|
||||
ops *ops.Ops
|
||||
id ops.StackID
|
||||
macroID uint32
|
||||
}
|
||||
|
||||
// Filter matches every [Event] that target the Tag and whose kind is
|
||||
// included in Kinds. Note that only tags specified in [event.Op] can
|
||||
// be targeted by pointer events.
|
||||
type Filter struct {
|
||||
Target event.Tag
|
||||
// Kinds is a bitwise-or of event types to match.
|
||||
Kinds Kind
|
||||
// ScrollX and ScrollY constrain the range of scrolling events delivered
|
||||
// to Target. Specifically, any Event e delivered to Tag will satisfy
|
||||
//
|
||||
// ScrollX.Min <= e.Scroll.X <= ScrollX.Max (horizontal axis)
|
||||
// ScrollY.Min <= e.Scroll.Y <= ScrollY.Max (vertical axis)
|
||||
ScrollX ScrollRange
|
||||
ScrollY ScrollRange
|
||||
}
|
||||
|
||||
// ScrollRange describes the range of scrolling distances in an
|
||||
// axis.
|
||||
type ScrollRange struct {
|
||||
Min, Max int
|
||||
}
|
||||
|
||||
// GrabCmd requests a pointer grab on the pointer identified by ID.
|
||||
type GrabCmd struct {
|
||||
Tag event.Tag
|
||||
ID ID
|
||||
}
|
||||
|
||||
type ID uint16
|
||||
|
||||
// Kind of an Event.
|
||||
type Kind uint
|
||||
|
||||
// Priority of an Event.
|
||||
type Priority uint8
|
||||
|
||||
// Source of an Event.
|
||||
type Source uint8
|
||||
|
||||
// Buttons is a set of mouse buttons
|
||||
type Buttons uint8
|
||||
|
||||
// Cursor denotes a pre-defined cursor shape. Its Add method adds an
|
||||
// operation that sets the cursor shape for the current clip area.
|
||||
type Cursor byte
|
||||
|
||||
// The cursors correspond to CSS pointer naming.
|
||||
const (
|
||||
// CursorDefault is the default cursor.
|
||||
CursorDefault Cursor = iota
|
||||
// CursorNone hides the cursor. To show it again, use any other cursor.
|
||||
CursorNone
|
||||
// CursorText is for selecting and inserting text.
|
||||
CursorText
|
||||
// CursorVerticalText is for selecting and inserting vertical text.
|
||||
CursorVerticalText
|
||||
// CursorPointer is for a link.
|
||||
// Usually displayed as a pointing hand.
|
||||
CursorPointer
|
||||
// CursorCrosshair is for a precise location.
|
||||
CursorCrosshair
|
||||
// CursorAllScroll is for indicating scrolling in all directions.
|
||||
// Usually displayed as arrows to all four directions.
|
||||
CursorAllScroll
|
||||
// CursorColResize is for vertical resize.
|
||||
// Usually displayed as a vertical bar with arrows pointing east and west.
|
||||
CursorColResize
|
||||
// CursorRowResize is for horizontal resize.
|
||||
// Usually displayed as a horizontal bar with arrows pointing north and south.
|
||||
CursorRowResize
|
||||
// CursorGrab is for content that can be grabbed (dragged to be moved).
|
||||
// Usually displayed as an open hand.
|
||||
CursorGrab
|
||||
// CursorGrabbing is for content that is being grabbed (dragged to be moved).
|
||||
// Usually displayed as a closed hand.
|
||||
CursorGrabbing
|
||||
// CursorNotAllowed is shown when the request action cannot be carried out.
|
||||
// Usually displayed as a circle with a line through.
|
||||
CursorNotAllowed
|
||||
// CursorWait is shown when the program is busy and user cannot interact.
|
||||
// Usually displayed as a hourglass or the system equivalent.
|
||||
CursorWait
|
||||
// CursorProgress is shown when the program is busy, but the user can still interact.
|
||||
// Usually displayed as a default cursor with a hourglass.
|
||||
CursorProgress
|
||||
// CursorNorthWestResize is for top-left corner resizing.
|
||||
// Usually displayed as an arrow towards north-west.
|
||||
CursorNorthWestResize
|
||||
// CursorNorthEastResize is for top-right corner resizing.
|
||||
// Usually displayed as an arrow towards north-east.
|
||||
CursorNorthEastResize
|
||||
// CursorSouthWestResize is for bottom-left corner resizing.
|
||||
// Usually displayed as an arrow towards south-west.
|
||||
CursorSouthWestResize
|
||||
// CursorSouthEastResize is for bottom-right corner resizing.
|
||||
// Usually displayed as an arrow towards south-east.
|
||||
CursorSouthEastResize
|
||||
// CursorNorthSouth is for top-bottom resizing.
|
||||
// Usually displayed as a bi-directional arrow towards north-south.
|
||||
CursorNorthSouthResize
|
||||
// CursorEastWestResize is for left-right resizing.
|
||||
// Usually displayed as a bi-directional arrow towards east-west.
|
||||
CursorEastWestResize
|
||||
// CursorWestResize is for left resizing.
|
||||
// Usually displayed as an arrow towards west.
|
||||
CursorWestResize
|
||||
// CursorEastResize is for right resizing.
|
||||
// Usually displayed as an arrow towards east.
|
||||
CursorEastResize
|
||||
// CursorNorthResize is for top resizing.
|
||||
// Usually displayed as an arrow towards north.
|
||||
CursorNorthResize
|
||||
// CursorSouthResize is for bottom resizing.
|
||||
// Usually displayed as an arrow towards south.
|
||||
CursorSouthResize
|
||||
// CursorNorthEastSouthWestResize is for top-right to bottom-left diagonal resizing.
|
||||
// Usually displayed as a double ended arrow on the corresponding diagonal.
|
||||
CursorNorthEastSouthWestResize
|
||||
// CursorNorthWestSouthEastResize is for top-left to bottom-right diagonal resizing.
|
||||
// Usually displayed as a double ended arrow on the corresponding diagonal.
|
||||
CursorNorthWestSouthEastResize
|
||||
)
|
||||
|
||||
const (
|
||||
// A Cancel event is generated when the current gesture is
|
||||
// interrupted by other handlers or the system.
|
||||
Cancel Kind = 1 << iota
|
||||
// Press of a pointer.
|
||||
Press
|
||||
// Release of a pointer.
|
||||
Release
|
||||
// Move of a pointer.
|
||||
Move
|
||||
// Drag of a pointer.
|
||||
Drag
|
||||
// Pointer enters an area watching for pointer input
|
||||
Enter
|
||||
// Pointer leaves an area watching for pointer input
|
||||
Leave
|
||||
// Scroll of a pointer.
|
||||
Scroll
|
||||
)
|
||||
|
||||
const (
|
||||
// Mouse generated event.
|
||||
Mouse Source = iota
|
||||
// Touch generated event.
|
||||
Touch
|
||||
)
|
||||
|
||||
const (
|
||||
// Shared priority is for handlers that
|
||||
// are part of a matching set larger than 1.
|
||||
Shared Priority = iota
|
||||
// Grabbed is used for matching sets of size 1.
|
||||
Grabbed
|
||||
)
|
||||
|
||||
const (
|
||||
// ButtonPrimary is the primary button, usually the left button for a
|
||||
// right-handed user.
|
||||
ButtonPrimary Buttons = 1 << iota
|
||||
// ButtonSecondary is the secondary button, usually the right button for a
|
||||
// right-handed user.
|
||||
ButtonSecondary
|
||||
// ButtonTertiary is the tertiary button, usually the middle button.
|
||||
ButtonTertiary
|
||||
// ButtonQuaternary is the fourth button, usually used for browser
|
||||
// navigation (backward)
|
||||
ButtonQuaternary
|
||||
// ButtonQuinary is the fifth button, usually used for browser
|
||||
// navigation (forward)
|
||||
ButtonQuinary
|
||||
)
|
||||
|
||||
func (s ScrollRange) Union(s2 ScrollRange) ScrollRange {
|
||||
return ScrollRange{
|
||||
Min: min(s.Min, s2.Min),
|
||||
Max: max(s.Max, s2.Max),
|
||||
}
|
||||
}
|
||||
|
||||
// Push the current pass mode to the pass stack and set the pass mode.
|
||||
func (p PassOp) Push(o *op.Ops) PassStack {
|
||||
id, mid := ops.PushOp(&o.Internal, ops.PassStack)
|
||||
data := ops.Write(&o.Internal, ops.TypePassLen)
|
||||
data[0] = byte(ops.TypePass)
|
||||
return PassStack{ops: &o.Internal, id: id, macroID: mid}
|
||||
}
|
||||
|
||||
func (p PassStack) Pop() {
|
||||
ops.PopOp(p.ops, ops.PassStack, p.id, p.macroID)
|
||||
data := ops.Write(p.ops, ops.TypePopPassLen)
|
||||
data[0] = byte(ops.TypePopPass)
|
||||
}
|
||||
|
||||
func (op Cursor) Add(o *op.Ops) {
|
||||
data := ops.Write(&o.Internal, ops.TypeCursorLen)
|
||||
data[0] = byte(ops.TypeCursor)
|
||||
data[1] = byte(op)
|
||||
}
|
||||
|
||||
func (t Kind) String() string {
|
||||
if t == Cancel {
|
||||
return "Cancel"
|
||||
}
|
||||
var buf strings.Builder
|
||||
for tt := Kind(1); tt > 0; tt <<= 1 {
|
||||
if t&tt > 0 {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('|')
|
||||
}
|
||||
buf.WriteString((t & tt).string())
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (t Kind) string() string {
|
||||
switch t {
|
||||
case Press:
|
||||
return "Press"
|
||||
case Release:
|
||||
return "Release"
|
||||
case Cancel:
|
||||
return "Cancel"
|
||||
case Move:
|
||||
return "Move"
|
||||
case Drag:
|
||||
return "Drag"
|
||||
case Enter:
|
||||
return "Enter"
|
||||
case Leave:
|
||||
return "Leave"
|
||||
case Scroll:
|
||||
return "Scroll"
|
||||
default:
|
||||
panic("unknown Type")
|
||||
}
|
||||
}
|
||||
|
||||
func (p Priority) String() string {
|
||||
switch p {
|
||||
case Shared:
|
||||
return "Shared"
|
||||
case Grabbed:
|
||||
return "Grabbed"
|
||||
default:
|
||||
panic("unknown priority")
|
||||
}
|
||||
}
|
||||
|
||||
func (s Source) String() string {
|
||||
switch s {
|
||||
case Mouse:
|
||||
return "Mouse"
|
||||
case Touch:
|
||||
return "Touch"
|
||||
default:
|
||||
panic("unknown source")
|
||||
}
|
||||
}
|
||||
|
||||
// Contain reports whether the set b contains
|
||||
// all of the buttons.
|
||||
func (b Buttons) Contain(buttons Buttons) bool {
|
||||
return b&buttons == buttons
|
||||
}
|
||||
|
||||
func (b Buttons) String() string {
|
||||
var strs []string
|
||||
if b.Contain(ButtonPrimary) {
|
||||
strs = append(strs, "ButtonPrimary")
|
||||
}
|
||||
if b.Contain(ButtonSecondary) {
|
||||
strs = append(strs, "ButtonSecondary")
|
||||
}
|
||||
if b.Contain(ButtonTertiary) {
|
||||
strs = append(strs, "ButtonTertiary")
|
||||
}
|
||||
if b.Contain(ButtonQuaternary) {
|
||||
strs = append(strs, "ButtonQuaternary")
|
||||
}
|
||||
if b.Contain(ButtonQuinary) {
|
||||
strs = append(strs, "ButtonQuinary")
|
||||
}
|
||||
return strings.Join(strs, "|")
|
||||
}
|
||||
|
||||
func (c Cursor) String() string {
|
||||
switch c {
|
||||
case CursorDefault:
|
||||
return "Default"
|
||||
case CursorNone:
|
||||
return "None"
|
||||
case CursorText:
|
||||
return "Text"
|
||||
case CursorVerticalText:
|
||||
return "VerticalText"
|
||||
case CursorPointer:
|
||||
return "Pointer"
|
||||
case CursorCrosshair:
|
||||
return "Crosshair"
|
||||
case CursorAllScroll:
|
||||
return "AllScroll"
|
||||
case CursorColResize:
|
||||
return "ColResize"
|
||||
case CursorRowResize:
|
||||
return "RowResize"
|
||||
case CursorGrab:
|
||||
return "Grab"
|
||||
case CursorGrabbing:
|
||||
return "Grabbing"
|
||||
case CursorNotAllowed:
|
||||
return "NotAllowed"
|
||||
case CursorWait:
|
||||
return "Wait"
|
||||
case CursorProgress:
|
||||
return "Progress"
|
||||
case CursorNorthWestResize:
|
||||
return "NorthWestResize"
|
||||
case CursorNorthEastResize:
|
||||
return "NorthEastResize"
|
||||
case CursorSouthWestResize:
|
||||
return "SouthWestResize"
|
||||
case CursorSouthEastResize:
|
||||
return "SouthEastResize"
|
||||
case CursorNorthSouthResize:
|
||||
return "NorthSouthResize"
|
||||
case CursorEastWestResize:
|
||||
return "EastWestResize"
|
||||
case CursorWestResize:
|
||||
return "WestResize"
|
||||
case CursorEastResize:
|
||||
return "EastResize"
|
||||
case CursorNorthResize:
|
||||
return "NorthResize"
|
||||
case CursorSouthResize:
|
||||
return "SouthResize"
|
||||
case CursorNorthEastSouthWestResize:
|
||||
return "NorthEastSouthWestResize"
|
||||
case CursorNorthWestSouthEastResize:
|
||||
return "NorthWestSouthEastResize"
|
||||
default:
|
||||
panic("unknown Type")
|
||||
}
|
||||
}
|
||||
|
||||
func (Event) ImplementsEvent() {}
|
||||
|
||||
func (GrabCmd) ImplementsCommand() {}
|
||||
|
||||
func (Filter) ImplementsFilter() {}
|
||||
Reference in New Issue
Block a user