Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(831)

Side by Side Diff: sky/specs/gestures.md

Issue 880963005: Specs: Yet Another Gesture Model (mark IV). This one handles (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/specs/events.md ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 Gestures 1 Gestures
2 ======== 2 ========
3 3
4 TODO(ianh): make it possible for a Gesture to time out and cancel even
5 without having seen a pointer event, to handle double-tap events
6
7 TODO(ianh): even with that, we should keep track of finished-but-valid
8 candidates so that when double-tap cancels itself, the tap, which was
9 still valid even though it's done, can be accepted
10
11 ```javascript 4 ```javascript
12 5 typedef PointerID Integer;
13 callback GestureCallback void (Event event);
14 6
15 dictionary GestureState { 7 dictionary GestureState {
16 Boolean valid = false; // if true, the event was part of the current gesture 8 Boolean cancel = true; // if true, then cancel the gesture at this point
17 Boolean forceCommit = false; // if true, the gesture thinks that other gestu res should give up 9 Boolean capture = false; // (for pointer-down) if true, then this pointer is r elevant
10 Boolean choose = false; // if true, the gesture thinks that other gestures sho uld give up
18 Boolean finished = true; // if true, we're ready for the next gesture to start 11 Boolean finished = true; // if true, we're ready for the next gesture to start
12
13 // choose and cancel are mutually exclusive
19 } 14 }
20 15
21 dictionary SendEventOptions { 16 dictionary SendEventOptions {
22 Integer? coallesceGroup = null; // when queuing events, only the last event wi th each group is kept 17 Integer? coallesceGroup = null; // when queuing events, only the last event wi th each group is kept
23 Boolean precommit = false; // if true, event should just be sent right away, n ot queued 18 Boolean prechoose = false; // if true, event should just be sent right away, n ot queued
24 } 19 }
25 20
26 abstract class Gesture { 21 abstract class Gesture : EventTarget {
27 constructor (); 22 constructor (EventTarget target);
28 23 readonly attribute EventTarget target;
29 attribute GestureCallback callback; 24
30 // set by GestureChooser to point to itself 25 virtual GestureState processEvent(Event event);
31 26 // return {}
32 GestureState processEvent(EventTarget target, Event event); 27 virtual void choose(); // called by GestureManager // make sure to call superc lass choose() before
33 // - if this.ready=true: 28 // - assert: this.active == true
34 // - clear the sendEvent() buffer 29 // - assert: this.chosen == false
35 // - set this.accepted = false 30 // - set this.chosen = true
36 // - let returnValue = this.processEventInternal(...) 31 // - if there are any buffered events, dispatch them on this
37 // - if this.discarding: 32 virtual void cancel(); // called by GestureManager // make sure to call superc lass cancel() after
38 // - assert: returnValue.valid == false 33 // - set active and chosen to false, clear the event buffer
39 // - if returnValue.valid == false 34
40 // - assert: returnValue.forceCommit == false 35 readonly attribute Boolean ready; // last event, we were finished
41 // - if !returnValue.valid, then: 36 readonly attribute Boolean active; // we have not yet been canceled since we l ast captured a pointer
42 // - clear the sendEvent() buffer 37 readonly attribute Boolean chosen; // we're the only possible gesture at this point
43 // - set this.accepted = false 38
44 // - set this.canceled = !returnValue.valid 39 // !ready && !active => we're discarding events until the user gets to a state where a new gesture can begin
45 // - set this.ready = returnValue.finished 40 // active && !chosen => we're collecting events until no other gesture is vali d, or until we take command
46 // - set this.discarding = !returnValue.valid && !returnValue.finished
47 // - set this.active = returnValue.valid && !returnValue.finished
48 // - return returnValue
49
50 readonly attribute Boolean canceled; // defaults to false
51 // true if either the last time processEvent was invoked, valid was
52 // false, or, we have been cancel()ed
53
54 readonly attribute Boolean ready; // defaults to true
55 // true if the last time processEvent was invoked, the gesture was
56 // over
57
58 readonly attribute Boolean discarding; // defaults to false
59 // true if the last time processEvent was invoked, valid was false
60 // and finished was false, or, we have been cancel()ed
61 // (aka canceled && !ready)
62
63 readonly attribute Boolean active; // defaults to false
64 // true if the last time processEvent was invoked, valid was true
65 // and finished was false, and we haven't been cancel()ed
66 // (aka !canceled && !ready)
67
68 readonly attribute Boolean accepted; // defaults to false
69 // true accept() was called and we haven't been cancel()ed since
70
71 void accept();
72 // assert: this.canceled == false
73 // set accepted = true
74 // send the buffered gesture events to the callback
75 // - call this immediately after getting a positive result from
76 // processEvent()
77
78 virtual void cancel();
79 // called to indicate that this gesture isn't going to be chosen,
80 // or if it was chosen, that it is finished
81 // - assert: this.canceled == false
82 // - set this.canceled = true
83 // - set this.discarding = !this.ready
84 // - set this.active = false
85 // - clear the sendEvent() buffer
86 // - set this.accepted = false
87 // - descendants may override this if they have more state to drop,
88 // or if they want to send an event to report that it's canceled,
89 // especially if this.accepted is true
90
91 virtual void reset();
92 // called immediately after the first pointer-down of a possible
93 // gesture is sent to processEvents() to indicate that the pointer
94 // wasn't captured so we are to forget anything ever happened (later
95 // pointer-downs are always captured)
96 // - set this.canceled = true
97 // - set this.ready = true
98 // - set this.discarding = false
99 // - set this.active = false
100 // - clear the sendEvent() buffer
101 // - set this.accepted = false
102 // - descendants may override this if they have more state to drop
103
104 // internal API:
105
106 virtual GestureState processEventInternal(EventTarget target, Event event);
107 // descendants override this
108 // default implementation returns { } (defaults)
109 // - if this.discarding == false, then:
110 // - optionally, call sendEvent() to fire gesture-specific
111 // events
112 // - as the events are received, they get examined to see if they
113 // fit the pattern for the gesture; if they do, then return an
114 // object with valid=true; if more events for this gesture could
115 // still come in, return finished=false.
116 // - if you returned valid=false finished=false, then the next call
117 // to this must not return valid=true
118 // - doing anything with the event or target other than reading
119 // state is a contract violation
120 // - you are allowed to call sendEvent() at any time during a
121 // processEventInternal() call, or after a call to
122 // processEventInternal(), assuming that the last such call
123 // returned either valid=true or finished=true, until the next
124 // call to processEventInternal() or cancel().
125 // - set forceCommit=true on the return value if you are confident
126 // that this is the gesture the user meant, even if it's possible
127 // that another gesture is still claiming it's valid (e.g. a long
128 // press might forceCommit to override a scroll, if the user
129 // hasn't moved for a while)
130 // - if you send events, you can set precommit=true to send the
131 // event even before the gesture has been accepted
132 // - if you send precommit events, make sure to send corresponding
133 // "cancel" events if reset() or cancel() are called
134 41
135 void sendEvent(Event event, SendEventOptions options); 42 void sendEvent(Event event, SendEventOptions options);
136 // used internally to queue up or send events 43 // used internally to queue up or send events
137 // - assert: this.discarding == false 44 // - assert: this.active == true
138 // - assert: options.precommit is false or options.coallesceGroup 45 // - assert: options.prechoose is false or options.coallesceGroup
139 // is null 46 // is null
140 // - set event.gesture = this 47 // - set event.gesture = this
141 // - if this.accepted is true or if options.precommit is true, then 48 // - if this.chosen is true or if options.prechoose is true, then
142 // send the event straight to the callback 49 // send the event straight to the callback
143 // - otherwise: 50 // - otherwise:
144 // - if the buffer has an entry with the same coallesceGroup 51 // - if the event buffer has an entry with the same
145 // identifier, drop it 52 // coallesceGroup identifier, drop it
146 // - add the event to the buffer 53 // - add the event to the event buffer
147 } 54 }
148 55 ```
149 class GestureChooser : EventTarget { 56
150 constructor (EventTarget? target = null, Array<Gesture> candidates = []); 57 ``Gesture`` objects have an Event buffer, initially empty. Each Event
151 // throws if any of the candidates are active 58 in this buffer can be associated with a coallesceGroup, which is
152 59 identified by integer.
153 readonly attribute EventTarget? target; 60
154 void setTarget(EventTarget? target); 61 When created, ``Gesture`` objects register themselves as pointer-down,
155 62 pointer-move, and pointer-up event handlers on their target, with the
156 Array<Gesture> getGestures(); 63 same event handler. That event handler runs the following steps:
157 void addGesture(Gesture candidate); 64 - let wasActive = this.active
158 // throw if candidates.active is true 65 - if this.ready == true, then:
159 void removeGesture(Gesture candidate); 66 - // reset the state to start a new gesture
160 // if active is true and candidate was the last Gesture in our list 67 - if this.active == true, then:
161 // to be active, set active and accepted to false 68 - call application.document.cancelGesture(this)
162 69 - set this.active = true
163 // while target is not null and the list of candidates is not empty, 70 - set this.ready = false
164 // ensures that it is registered as an event listener for 71 - let returnValue be the result of calling ``processEvent()`` with
165 // pointer-down, pointer-move, and pointer-up events on the target; 72 the Event object
166 // when the target changes, or when the list of candidates is 73 - if returnValue.capture == true:
167 // emptied, unregisters itself 74 - assert: the event is a pointer-down event
168 75 - if the event is a pointer-down event:
169 readonly attribute Boolean active; // at least one of the gestures is active ( initially false) 76 - push this onto the event's return value
170 readonly attribute Boolean accepted; // we accepted a gesture since the last t ime active was false (initially false) 77 - if returnValue.cancel == true:
171 78 - assert: returnValue.choose == false
172 // internal state: 79 - if wasActive == true:
173 // /candidates/ is a list of Gesture objects, initially empty 80 - call application.document.cancelGesture(this)
174 // 81 - // if wasActive == false, then no need to cancel, since we never added ourselves
175 // any time one of the pointer events is received: 82 - if returnValue.cancel == false and this.active == true:
176 // - if it's pointer-down and it's already captured, ignore the 83 - if wasActive == false or if event is a pointer-down event:
177 // event and skip the remaining steps 84 - call application.document.addGesture(event, this)
178 // - let captured be a boolean 85 - if returnValue.choose == true:
179 // - if /candidates/ is empty, then: 86 - call application.document.chooseGesture(this)
180 // - set captured to false 87 - set this.ready = returnValue.finished
181 // - if accepted is true, call cancel() on whatever the last 88 - set this.active = returnValue.valid
182 // accepted candidate was, if any 89
183 // - add all the registered Gestures to /candidates/ 90 Subclasses should override ``processEvent()``:
184 // - otherwise: 91 - as the events are received, they get examined to see if they
185 // - set captured to true 92 fit the pattern for the gesture; if they do, then return an
186 // - if it's pointer-down, capture the event 93 object with valid=true; if more events for this gesture could
187 // - call processEvent() with the event on all the Gestures in 94 still come in, return finished=false.
188 // /candidates/, collecting their return values (GestureState 95 - if you returned valid=false finished=false, then the next call
189 // objects) 96 to this must not return valid=true
190 // - set forcingAccept to false 97 - doing anything with the event or target other than reading
191 // - set willAccept to null 98 state is a contract violation
192 // - for each Gesture in /candidates/, in registration order: 99 - you are allowed to call sendEvent() at any time during a
193 // - if it returned valid==false, then 100 processEventInternal() call, or after a call to
194 // - if it is our last accepted candidate, then: 101 processEventInternal(), assuming that the last such call returned
195 // - set this.accepted = false 102 valid=true, until the next call to processEventInternal() or
196 // - if it returned valid==true: 103 cancel().
197 // - if it's pointer-down, then: 104 - set forceChoose=true on the return value if you are confident
198 // - set captured to true 105 that this is the gesture the user meant, even if it's possible
199 // - capture the event 106 that another gesture is still claiming it's valid (e.g. a long
200 // - if this.accepted == true: 107 press might forceChoose to override a scroll, if the user
201 // - assert: this Gesture is the last accepted candidate 108 hasn't moved for a while)
202 // - if it returned forceCommit==true then: 109 - if you send events, you can set prechoose=true to send the
203 // - assert that its accepted attribute is false 110 event even before the gesture has been chosen
204 // - if forcingAccept is false, then: 111 - if you send prechoose events, make sure to send corresponding
205 // - set willAccept to this Gesture 112 "cancel" events if cancel() is called
206 // - set forcingAccept to true 113
207 // - otherwise: 114 ```javascript
208 // - if forcingAccept is false: 115 dictionary GestureList {
209 // - if willAccept is null: 116 Array<Gesture> gestures;
210 // - set willAccept to this Gesture 117 Boolean chosen;
211 // - otherwise: 118 }
212 // - set willAccept to 'undecided' 119
213 // - if it returned finished==true 120 class GestureManager {
214 // - remove the Gesture from /candidates/ 121 constructor (EventTarget target);
215 // - if willAccept is set to a Gesture: 122 readonly attribute EventTarget target; // the ApplicationDocument, normally
216 // - set this.accepted = true 123
217 // - call the Gesture's accept() method; this is now the last 124 void addGesture(Event event, Gesture gesture);
218 // accepted candidate 125 void cancelGesture(Gesture gesture);
219 // - call cancel() on all the other Gesture objects that returned 126 void chooseGesture(Gesture gesture);
220 // valid==true 127
221 // - if captured is false: 128 GestureList getActiveGestures(PointerID pointer);
222 // - call reset() on all the gestures in /candidates/, and then 129 }
223 // let /candidates/ be empty 130 ```
224 // - if /candidates/ is now empty, then set active to false; 131
225 // otherwise, set active to true 132 ``GestureManager`` objects have a map of lists of Gesture objects,
226 133 keyed on pointer IDs, and with each list associated with a "chosen"
227 } 134 flag indicating if an entry in the list has already been chosen.
228 135 Initially the map is empty. It is exposed by the
136 ``getActiveGestures()`` method, which returns the list and flag.
137
138 When addGesture() is called with an event and a Gesture, it runs the
139 following steps:
140 - let pointer be the value of the event's pointer field
141 - assert: pointer is an integer
142 - if we already have an entry for pointer:
143 - assert: this Gesture isn't already on the list for pointer
144 - if the list's "chosen" flag is set, then call
145 ``cancelGesture()`` with this Gesture
146 - otherwise, add this Gesture to the list for pointer
147 - otherwise, we don't have an entry for this pointer:
148 - create a list for pointer
149 - add this Gesture to the list for pointer
150
151 A ``GestureManager``, when created, starts listening to
152 ``pointer-down`` events on its target. The listener acts as follows:
153 - assert: event is a ``pointer-down`` event
154 - let pointer be the value of the event's pointer field
155 - if we have an entry for this pointer, and the "chosen" flag isn't
156 set, and there is just one Gesture in the list, then set the flag
157 on the list and call the Gesture's ``choose()`` method.
158
159 When ``cancelGesture()`` is called with a Gesture:
160 - for each pointer list:
161 - if the pointer list has this Gesture, remove it
162 - call cancel() on the Gesture
163 - for each pointer list:
164 - if the pointer list has no entries, forget it
165 - if the pointer list has one Gesture and the "chosen" flag isn't
166 set, set it and call that Gesture's ``choose()`` method.
167
168 When ``chooseGesture()`` is called with a Gesture:
169 - if this Gesture is not active, then return silently
170 // this could happen e.g. if two gestures simultaneously add themselves
171 // and chose themselves for the same pointer-down
172 - let losers be an empty list of Gestures
173 - for each pointer list:
174 - if the pointer list has this Gesture, add all the other Gestures
175 in the list to losers, remove them from the list, and set the
176 "chosen" flag on that list
177 - remove duplicates from losers
178 - call ``cancel()`` on each entry in losers
179 - call ``choose()`` on the Gesture
180
181
182 ```javascript
229 class TapGesture : Gesture { 183 class TapGesture : Gesture {
230 184
231 // internal state: 185 // internal state:
232 // Integer numButtons = 0; 186 // Integer numButtons = 0;
233 // Boolean primaryDown = false; 187 // Boolean primaryDown = false;
234 188
235 virtual Boolean internalProcessEvent(EventTarget target, Event event); 189 virtual GestureState processEvent(Event event);
190 // - let returnValue = { finished = false }
236 // - if the event is a pointer-down: 191 // - if the event is a pointer-down:
237 // - increment this.numButtons 192 // - increment this.numButtons
193 // - set returnValue.capture = true
238 // - otherwise if it is a pointer-up: 194 // - otherwise if it is a pointer-up:
239 // - assert: this.numButtons > 0 195 // - assert: this.numButtons > 0
240 // - decrement this.numButtons 196 // - decrement this.numButtons
241 // - if this.discarding == true: 197 // - if numButtons == 0:
242 // return { valid: false, finished: this.numButtons == 0 } 198 // - set returnValue.finished = true
199 // - if this.ready == false and this.active == false:
200 // - return returnValue
243 // - if EventTarget isn't an Element: 201 // - if EventTarget isn't an Element:
244 // - assert: event is a pointer-down 202 // - assert: event is a pointer-down
245 // - assert: this.numButtons > 0 203 // - return returnValue
246 // - return { valid: false, finished: false }
247 // - if the event is pointer-down: 204 // - if the event is pointer-down:
248 // - assert: this.numButtons > 0 205 // - assert: this.numButtons > 0
249 // - if it's primary: 206 // - if it's primary:
250 // - assert: this.ready==true // this is the first press 207 // - assert: this.ready==true // this is the first press
251 // - this.primaryDown = true 208 // - this.primaryDown = true
252 // - sendEvent() a tap-down event, with precommit=true 209 // - sendEvent() a tap-down event, with prechoose=true
253 // - return { valid: true, finished: false } 210 // - set returnValue.cancel = false
211 // - return returnValue
254 // - otherwise: 212 // - otherwise:
255 // - if this.ready == false: 213 // - if this.primaryDown == true and this.active == true:
256 // - // this is a right-click or similar 214 // - // this is some bogus secondary press that we should have preven t
257 // - return { valid: false, finished: false } 215 // // taps from starting until it's finished, but it doesn't invali date
258 // - otherwise, if this.canceled==false: 216 // // the existing primary press
259 // - assert: this.active==true 217 // - set returnValue.cancel = false
260 // - // this is some bogus secondary press that we should ignore 218 // - return returnValue
261 // // but it doesn't invalidate the existing primary press
262 // - return { valid true, finished: false }
263 // - otherwise: 219 // - otherwise:
264 // - // this is some secondary press but we don't have a first press 220 // - // this is some secondary press but we don't have a first press
265 // // we have to wait til it's done before we can start a 221 // // (maybe this is all in the context of a right-click or somethi ng)
266 // // tap gesture again 222 // // we have to wait til it's done before we can start a tap gestu re again
267 // - return { valid: false, finished: false } 223 // - return returnValue
268 // - otherwise: 224 // - if the event is pointer-move:
269 // - assert: this.active 225 // - assert: this.numButtons > 0
270 // // if we're ready, forcibly the first event we'll see is a pointer-down , 226 // - if it's primary:
271 // // so this.ready will never be true here 227 // - if it hit tests within target's bounding box:
272 // // if we're cancelled, then we won't get to here 228 // - sendEvent() a tap-move event, with prechoose=true
273 // - if the event is pointer-move: 229 // - set returnValue.cancel = false
274 // - assert: this.numButtons > 0 230 // - return returnValue
275 // // because otherwise we would have lost capture and thus not be gett ing the events 231 // - otherwise:
276 // - if it's primary: 232 // - sendEvent() a tap-cancel event, with prechoose=true
277 // - if it hit tests within target's bounding box: 233 // - return returnValue
278 // - sendEvent() a tap-move event, with precommit=true 234 // - otherwise:
279 // - return { valid: true, finished: false } 235 // - // this is the move of some bogus secondary press
280 // - otherwise: 236 // // ignore it, but continue listening if we have a primary button do wn
281 // - sendEvent() a tap-cancel event, with precommit=true 237 // - if this.primaryDown == true and this.active == true:
282 // - return { valid: false, finished: false } 238 // - set returnValue.cancel = false
283 // - otherwise: 239 // - return returnValue
284 // - // this is the move of some bogus secondary press 240 // - if the event is pointer-up:
285 // // ignore it, but continue listening 241 // - if it's primary:
286 // - return { valid: true, finished: false } 242 // - sendEvent() a tap event
287 // - if the event is pointer-up: 243 // - set this.primaryDown = false
288 // - if it's primary: 244 // - set returnValue.cancel = false
289 // - sendEvent() a tap event 245 // - return returnValue
290 // - this.primaryDown = false 246 // - otherwise:
291 // - return { valid: true, forceCommit: this.numButtons == 0, finished : this.numButtons == 0 } 247 // - // this is the 'up' of some bogus secondary press
292 // - otherwise: 248 // // ignore it, but continue listening for our primary up if necessar y
293 // - // this is the 'up' of some bogus secondary press 249 // - if this.primaryDown == true and this.active == true:
294 // // ignore it, but continue listening for our primary up 250 // - set returnValue.cancel = false
295 // - return { valid: this.primaryDown, finished: this.numButtons == 0 } 251 // - return returnValue
296 } 252 }
297 253
298 class LongPressGesture : Gesture { 254 class LongPressGesture : Gesture {
299 GestureState processEvent(EventTarget target, Event event); 255 GestureState processEvent(EventTarget target, Event event);
300 // long-tap-start: sent when the primary pointer goes down 256 // long-tap-start: sent when the primary pointer goes down
301 // long-tap-cancel: sent when cancel(), reset(), or finger goes out of boundin g box 257 // long-tap-cancel: sent when cancel()ed or finger goes out of bounding box
302 // long-tap: sent when the primary pointer is released 258 // long-tap: sent when the primary pointer is released
303 } 259 }
304 260
305 class DoubleTapGesture : Gesture { 261 class DoubleTapGesture : Gesture {
306 GestureState processEvent(EventTarget target, Event event); 262 GestureState processEvent(EventTarget target, Event event);
307 // double-tap-start: sent when the primary pointer goes down the first time 263 // double-tap-start: sent when the primary pointer goes down the first time
308 // double-tap-cancel: sent when cancel(), reset(), or finger goes out of bound ing box, or it times out 264 // double-tap-cancel: sent when cancel()ed or finger goes out of bounding box, or it times out
309 // double-tap: sent when the primary pointer is released the second time 265 // double-tap: sent when the primary pointer is released the second time withi n the timeout
310 } 266 }
311 267
312 268
313 abstract class ScrollGesture : Gesture { 269 abstract class ScrollGesture : Gesture {
314 GestureState processEvent(EventTarget target, Event event); 270 GestureState processEvent(EventTarget target, Event event);
315 // this fires the following events (inertia is a boolean, delta is a float): 271 // this fires the following events (inertia is a boolean, delta is a float):
316 // scroll-start, with field inertia=false, delta=0; precommit=true 272 // scroll-start, with field inertia=false, delta=0; prechoose=true
317 // scroll, with fields inertia (is this a simulated scroll from inertia or a real scroll?), delta (number of pixels to scroll); precommit=true 273 // scroll, with fields inertia (is this a simulated scroll from inertia or a real scroll?), delta (number of pixels to scroll); prechoose=true
318 // scroll-end, with field inertia (same), delta=0; precommit=true 274 // scroll-end, with field inertia (same), delta=0; prechoose=true
319 // scroll-start is fired right away 275 // scroll-start is fired right away
320 // scroll is sent whenever the primary pointer moves while down 276 // scroll is sent whenever the primary pointer moves while down
321 // scroll is also sent after the pointer goes back up, based on inertia 277 // scroll is also sent after the pointer goes back up, based on inertia
322 // scroll-end is sent after the pointer goes back up once the scroll reaches d elta=0 278 // scroll-end is sent after the pointer goes back up once the scroll reaches d elta=0
323 // scroll-end is also sent when the gesture is canceled or reset 279 // scroll-end is also sent when the gesture is canceled or reset
324 // processEvent() returns: 280 // processEvent() returns:
325 // - valid=true pretty much always so long as there's a primary touch (e.g. n ot for a right-click) 281 // - cancel=false pretty much always so long as there's a primary touch (e.g. not for a right-click)
326 // - forceCommit=true when you travel a certain distance 282 // - chose=true when you travel a certain distance
327 // - finished=true when the primary pointer goes up 283 // - finished=true when the primary pointer goes up
328 } 284 }
329 285
330 class HorizontalScrollGesture : ScrollGesture { } 286 class HorizontalScrollGesture : ScrollGesture { }
331 // a ScrollGesture giving x-axis scrolling 287 // a ScrollGesture giving x-axis scrolling
332 288
333 class VerticalScrollGesture : ScrollGesture { } 289 class VerticalScrollGesture : ScrollGesture { }
334 // a ScrollGesture giving y-axis scrolling 290 // a ScrollGesture giving y-axis scrolling
335 291
336 292
337 class PanGesture : Gesture { 293 class PanGesture : Gesture {
338 // similar to ScrollGesture, but with two axes 294 // similar to ScrollGesture, but with two axes
339 // pan-start, pan, pan-end 295 // pan-start, pan, pan-end
340 // events have inertia (boolean), dx (float), dy (float) 296 // events have inertia (boolean), dx (float), dy (float)
341 } 297 }
342 298
343 299
344 abstract class ZoomGesture : Gesture { 300 abstract class ZoomGesture : Gesture {
345 GestureState processEvent(EventTarget target, Event event); 301 GestureState processEvent(EventTarget target, Event event);
346 // zoom-start: sent when we could start zooming (e.g. for pinch-zoom, when two fingers hit the glass) (precommit) 302 // zoom-start: sent when we could start zooming (e.g. for pinch-zoom, when two fingers hit the glass) (prechoose)
347 // zoom-end: sent when cancel()ed after zoom-start, or when the fingers are li fted (precommit) 303 // zoom-end: sent when cancel()ed after zoom-start, or when the fingers are li fted (prechoose)
348 // zoom, with a 'scale' attribute, whose value is a multiple of the scale fact or at zoom-start 304 // zoom, with a 'scale' attribute, whose value is a multiple of the scale fact or at zoom-start
349 // e.g. if the user zooms to 2x, you'd get a bunch of 'zoom' events like scale =1.0, scale=1.17, ... scale=1.91, scale=2.0 305 // e.g. if the user zooms to 2x, you'd get a bunch of 'zoom' events like scale =1.0, scale=1.17, ... scale=1.91, scale=2.0
350 } 306 }
351 307
352 class PinchZoomGesture : ZoomGesture { 308 class PinchZoomGesture : ZoomGesture {
353 // a ZoomGesture for two-finger-pinch gesture 309 // a ZoomGesture for two-finger-pinch gesture
354 // zoom is precommit 310 // zoom is prechoose
355 } 311 }
356 312
357 class DoubleTapZoomGesture : ZoomGesture { 313 class DoubleTapZoomGesture : ZoomGesture {
358 // a ZoomGesture for the double-tap-slide gesture 314 // a ZoomGesture for the double-tap-slide gesture
359 // when the slide starts, forceCommit 315 // when the slide starts, forceChoose
360 } 316 }
361 317
362 318
363 class PanAndZoomGesture : Gesture { 319 class PanAndZoomGesture : Gesture {
364 GestureState processEvent(EventTarget target, Event event); 320 GestureState processEvent(EventTarget target, Event event);
365 // manipulate-start (precommit) 321 // manipulate-start (prechoose)
366 // manipulate: (precommit) 322 // manipulate: (prechoose)
367 // panX, panY: pixels 323 // panX, panY: pixels
368 // scaleX, scaleY: a multiplier of the scale at manipulate-start 324 // scaleX, scaleY: a multiplier of the scale at manipulate-start
369 // rotation: turns 325 // rotation: turns
370 // manipulate-end (precommit) 326 // manipulate-end (prechoose)
371 } 327 }
372 328
373 329
374 abstract class FlingGesture : Gesture { 330 abstract class FlingGesture : Gesture {
375 GestureState processEvent(EventTarget target, Event event); 331 GestureState processEvent(EventTarget target, Event event);
376 // fling-start: when the gesture begins (precommit) 332 // fling-start: when the gesture begins (prechoose)
377 // fling-move: while the user is directly dragging the element (has delta attr ibute with the distance from fling-start) (precommit) 333 // fling-move: while the user is directly dragging the element (has delta attr ibute with the distance from fling-start) (prechoose)
378 // fling: the user has released the pointer and the decision is it was in fact flung 334 // fling: the user has released the pointer and the decision is it was in fact flung
379 // fling-cancel: cancel(), or the user has released the pointer and the decisi on is it was not flung (precommit) 335 // fling-cancel: cancel(), or the user has released the pointer and the decisi on is it was not flung (prechoose)
380 // fling-end: cancel(), reset(), or after fling or fling-cancel (precommit) 336 // fling-end: cancel(), or after fling or fling-cancel (prechoose)
381 } 337 }
382 338
383 class FlingLeftGesture : FlingGesture { } 339 class FlingLeftGesture : FlingGesture { }
384 class FlingRightGesture : FlingGesture { } 340 class FlingRightGesture : FlingGesture { }
385 class FlingUpGesture : FlingGesture { } 341 class FlingUpGesture : FlingGesture { }
386 class FlingDownGesture : FlingGesture { } 342 class FlingDownGesture : FlingGesture { }
387 343
388 ``` 344 ```
OLDNEW
« no previous file with comments | « sky/specs/events.md ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698