feathersui-openfl icon indicating copy to clipboard operation
feathersui-openfl copied to clipboard

PopUpListView: select item on list item mouse up when mouse down originated on button or another list item

Open player-03 opened this issue 2 years ago • 2 comments

The PopUpListView class (correctly) opens on a MOUSE_DOWN event. However, if the user drags down to the list item they want and releases the mouse button, nothing happens. Or if the user thinks better of their choice and switches items mid-click, Feathers ignores that too. The list items light up in turn

This is because a ListView is made up of individual buttons, each of which use TriggerEvents, which only occur after a MOUSE_DOWN and MOUSE_UP event on the same button.


The solution? I'm not quite sure. Switching to MOUSE_UP certainly fixes this case, but opens up other problems. You could click and drag between lists and still trigger an event, when (if anything) you're probably trying to move an item from place to place.

At least in the list-to-list case, the CLICK began on a control of some kind. A worse case would be to click on nothing, drag over a control, and release to select an option. Perhaps it's enough to keep a static (?) variable tracking whether the MOUSE_DOWN event affected a control, and ignore the MOUSE_UP event if it didn't. No, that's the wrong way to use a static variable. At the very least you'd want to tie it to a Stage instance...


I think Ubuntu's excellent implementation offers some hints. In Ubuntu, you can click and drag to navigate an entire menu bar. If you click on "File," you can drag down to "Save" or sideways to "Edit" and then down to "Copy."

However, you can only drag within related controls. If there are two menu bars onscreen and you click one, you can only drag within that menu. (Even two menu bars within a single app are considered distinct.)


I think the ideal solution requires rethinking how events work. Instead of events beginning at the bottom of the display hierarchy and bubbling up, the top-level control would need to catch them (using mouseChildren = false) and pass them along to its children. That way, OpenFL will dispatch a CLICK event based on whether the PopUpListView received the original MOUSE_DOWN event, even if the mouse moved between list items. You could even make a menu bar by combining a bunch of PopUpListViews into a single higher-level control, and OpenFL would dispatch CLICK as long as the mouse remained somewhere in the bar.

The big problem I see with this solution is determining which child (or grandchild!) to pass the event to. hitTestPoint() might not be enough.

player-03 avatar Mar 05 '22 02:03 player-03

Update: the mouseChildren solution fails due to how OpenFL tracks CLICK events, and working around it seems to require private access on openfl.display.Stage.

Plus side, not only is it doable, it generalizes to any OpenFL app, so I can make a separate library for it.


As far as Feathers is concerned, MOUSE_UP may be the best solution after all. Maybe add an option to PointerTrigger?

Also, make sure to highlight buttons as you drag over them.

player-03 avatar Mar 07 '22 07:03 player-03

Since it has always worked this way in Feathers UI, going all the way back into the Starling version, I'm going to leave it as-is for for the 1.0 stable release. Post 1.0, I'll spend some time considering possible solutions for this one.

joshtynjala avatar Mar 07 '22 16:03 joshtynjala