github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/io/pointer/pointer.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package pointer 4 5 import ( 6 "encoding/binary" 7 "image" 8 "strings" 9 "time" 10 11 "github.com/gop9/olt/gio/f32" 12 "github.com/gop9/olt/gio/internal/opconst" 13 "github.com/gop9/olt/gio/io/event" 14 "github.com/gop9/olt/gio/io/key" 15 "github.com/gop9/olt/gio/op" 16 ) 17 18 // Event is a pointer event. 19 type Event struct { 20 Type Type 21 Source Source 22 // PointerID is the id for the pointer and can be used 23 // to track a particular pointer from Press to 24 // Release or Cancel. 25 PointerID ID 26 // Priority is the priority of the receiving handler 27 // for this event. 28 Priority Priority 29 // Time is when the event was received. The 30 // timestamp is relative to an undefined base. 31 Time time.Duration 32 // Buttons are the set of pressed mouse buttons for this event. 33 Buttons Buttons 34 // Hit is set when the event was within the registered 35 // area for the handler. Hit can be false when a pointer 36 // was pressed within the hit area, and then dragged 37 // outside it. 38 Hit bool 39 // Position is the position of the event, relative to 40 // the current transformation, as set by op.TransformOp. 41 Position f32.Point 42 // Scroll is the scroll amount, if any. 43 Scroll f32.Point 44 // Modifiers is the set of active modifiers when 45 // the mouse button was pressed. 46 Modifiers key.Modifiers 47 } 48 49 // AreaOp updates the hit area to the intersection of the current 50 // hit area and the area. The area is transformed before applying 51 // it. 52 type AreaOp struct { 53 kind areaKind 54 rect image.Rectangle 55 } 56 57 // InputOp declares an input handler ready for pointer 58 // events. 59 type InputOp struct { 60 Key event.Key 61 // Grab, if set, request that the handler get 62 // Grabbed priority. 63 Grab bool 64 } 65 66 // PassOp sets the pass-through mode. 67 type PassOp struct { 68 Pass bool 69 } 70 71 type ID uint16 72 73 // Type of an Event. 74 type Type uint8 75 76 // Priority of an Event. 77 type Priority uint8 78 79 // Source of an Event. 80 type Source uint8 81 82 // Buttons is a set of mouse buttons 83 type Buttons uint8 84 85 // Must match app/internal/input.areaKind 86 type areaKind uint8 87 88 const ( 89 // A Cancel event is generated when the current gesture is 90 // interrupted by other handlers or the system. 91 Cancel Type = iota 92 // Press of a pointer. 93 Press 94 // Release of a pointer. 95 Release 96 // Move of a pointer. 97 Move 98 ) 99 100 const ( 101 // Mouse generated event. 102 Mouse Source = iota 103 // Touch generated event. 104 Touch 105 ) 106 107 const ( 108 // Shared priority is for handlers that 109 // are part of a matching set larger than 1. 110 Shared Priority = iota 111 // Grabbed is used for matching sets of size 1. 112 Grabbed 113 ) 114 115 const ( 116 ButtonLeft Buttons = 1 << iota 117 ButtonRight 118 ButtonMiddle 119 ) 120 121 const ( 122 areaRect areaKind = iota 123 areaEllipse 124 ) 125 126 // Rect constructs a rectangular hit area. 127 func Rect(size image.Rectangle) AreaOp { 128 return AreaOp{ 129 kind: areaRect, 130 rect: size, 131 } 132 } 133 134 // Ellipse constructs an ellipsoid hit area. 135 func Ellipse(size image.Rectangle) AreaOp { 136 return AreaOp{ 137 kind: areaEllipse, 138 rect: size, 139 } 140 } 141 142 func (op AreaOp) Add(o *op.Ops) { 143 data := o.Write(opconst.TypeAreaLen) 144 data[0] = byte(opconst.TypeArea) 145 data[1] = byte(op.kind) 146 bo := binary.LittleEndian 147 bo.PutUint32(data[2:], uint32(op.rect.Min.X)) 148 bo.PutUint32(data[6:], uint32(op.rect.Min.Y)) 149 bo.PutUint32(data[10:], uint32(op.rect.Max.X)) 150 bo.PutUint32(data[14:], uint32(op.rect.Max.Y)) 151 } 152 153 func (h InputOp) Add(o *op.Ops) { 154 data := o.Write(opconst.TypePointerInputLen, h.Key) 155 data[0] = byte(opconst.TypePointerInput) 156 if h.Grab { 157 data[1] = 1 158 } 159 } 160 161 func (op PassOp) Add(o *op.Ops) { 162 data := o.Write(opconst.TypePassLen) 163 data[0] = byte(opconst.TypePass) 164 if op.Pass { 165 data[1] = 1 166 } 167 } 168 169 func (t Type) String() string { 170 switch t { 171 case Press: 172 return "Press" 173 case Release: 174 return "Release" 175 case Cancel: 176 return "Cancel" 177 case Move: 178 return "Move" 179 default: 180 panic("unknown Type") 181 } 182 } 183 184 func (p Priority) String() string { 185 switch p { 186 case Shared: 187 return "Shared" 188 case Grabbed: 189 return "Grabbed" 190 default: 191 panic("unknown priority") 192 } 193 } 194 195 func (s Source) String() string { 196 switch s { 197 case Mouse: 198 return "Mouse" 199 case Touch: 200 return "Touch" 201 default: 202 panic("unknown source") 203 } 204 } 205 206 // Contain reports whether the set b contains 207 // all of the buttons. 208 func (b Buttons) Contain(buttons Buttons) bool { 209 return b&buttons == buttons 210 } 211 212 func (b Buttons) String() string { 213 var strs []string 214 if b.Contain(ButtonLeft) { 215 strs = append(strs, "ButtonLeft") 216 } 217 if b.Contain(ButtonRight) { 218 strs = append(strs, "ButtonRight") 219 } 220 if b.Contain(ButtonMiddle) { 221 strs = append(strs, "ButtonMiddle") 222 } 223 return strings.Join(strs, "|") 224 } 225 226 func (Event) ImplementsEvent() {}