FLTK logo

Re: [fltk.coredev] Gesture progress for 1.4?

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.coredev  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: Gesture progress for 1.4? Albrecht Schlosser Oct 09, 2021  
 
On 10/9/21 7:22 AM Rob McDonald wrote:
Thanks to Albrecht's direction, I parroted this commit by Matthias Melcher to add support for a couple other MacOS gestures, two-finger rotate and two-finger scroll.  I can add three finger swype, but my application does not need it, so I'll hold off to see how this is received first.

Changes pushed up here:


Thanks, I took a quick look ... looks good, thank you very much!

I still need to test it though.

This was done in a monkey-see monkey-do way -- I do not claim to have any understanding of Apple's API's.  I have never used Objective-C and will continue to make that claim after doing this work.  I followed Matthias' example and read this bit of Apple documentation as well as a few other bits of their terrible API docs...

Yes, as a macOS / Objective-C beginner I find these docs terrible as well. If you know the basics it might be better to handle though.

In the end, it works for my application and is pretty cool.  It would be great if other OS support could be similarly added.

I took a look into the Windows documentation you posted in another message. I couldn't resist and tried what I could get. Took me (way too many) hours but I'm now at a point where I get the gesture messages and I can interpret the data partly - not yet finished though.

The tricky part will be to integrate it with the FLTK event system (for now I'm only logging the messages) and to create the *correct* FLTK event data to have identical events and associated data on all platforms. Example:

WM_MOUSEHWHEEL message (526), delta = -5
WM_MOUSEHWHEEL message (526), delta = -2
Gesture GID_BEGIN        (1): flags=00, args=0, pos=(1398, 280)
Gesture GID_ROTATE       (5): flags=01, args=39413, pos=(1334, 525)
    rotation angle =    1.27 (  73.01 degrees)
Gesture GID_ROTATE       (5): flags=00, args=32186, pos=(1334, 525)
    rotation angle =   -0.11 (  -6.39 degrees)
Gesture GID_ROTATE       (5): flags=00, args=32164, pos=(1334, 525)
    rotation angle =   -0.12 (  -6.63 degrees)
...
Gesture GID_ROTATE       (5): flags=00, args=34298, pos=(1327, 526)
    rotation angle =    0.29 (  16.81 degrees)
Gesture GID_ROTATE       (5): flags=04, args=34298, pos=(1327, 526)
    rotation angle =    0.29 (  16.81 degrees)
Gesture GID_END          (2): flags=00, args=0, pos=(1328, 406)
Gesture GID_BEGIN        (1): flags=00, args=0, pos=(1196, 321)
Gesture GID_PAN          (4): flags=01, args=143, pos=(1190, 394)
Gesture GID_PAN          (4): flags=00, args=142, pos=(1286, 394)
Gesture GID_PAN          (4): flags=00, args=142, pos=(1300, 394)
...
Gesture GID_PAN          (4): flags=00, args=142, pos=(1410, 394)
Gesture GID_PAN          (4): flags=04, args=142, pos=(1410, 394)
Gesture GID_END          (2): flags=00, args=0, pos=(1410, 399)
...
Gesture GID_BEGIN        (1): flags=00, args=0, pos=(1447, 427)
Gesture GID_ZOOM         (3): flags=01, args=81, pos=(1414, 437)
Gesture GID_ZOOM         (3): flags=00, args=174, pos=(1445, 439)
WM_MOUSEWHEEL message (522), delta = 120
Gesture GID_ZOOM         (3): flags=00, args=179, pos=(1443, 439)
Gesture GID_ZOOM         (3): flags=00, args=186, pos=(1439, 439)
Gesture GID_ZOOM         (3): flags=00, args=191, pos=(1437, 440)
Gesture GID_ZOOM         (3): flags=00, args=197, pos=(1434, 440)
Gesture GID_ZOOM         (3): flags=00, args=202, pos=(1431, 440)
Gesture GID_ZOOM         (3): flags=00, args=208, pos=(1428, 441)
WM_MOUSEWHEEL message (522), delta = 120
Gesture GID_ZOOM         (3): flags=00, args=212, pos=(1426, 441)
Gesture GID_ZOOM         (3): flags=00, args=218, pos=(1423, 442)
Gesture GID_ZOOM         (3): flags=00, args=222, pos=(1421, 442)
...
Gesture GID_ZOOM         (3): flags=04, args=269, pos=(1397, 452)
Gesture GID_END          (2): flags=00, args=0, pos=(1397, 452)
Gesture GID_BEGIN        (1): flags=00, args=0, pos=(1562, 437)
Gesture GID_ZOOM         (3): flags=01, args=321, pos=(1402, 471)
Gesture GID_ZOOM         (3): flags=00, args=273, pos=(1382, 481)
...

I thought I might get these events from my notebook's touchpad but this didn't work. However, the touch*screen* worked fine (see logs above).

Note that the two WM_MOUSEHWHEEL messages at the beginning of the log are really that. However, I don't know where exactly the other ewo interspersed WM_MOUSEHWHEEL messages came from. I think that's a Windows "feature", some gestures are sent as normal mousewheel events for backwards compatibility (more tests required).

The rotate gesture is pretty straightforward.  Apple returns the rotation angle in floating point degrees.  I followed Matthias' example and multiplied by 1000.0 and returned it the dy integer.

Of course the rotation angle must have the same units and orientation on all platforms etc..

How is the "rotation angle" on macOS defined? Is it relative (per event) or is it some kind of absolute angle? Clockwise or counter-clockwise? My observations on Windows seem to indicate that it's the absolute angle of the two fingers, 0° = "north", increasing counter-clockwise (more tests needed, I didn't find it in the docs - docs are AFAICT incomplete and confusing).

BTW: after reading the macOS docs I believe that the zoom value issued on macOS by FLTK's FL_ZOOM_GESTURE event is not "correct" (whatever "correct" means here). The docs say you need to add 1 to the "magnification" value (you can still multiply with 1000). But what exactly is that value?

Some questions:
(1) What zoom values do you see on your macOS system? Do they make sense?
(2) What hardware did you use?
(3) I have a macBook Air with touch-/trackpad (no external device). Does it work with this config?

I also added handling for two-finger scroll on the trackpad.  Apple actually fires the same event for this as for a mouse scroll wheel -- but with tiny magnitude dx,dy such that it seems like nothing is actually happening.  In my application (involving 3D manipulation), I wanted to have different behavior for the scroll wheel (zoom) as for two-finger scroll (pan).  So, I needed to differentiate between these different kinds of scrolls.

I eventually found NSEventSubtype which is equal to NSEventSubtypeMouseEvent when the event originates from a mouse rather than other hardware.  There seemed to be other similar things to check for slightly different API versions.  I don't know if we want to add a bunch of conditionals to know which variable to test.

With this change, FLTK will issue separate FL_MOUSEWHEEL and FL_SCROLL_GESTURE events depending on this value.  Existing applications should be OK with this because the dx,dy returned by two-finger scroll via FL_MOUSEWHEEL is probably getting ignored (unless you do some really angry scrolling in the y-direction only).

I think here we have an issue with backwards compatibility. If I read your statements correctly (but this may be not the case) then "splitting" in different event types may be an issue. IIRC I used my built-in (macBook Air) touchpad with two-finger scrolling as a replacement for scrolling with the mousewheel - because I don't use a mouse with my macBook. If this would be "converted" to FL_SCROLL_GESTURE then it could break existing apps that rely on FL_MOUSEWHEEL simulation. But, again, this needs testing...

I wasn't sure if the float s = Fl::screen_driver()->scale(0); scale value needs to be applied to the scroll gesture.  I'm not sure where it comes from and how I would get it to have different values for testing on my machine.

You can define the env variable FLTK_SCALING_FACTOR=1.5 or similar before starting your program. Then all your FLTK programs should start zoomed by 150% and you could use cmd/+/- on a Mac to change scaling (ctrl/+/- on other systems).

I also wasn't sure if and where to add to unit tests, test applications, documentation, etc.

Eventually we'll need that. A test program (test/gestures.cxx ?) would be helpful if we could demonstrate the zoom, pan, scroll, and rotate gestures in one cross-platform program.

Finally, as this adds some new event types, I am not sure how to add protections to existing applications that still need to be able to compile against older versions of FLTK that do not have these defined.

That's not an issue. Additional events are ignored by existing programs. But changing the semantics like changing a working event to another one (which would be ignored) is problematic (see my notes above).

The other thing we do really need is the fl_eventnames array which you did already update in your patch. Thanks.

PS: it's been a long day, I'll be offline shortly, don't expect any quick replies today (it's ~11pm (Sat.) here).

--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/b047eda8-5c05-5c1e-52b6-0d17b1be649d%40online.de.
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.