github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/io/pointer/doc.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 /* 4 Package pointer implements pointer events and operations. 5 A pointer is either a mouse controlled cursor or a touch 6 object such as a finger. 7 8 The InputOp operation is used to declare a handler ready for pointer 9 events. Use an event.Queue to receive events. 10 11 Areas 12 13 The area operations are used for specifying the area where 14 subsequent InputOp are active. 15 16 For example, to set up a rectangular hit area: 17 18 var ops op.Ops 19 var h *Handler = ... 20 21 r := image.Rectangle{...} 22 pointer.Rect().Add(ops) 23 pointer.InputOp{Key: h}.Add(ops) 24 25 Note that areas compound: the effective area of multiple area 26 operations is the intersection of the areas. 27 28 Matching events 29 30 StackOp operations and input handlers form an implicit tree. 31 Each stack operation is a node, and each input handler is associated 32 with the most recent node. 33 34 For example: 35 36 ops := new(op.Ops) 37 var stack op.StackOp 38 var h1, h2 *Handler 39 40 stack.Push(ops) 41 pointer.InputOp{Key: h1}.Add(Ops) 42 stack.Pop() 43 44 stack.Push(ops) 45 pointer.InputOp{Key: h2}.Add(ops) 46 stack.Pop() 47 48 implies a tree of two inner nodes, each with one pointer handler. 49 50 When determining which handlers match an Event, only handlers whose 51 areas contain the event position are considered. The matching 52 proceeds as follows. 53 54 First, the foremost matching handler is included. If the handler 55 has pass-through enabled, this step is repeated. 56 57 Then, all matching handlers from the current node and all parent 58 nodes are included. 59 60 In the example above, all events will go to h2 only even though both 61 handlers have the same area (the entire screen). 62 63 Pass-through 64 65 The PassOp operations controls the pass-through setting. A handler's 66 pass-through setting is recorded along with the InputOp. 67 68 Pass-through handlers are useful for overlay widgets such as a hidden 69 side drawer. When the user touches the side, both the (transparent) 70 drawer handle and the interface below should receive pointer events. 71 72 Disambiguation 73 74 When more than one handler matches a pointer event, the event queue 75 follows a set of rules for distributing the event. 76 77 As long as the pointer has not received a Press event, all 78 matching handlers receive all events. 79 80 When a pointer is pressed, the set of matching handlers is 81 recorded. The set is not updated according to the pointer position 82 and hit areas. Rather, handlers stay in the matching set until they 83 no longer appear in a InputOp or when another handler in the set 84 grabs the pointer. 85 86 A handler can exclude all other handler from its matching sets 87 by setting the Grab flag in its InputOp. The Grab flag is sticky 88 and stays in effect until the handler no longer appears in any 89 matching sets. 90 91 The losing handlers are notified by a Cancel event. 92 93 For multiple grabbing handlers, the foremost handler wins. 94 95 Priorities 96 97 Handlers know their position in a matching set of a pointer through 98 event priorities. The Shared priority is for matching sets with 99 multiple handlers; the Grabbed priority indicate exclusive access. 100 101 Priorities are useful for deferred gesture matching. 102 103 Consider a scrollable list of clickable elements. When the user touches an 104 element, it is unknown whether the gesture is a click on the element 105 or a drag (scroll) of the list. While the click handler might light up 106 the element in anticipation of a click, the scrolling handler does not 107 scroll on finger movements with lower than Grabbed priority. 108 109 Should the user release the finger, the click handler registers a click. 110 111 However, if the finger moves beyond a threshold, the scrolling handler 112 determines that the gesture is a drag and sets its Grab flag. The 113 click handler receives a Cancel (removing the highlight) and further 114 movements for the scroll handler has priority Grabbed, scrolling the 115 list. 116 */ 117 package pointer