Skip to content
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

Add ability to change mouse cursor in groups and buttons #2399

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

SamuMazzi
Copy link
Contributor

Description:
As described in #2248 I've implemented a way to change mouse cursor when hovering widgets. As suggested by @v-ein I've added it as a paramter to add_group, but also (for convenience IMO), I've added it to add_button.

In my Ubuntu 24 I wasn't able to render all the cursors, but I guess it's something related to the backend (actually you can set io.MouseDrawCursor to True to see all of them, but doing so degraded my performance a lot)

Closes #2248

This parameter has been added only to groups and buttons
@axeldavy
Copy link

axeldavy commented Oct 9, 2024

Out of curiosity, why not instead have the user bind hover handlers to its buttons to set the cursor it wants ?

@SamuMazzi
Copy link
Contributor Author

Take a look at #2248, there v-ein suggested this:

[Such a function] would need to be bound to a widget, so that when the widget is hovered, mouse cursor changes. Not much work, but we can't add it to every widget, that would be a mess. It could be, for example, an argument to dpg.group, since a group is a pretty much universal container - we can wrap virtually anything with a group.

I think this is pretty much self explanatory... it was needed an almost universal solution and this was the most efficient one

@v-ein
Copy link
Contributor

v-ein commented Oct 9, 2024

why not instead have the user bind hover handlers to its buttons to set the cursor it wants ?

This might work too, but hover handlers don't have (yet) the ability to capture the "mouseout" event (going to add this in future, probably soon). That is, the user would need a way to revert the cursor back to default.

@axeldavy
Copy link

axeldavy commented Oct 9, 2024

The issue with the un-hovered/mouse-out event is that the item might be not rendered(tree node closed or any reason) and thus the event might not trigger.

I was thinking more in the line of the mouse being reset after a ~0.1s delay of no new cursor command is issued.

@v-ein
Copy link
Contributor

v-ein commented Oct 9, 2024

the item might be not rendered(tree node closed or any reason) and thus the event might not trigger

Good point!

mouse being reset after a ~0.1s delay of no new cursor command is issued

To me, looks like a hack with its own potential issues...

@axeldavy
Copy link

axeldavy commented Oct 9, 2024

To me, looks like a hack with its own potential issues...

Agree... I also thought of another way which is to add the ability for handlers to look at the state of another item. Then you can have a top level item watch for the end of the hover but I'm not a fan.

@axeldavy
Copy link

axeldavy commented Oct 12, 2024

Agree... I also thought of another way which is to add the ability for handlers to look at the state of another item. Then you can have a top level item watch for the end of the hover but I'm not a fan.

In the end, I'm currently experimenting in DCG the two ideas: having GotHoverHandler and LostHoverHandler handlers in order to trigger something when we gain or lose hover, as well as having handlers checking other item states.

I think the main issue of both in the context of mouse cursor is that there is a delay (we don't know if the user is taking his time to treat the callback queue or not), and if we move from a button to another that want each to set the mouse cursor, we might 'undo' the cursor of the first button after setting the cursor of the second button.

Thus I'm more and more convinced what is proposed in this PR is a good solution.

In DCG, I think I'll implement it as a custom handler, that would be equivalent to that PR, but is more customizable (I want to be able to change cursor only if alt is pressed).

@v-ein
Copy link
Contributor

v-ein commented Oct 13, 2024

having GotHoverHandler and LostHoverHandler handlers

The same entry/exit logic can be applied to some other handlers, too, in particular the "focus" handler and the "item visible" handler. In my version of DPG, I simply added an event_type argument to already existing item handlers, like this:

event_type (int, optional): What kind of events to track: just got focus (mvEventType_Enter), currently having focus (mvEventType_On), lost focus (mvEventType_Leave). Can be a combination of these flags. Defaults to mvEventType_On.

event_type (int, optional): What kind of events to track: mouse-in (mvEventType_Enter), mouse-over (mvEventType_On), mouse-out (mvEventType_Leave). Can be a combination of these flags. Defaults to mouse-over.

Will this be usefult in DCG?

This, however, does not solve the problem of the "exit" event being missed when the widget's container gets hidden and therefore does not even try to render the widget. It is highly noticeable with the "item visible" handler, on which mvEventType_Leave will only work for some containers but is unlikely to work for regular widgets (therefore I have doubts as to whether to push this part to a PR). But, well, it's a whole separate problem, and can even be addressed via documentation - by saying it's just the way ImGui works 😂.

if we move from a button to another that want each to set the mouse cursor, we might 'undo' the cursor of the first button after setting the cursor of the second button.

Exactly. If the button being hovered gets rendered first, and the other button (with the LostHoverHandler event) is rendered after it, then the handlers will go as (1) GotHoverHandler that sets the desired cursor on hovered button, and (2) LostHoverHandler that resets the cursor back to default. I've seen it for real with activation/deactivation handlers, and had a hard time trying to make it all work the way I need it.

@axeldavy
Copy link

The same entry/exit logic can be applied to some other handlers

Yes indeed, and I added this logic to all handlers see here

This, however, does not solve the problem of the "exit" event being missed when the widget's container gets hidden and therefore does not even try to render the widget.

In DCG this is solved by propagating the non visible state to children this first time we turn invisible, and running handlers the first time you turn invisible. The only case not catched yet is if you move a visible item to a parent that is already invisible. In addition one can use handlers on items that are rendered (=visible) to take action when target items are not rendered see here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ability to change the mouse cursor
3 participants