-
Notifications
You must be signed in to change notification settings - Fork 26
No pointer_drag events emitted with egt 1.9-rc1 #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi Sascha, The way 'pointer_drag' and 'pointer_drag_stop' events are handled has changed. 'pointer_drag_start' events, like previously, go through the widget hierarchy. However, now one of them must accept this 'pointer_drag_start' event in order to receive the associated 'pointer_drag' and 'pointer_drag_stop' events. Also, only one widget can accept the 'pointer_drag_start' event. Once accepted, further widgets in the hierarchy may not receive the 'pointer_drag_start' event at all and should not accept it anyway. Later, when 'pointer_drag' and 'pointer_drag_stop' are emitted, they are sent directly and only to the widget that has accepted the 'pointer_drag_start' event, if any. Indeed, if no widget at all has accepted the 'pointer_drag_start' event, then no widget receives the associated 'pointer_drag' and 'pointer_drag_stop' events. Then, in order to accept 'pointer_drag_start' events, widgets now have to either:
Widgets defined in libegt that are supposed to handle drag & drop events, like egt::Slider for instance, override the internal_drag() method. Therefore, there is nothing more to do and they should work as before. Indeed, widgets inheriting from egt::Frame may not handle 'pointer_drag*' events, but still, one of their descendant may be the target of the 'pointer_drag_start' event. So, the event walk through the hierarchy until one widget accepts it. Finally, the track_drag() method has been introduced aside the accept_drag() method to tune a little bit how 'pointer_drag*' events are emitted:
If a widget accepts 'pointer_drag_start' events and track_drag() is enabled (for egt::Slider as an example), it works as before in libegt 1.8: even if the mouse pointer moves out of the widget boundaries, this widget still receives 'pointer_drag' and 'pointer_drag_stop' events On the other hand, if a widget accepts 'pointer_drag_start' events but track_drag() is disabled (egt::ScrolledView for instance), if the mouse pointer moves out the widget boundaries, the 'pointer_drag' event is reshaped into a 'pointer_drag_stop' event and the widget won't receive the further 'pointer_drag' or 'pointer_drag_stop' events associated with the initial 'pointer_drag_start' event. BR, Cyrille |
Hi Cyrille, thanks for the explanation! I tried the user_drag() on libegt defined widgets as well as the internal_drag() const override{} on my own widgets and both works as expected. If I define a widget class with the internal_drag() set to true, I assume there is no way to switch the acceptance of the drag pointers for a dedicated object of that class off via something like user_drag(false)? Regards |
If you override internal_drag(), then you can make it return whatever you want, ie some else but an hard-coded 'true' value. Hence, for instance, you can make it return user_drag() and set the associated 'user_drag' flag in the constructor if you want the drag & drop feature to be enabled by default for this custom class. BR, Cyrille |
Thanks! That was all very helpful and my code works again as expected. One last question: What made you introduce the change about the need to accept the pointer_drag_starts to further receive pointer_drags? In older EGT versions a widget would just not define an action for a pointer_drag in the handler and would not be further affected either? Issue can be closed otherwise. Regards |
When we reworked the egt-launcher application, we made use of the egt::ScrolledView widget to create grids of icons that can be swiped, like the launcher of a smartphone. However, during our tests, we noticed many issues with the egt::ScrolledView. For instance, if we put an egt::Slider as a child of an egt::ScrolledView, when we try to move the slider handle, both the slider and the scrolled view were handling the 'pointer_drag*' events. Hence both the slider handle and the slider itself, with all other children of the scrolled view, were translated. To solve this issue, we had to find a way so only the expected widget handles 'pointer_drag*' events. Therefore, when 'pointer_drag_start' events walk through the widgets hierarchy, we want to find the widget that is the uppermost (highest z coordinate) among widgets that handle 'pointer_drag*' events and having a box containing the mouse pointer. Once this widget found, we assume it consumes the 'pointer_drag_start' event so the event should not walk further the hierarchy. This is why, we now need a mean to know whether a widget handle() method has consumed the 'pointer_drag_start' event. One solution would have been to patch all overridden handle methods that deal with any 'pointer_drag*' event so those methods would have called Event::stop() on such events. Also, we would have to make sure that all handle() overrides test Event::quit() at the very beginning then return immediately if needed. We thought this solution would have required too many changes in the source code, including customers applications. Obviously, for this solution to work, we also assume that every override of handle() method calls Widget::start_drag() at some point, directly or indirectly by calling the handle() method of the parent class, so the 'pointer_drag_start' event is consumed and stopped properly. Also, Widget::start_drag() calls detail::dragged(this) so later Input::dispatch() forwards the further 'pointer_drag*' events associated to the 'pointer_drag_start' event only to the widget that has accepted this event. BR, Cyrille |
Thanks for the explanation, that is very helpful. |
Hi,
I just updated to the most recent commit 826751c and found that there is an issue with pointer_drag events. Just before the update I tested the branch 27-event-handler-sees-no-further-pointer_hold-after-pointer_drag_start where everything worked fine (as described in the last comment of issue #27 ) and pointer_drag events were emitted.
With the master branch and the most recent commit there is a pointer_drag_start emitted but no further pointer_drags anymore. the raw_pointer_move still works as well as the pointer_holds.
The test program from #27 delivers the following results if I "drag" on the widgets:
As you can see the pointer_drag_start is emitted but then nothing anymore but the pointer_holds.
Regards
Sascha
The text was updated successfully, but these errors were encountered: