FIGURE 9-2 The

FIGURE 9-2 The PointerEvents example output for gesture events (screen shot cropped a bit to emphasize detail). Again, gesture events are fired in response to a series of pointer events, offering higher-level interpretations of the lower-level pointer events. It’s the process of interpretation that differentiates the tap/hold events from the start/change/end events, how and when the MSInertiaStart event kicks off, and what the gesture recognizer does when the MSGesture object is given multiple points. Starting with a single pointer gesture, the first aspect of differentiation is a pointer movement threshold. When the gesture recognizer sees an MSPointerDown event, it starts to watch the MSPointerMove events to see whether they stay inside that threshold, which is the effective boundary for tap and hold events. This accounts for and effectively ignores small amounts of jiggle in a mouse or a touch point as illustrated (or shall I say, exaggerated!) below, where a pointer down, a little movement, and a pointer up generates an MSGestureTap: What then differentiates MSGestureTap and MSGestureHold is a time threshold: • MSGestureTap occurs when MSPointerDown is followed by MSPointerUp within the time threshold. 380

• MSGestureHold occurs when MSPointerDown is followed by MSPointerUp outside the time threshold. MSGestureHold then fires once when the time threshold is passed with eventArgs.detail set to 1 (MSGESTURE_FLAG_BEGIN). Provided that the pointer is still within the movement threshold, MSGestureHold fires then again when MSPointerUp occurs, with eventArgs.detail set to 2 (MSGESTURE_FLAG_END). You can see this detail included in the first two events of Figure 9-2 above. The gesture flags in eventArgs.detail value is accompanied by many other positional and movement properties in the eventArgs object as shown in the following table: Properties screenX, screenY clientX, clientY offsetX, offsetY translationX, translationY velocityX, velocityY scale expansion velocityExpansion rotation velocityAngular detail Description The x- and y-coordinates of the gesture center point relative to the screen. The x- and y-coordinates of the gesture center point relative to the client area of the app. The x- and y-coordinates of the gesture center point relative to the element. Translation along the x- and y-axes. Velocity of movement along x- and y-axes. Scale factor for zoom (percentage change in the scale). Diameter of the manipulation area (absolute change in size, in pixels). Velocity of expanding manipulation area. Rotation angle in radians. Angular velocity in radians. Contains the gesture flags that describe the gesture state of the event; these flags are defined as values in eventArgs itself: eventArgs.MSGESTURE_FLAG_NONE (0): Indicates ongoing gesture such as MSGestureChange where there is change in the coordinates. eventArgs.MSGESTURE_FLAG_BEGIN (1): The beginning of the gesture sequence. If the interaction contains single event such as MSGestureTap, both MSGESTURE_FLAG_BEGIN and MSGESTURE_FLAG_END flags will be set (detail will be 3). eventArgs.MSGESTURE_FLAG_END (2): The end of the gesture sequence. Again, if the interaction contains single event such as MSGestureTap, both MSGESTURE_FLAG_BEGIN and MSGESTURE_FLAG_END flags will be set (detail will be 3). eventArgs.MSGESTURE_FLAG_CANCEL (4): The gesture was cancelled. Always comes paired with MSGESTURE_FLAG_END, (detail will be 6). hwTimestamp eventArgs.MSGESTURE_FLAG_INERTIA (8): The gesture is in an inertia state. The MSGestureChange event can be distinguished from direct interaction and timer driven inertia through this flag. The timestamp of the pointer assigned by the system when the input was received from the hardware. Many of these properties become much more interesting when a pointer moves outside the movement threshold, after which time you’ll no longer see the tap or hold events. Instead, as soon as the pointer leaves the threshold area, MSGestureStart is fired, followed by zero or more MSGestureChange events (typically many more!), and completed with a single MSGestureEnd event: 381