123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- // 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 or Cancel.
- 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
- // Foremost priority is like Shared, but the
- // handler is the foremost of the matching set.
- Foremost
- // 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
- )
- 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 Foremost:
- return "Foremost"
- 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")
- }
- 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() {}
|