renpy / renpy

The Ren'Py Visual Novel Engine
http://www.renpy.org/
5.04k stars 705 forks source link

doubleclick, mousewheelup and mousewheeldown actions #4099

Open lauwurence opened 1 year ago

lauwurence commented 1 year ago

What about adding new actions? Double click as mentioned here https://github.com/renpy/renpy/issues/4020 And two new actions that can be applied to buttons, bars and run only when you hover the mouse over the button and scroll the mouse wheel up or down.

button:
   mousewheelup IncreaseScreenVariable('...')
   mousewheeldown DecreaseScreenVariable('...')

vbar:
   value FieldValue(..., scroll_step=5)

It may be useful for complex settings screens.

kigyo commented 1 year ago

Not sure if that would already be enough, but mouse wheel actions can already be implemented in a roundabout way using something like:

action IncreaseScreenVariable('...') keysym "mousedown_4"
alternate DecreaseScreenVariable('...') alternate_keysym "mousedown_5"

This way, scrolling up would invoke the left click action, scrolling down the right click action.

The drawback would be that you can't make scrolling do something new/different from clicking, but in the example you gave that probably wouldn't be too bad.

lauwurence commented 1 year ago

This won't work if there are like 2 or more different buttons, since keysym is exactly the same as key 'mousedown_4'.

Gouvernathor commented 1 year ago

Implementation-wise, there could be a way to do that by making the screen element create/take a ui.adjustment object like the viewport does, making it catch scrolling when the mouse is over it, and then send the information somewhere else. Because for the scrolling part, the only thing you would add is that behavior of only catching the scroll action when hovering the button and a bit of syntax sugar, right ?

For the double-click, I'm a bit doubtful because it requires to wait for the maximum duration inside a double-click, befure allowing a simple click to pass through. It could cause problems in games where time is somehow limited and you want to do the action as soon as the player clicks, this would induce a lag. The solution could be to make it opt-in on a button-by-button basis, but how would we integrate that distinction with the cdd framework using pygame ?

Booplicate commented 1 year ago

how would we integrate that distinction with the cdd framework using pygame

What if you waited for the second click only if a double click action was specified for the button? The wait time could be about 100-200 ms, it should be enough for the user to click again while not freezing the game flow. Although, would be nice if that was adjustable in accessibility and/or config.

Gouvernathor commented 1 year ago

Yeah, that's what I'm saying, making it opt-in for each button separately. But then how do we make the double-click available to the pygame events system for creator-defined displayables ? Do we leave them out, and leave creators to implement it themselves if they want it ?

bober-gith commented 1 year ago

double click implementation through the screen is possible in ren'py right now, but mb too heavy in processing since it involves having screens:

screen custom_keymap_listener():
    key "mouseup_1" action Show("detect_doubleclick")
screen detect_doubleclick():
    key 'mouseup_1' action /whatyouwanttodo
    timer 1.0 action Hide("detect_doubleclick")
lauwurence commented 1 year ago

@Org-gith That's cool but the thing is Show and Hide actions have a renpy.restart_interaction() function inside, which produces a small fps drop.

bober-gith commented 1 year ago

@via-my Definitely not optimal, just wanted to point that out in case it helps, I think it takes too much processing away for a simple double click too.

Booplicate commented 1 year ago

But then how do we make the double-click available to the pygame events system for creator-defined displayables ? Do we leave them out, and leave creators to implement it themselves if they want it ?

I prefer to handle events in custom classes myself, unless it's something complex and I need the keymap for it. Thus I think it's fine if the creators of CDD will have to create a system to handle double clicks themselves. From my experience, if I need a CDD I will probably need some custom event handler too (unless it's purely for displaying something). If I don't need any custom logic or I want to reuse what renpy has, I can just subclass one of renpy classes (which would work in this case too - just subclass Button).