xtra MultiTouch -- v0.3 (c) 2019 Valentin Schmidt new object me, *callbackTarget listen_start object me, integer touchEvents, *propListGestureConfig listen_stop object me This scripting xtra for Windows allows to receive both raw touch events (WM_POINTER* messages) and gesture events (WM_GESTURE messages). It requires Windows 8 or newer, Windows 7 is not supported. For maximum performance such Windows messages are forwarded to Lingo *directly*, i.e. in an "unsafe" way. Therefor, if you want to trigger anything that messes with Director's DOM and timeline, such messages should first be "detached" from the original call stack, e.g. by using a 1 ms timeout. The xtra comes with a parent script called "detacher" that takes care of this (/lib/detacher/index.ls). For details about WM_POINTER* and WM_GESTURE see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/inputmsg/wm-pointerdown https://docs.microsoft.com/en-us/windows/win32/wintouch/wm-gesture ---------------------------------------- -- new object me, *callbackTarget ---------------------------------------- Optional argument 'callbackTarget' can be a script or script instances that receives the event messages. If not specified, the event handlers are expected in _movie scope, i.e. in a movie script. ---------------------------------------- -- listen_start object me, integer touchEvents, *propListGestureConfig ---------------------------------------- Starts listening to raw touch or gesture event messages (or both). If 'touchEvents' is specified as TRUE, raw touch events are received, which means that the 4 event handlers on touchStart (touchEventID, touchPoint) on touchEnd (touchEventID, touchPoint) on touchMove (touchEventID, touchPoint) on touchCancel (touchEventID, touchPoint) should exist. Run demo "demo_touch_print.lsw" to see all received touch events in a console window. If optional parameter 'propListGestureConfig' is omitted, no gesture events are received, otherwise the passed property list configures which gesture events you want to receive, and how gesture recognition is configured. Depending on this config, the following event handlers are called: on gestureZoom (flags, args, gesturePoint) on gesturePan (flags, args, gesturePoint) on gestureRotate (flags, angle, gesturePoint) on gestureTwoFingerTap (flags, args, gesturePoint) on gesturePressAndTap (flags, args, gesturePoint) Run demo "demo_wmgesture_print.lsw" to see all received gesture events in a console window. For details on 'propListGestureConfig', see https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setgestureconfig https://docs.microsoft.com/de-de/windows/win32/api/winuser/ns-winuser-gestureconfig Here are some examples: ---------------------------------------- config = [#gestureAll: [$.multitouch.GC_ALLGESTURES, 0]] => All 5 gesture types are received, and all with default configuration. This means that the system has to distinguish between 2-finger-gestures ZOOM and ROTATE, which causes some delay before those gestures are recognized. ---------------------------------------- config = [:] dwWant = $.multitouch.GC_PAN_WITH_SINGLE_FINGER_VERTICALLY + $.multitouch.GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY dwBlock = $.multitouch.GC_PAN_WITH_GUTTER + $.multitouch.GC_PAN_WITH_INERTIA config[#gesturePan] = [dwWant, dwBlock] config[#gestureZoom] = [1, 0] -- enable zoom config[#gestureRotate] = [0, 1] -- disable rotate (disabled by default) config[#gestureTwoFingerTap] = [0, 1] -- disable twoFingerTap config[#gesturePressAndTap] = [0, 1] -- disable pressAndTap => Only ZOOM and PAN are recognized. Pan events are based on a single finger and use both horizontal and vertical direction. Pan is neither based on gutter nor on inertia. ---------------------------------------- config = [:] -- configure pan gesture dwWant = $.multitouch.GC_PAN_WITH_SINGLE_FINGER_VERTICALLY +\ $.multitouch.GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY +\ $.multitouch.GC_PAN_WITH_INERTIA dwBlock = $.multitouch.GC_PAN_WITH_GUTTER config[#gesturePan] = [dwWant, dwBlock] -- disable all other gestures config[#gestureZoom] = [0, 1] config[#gestureRotate] = [0, 1] config[#gestureTwoFingerTap] = [0, 1] config[#gesturePressAndTap] = [0, 1] => Only PAN gestures are recognized, no gutter is used, but inertia is activated. Check out demo "demo_wmgesture_inertia" that uses this configuration. Lingo is used to keep the draggable square inside the window (i.e. bounce it at the borders), but inertia (and related easing curve) is directly created by the system. ---------------------------------------- Note: above examples use some numeric constants (GC_ALLGESTURES etc.) that are defined in script /lib/multitouch/index.ls that comes with the xtra. ---------------------------------------- -- listen_stop object me ---------------------------------------- Stops listening to raw touch and gesture event messages. General Notes ============= WM_GESTURE event messages are based on some older (Windows 7) gesture recognition engine that only supports a limited number of gestures: - ZOOM (or pinch) - PAN (either single finger or two-finger) - ROTATE (one finger stays at fixed position, the other roatest around) - TWO-FINGER-TAP - PRESS-AND-TAP (one finger stays at touch point, then the other is tapped) If you want to support more/other gestures (like SWIPE, LONG-TAP, DOUPLE-TAP etc.), don't activate/use those gesture events, but instead build you own gesture recognizer based on raw touch events. The xtra comes with an example for such a custom gesture recognizer (/resources/gesture_recognizer.ls). Another shortcoming of WM_GESTURE and the system's gesture recognition engine is that it only supports a single gesture at the same time. Therefor you can't use its PAN gesture to implement e.g. a multi-slider that supports dragging sliders simultaneously with multiple fingers. Demo "demo_touch_multislider" shows how to build such a (5 fingers) multi-slider based on raw touch events instead.