lambdanative
lambdanative copied to clipboard
Gesture Support?
I'm happily compiling some code and looking at the modules, and I don't see any support for gesture recognition. Has work been done here?
My use case is simple, I'd like to check swipes up, left, down and right on ios.
We don't have a specific widget for it, however, glgui-box-dragable has been made for this purpose. It uses an invisible box, in which you can drag and which fires a callback. The internal variables offsetx
and offsety
can be used to identify the directions. Here an example of how such a callback is used in an app:
(define (wave-canvas-callback g w t x y)
(let ((ox (glgui-widget-get g w 'offsetx))
(rooms (store-ref "main" "myRooms"))
(waveform-room-idx (store-ref "main" "waveform-room-idx")))
(if (and ox (> ox 20)) ;; go down as dragging is L->R
(store-set! "main" "waveform-room-idx" (if (<= waveform-room-idx 0) (- (length rooms) 1) (- waveform-room-idx 1)))
)
(if (and ox (< ox -20));; go up, as dragging R->L
(store-set! "main" "waveform-room-idx" (if (>= waveform-room-idx (- (length rooms) 1)) 0 (+ waveform-room-idx 1)))
)
(if (and ox (> (abs ox) 20))
(begin
(for-each (lambda (l) (gltrace:clear l)) (list ecg-trace pleth-trace co2-trace art-trace))
(let ((or-name (list-ref rooms (store-ref "main" "waveform-room-idx"))))
(for-each (lambda (l) (store-clear! or-name l)) '("ECG1" "PLETH" "CO2" "INVP1"))
)
(set! rupi:last-wave-request 0.)(set! rupi:last-wave-update 0.) ;; Force immediate redraw
(glgui-widget-set! g w 'offsetx #f); //Otherwise consecutive taps go there too
)
)
)
)
Got it, thank you.
@vessenes if you think gesture detection should have its own widget we could consider expanding this one for it? Or if you come up with something generalizable yourself, feel free to submit a pull request. Thanks Matthias
I'm mostly interested in using lambdanative as an ios development platform with my daughter who can code racket. There are a few different paths to go down, including react native. But, the scheme angle drew me in.
I'll see what she's interested in doing with it, but one of the first use cases would be turning some gestures into effects on the screen, and I was curious what support was like.
React Native has two sets of libraries that relate; gesture responder and panresponder. If someone gets ambitious, those are probably worth reviewing before deciding on a direction for implementation.
Rather than creating a specific widget to parse events and interpret them as gestures, I think we should use existing gesture listeners like GestureDetector on Android and UIGestureRecognizer on iOS, and use those to create new LambdaNative events (EVENT_SWIPE
and EVENT_SCROLL
, perhaps) which will be handled by the event-loop. Then individual widgets can choose to handle these events however they wish.
Using native gesture detectors comes with a tradeoff - you might loose the ability to get high frequency short tap events. On my android version taps started getting lost/unreliable beyond 3 taps/s
Sent from my Android device with K-9 Mail. Please excuse my brevity.
@lighhw68 This is probably a different issue, since GestureDetector only interprets the MotionEvents received by the View's onTouchEvent method, which is what we currently use to send EVENT_BUTTONXDOWN/UP
events to the Scheme side. It's working well in apps like RRate for instance (of our LNhealth repository), which is able to react to many more taps in quick succession. If you mean capturing double-tap events, we probably don't need to use GestureDetector; the keypad
module already supports this for the on-screen shift key to trigger caps lock, and other widgets that need this functionality can refer to that implementation.
I looked into this a bit and it turns out iOS's UISwipeGestureRecognizer
will interfere with our existing touchesEnded:withEvent:
in that if a swipe event is registered it doesn't seem to call the latter function anymore. Also, unlike Android, UISwipeGestureRecognizer
won't provide any information on swipe velocity; UIPanGestureRecognizer
will, but involves the motion of a view over a superview, and we only have one main view. As far as use-case goes, if the existing draggable widgets suffice for this purpose (we have the draggable box, the draggable container, and the framed container) then I won't make any further changes for now.