kiwi icon indicating copy to clipboard operation
kiwi copied to clipboard

Implementing a mouse click event

Open wasamasa opened this issue 9 years ago • 9 comments

Currently there are mouse down and mouse up handlers for handling click events. Neither are ideal for implementing buttons that can be clicked as the actual behavior (as can be seen in GTK with zenity --info --text "foobar" or Qt applications) is subtly different:

  • Button enters clicked state (at this point the mouse down handler fires)
  • By holding the mouse button, one can remain in this state
  • By moving the mouse button while still holding it, one can exit this state, release the mouse button and have no click trigger (at this point the mouse up handler fires)
  • However if the mouse button is released with the cursor still on the button, a mouse click handler is fired

I don't quite understand the event handling code yet, otherwise I'd have handed in a PR. For the time being, I'll use the mouse up handler.

wasamasa avatar May 23 '16 09:05 wasamasa

Well, I haven't implemented it yet because I was unsure on what would be the best way to detect a mouse click between MousePressed and MouseReleased events, but I think I'll simply calculate the time between the mouse press and release and if it is less than some amount, I'll fire the MouseClick. The amount I'll test, but I'm thinking around 300ms.

The whole event system needs some overhaul, to decouple it from SDL. I'm thinking in something either like render drivers and/or exposing the event functions (things like KW_PostMouseMotion(), KW_PostMouseButtonDown(), etc), but it needs more thinking.

mobius3 avatar May 23 '16 13:05 mobius3

[…]I think I'll simply calculate the time between the mouse press and release and if it is less than some amount, I'll fire the MouseClick.

Note that doing it this way wouldn't make the click handler behave as described in my original post. Perhaps I should record a screencast once I find some tool that can visualize when the mouse button is held down...

wasamasa avatar May 23 '16 13:05 wasamasa

I see. In addition to the timeout, we can check if the release happened in the same widget where it started, and then fire the click.

mobius3 avatar May 23 '16 13:05 mobius3

It's more like checking whether a mouse-down and mouse-up event happened on the same button, without any timeout going on.

wasamasa avatar May 23 '16 14:05 wasamasa

I don't know if that behaviour is desirable because the drag event is fired by taking movement in consideration while the mouse is down. What I usually consider a click event is mouse down and up without movement.

mobius3 avatar May 23 '16 15:05 mobius3

Indeed, the code for that would likely interfere with dragging. Then, that would explain why you rarely if ever find applications that allow both clicking and dragging to happen with the same widget and typically introduce an extra mode for switching between both, like by clicking to make the widget draggable or an explicit switch between both.

Ultimately, the decision on what behavior is desirable comes down on whether you want the widgets to feel as close to native ones as possible or whether you're aiming for simplicity.

wasamasa avatar May 23 '16 16:05 wasamasa

Is KW_IsCursorOverWidget/KW_IsCursorPressedOnWidget/KW_IsCursorReleasedOnWidget related to this discussion? I'm currently updating my bindings to the latest progress and not sure whether I should include these, too...

wasamasa avatar Jul 01 '16 13:07 wasamasa

Marginally related, I'd say. I implemented them because I realised there was no way of querying cursor state in widgets. It was required to listen to the over/press/release events and keep an internal boolean just to know the cursor state in the render phase. This way one can simply query the cursor and render differently based on that.

It can be used to implement click querying, but I haven't actually advanced in this discussion because I am still unsure on the correct behaviour and how to implement it.

mobius3 avatar Jul 06 '16 13:07 mobius3

I see. Somewhat related, I've dabbled around with nuklear in the meantime and it happens to pass the choice to the user by providing an NK_BUTTON_TRIGGER_ON_RELEASE identifier one must define to change to clicks being triggered on mouse button release.

wasamasa avatar Jul 06 '16 16:07 wasamasa