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

Button hold delay + hold repeat rate #1095

Open
asztalosdani opened this issue Oct 19, 2023 · 3 comments
Open

Button hold delay + hold repeat rate #1095

asztalosdani opened this issue Oct 19, 2023 · 3 comments

Comments

@asztalosdani
Copy link

I would like to set a different hold delay and a hold repeat rate for a Button, like when you hold a key on the keyboard on PC.
Currently it is not possible because the Button waits hold_time first, then fires every hold_time.

@lurch
Copy link
Contributor

lurch commented Oct 20, 2023

So I guess you're asking for e.g. a repeat_time parameter, which is different from hold_time? That'd probably need changes to HoldMixin and it might be tricky to make those changes in a backwards-compatible way.

As a "temporary hack" what happens if you directly modify the Button's .hold_time property from inside the .when_held callback? I guess you'd also need to "reset" the hold time in the .when_released callback too.

@asztalosdani
Copy link
Author

So I guess you're asking for e.g. a repeat_time parameter, which is different from hold_time? That'd probably need changes to HoldMixin and it might be tricky to make those changes in a backwards-compatible way.

Yes. Ideally it could be represented with only two parameters, Button(pin, hold_delay, repeat_rate) where hold_delay is the time to wait until the button considers it held, and repeat_rate is the time between each hold event fires, with a default of 0 meaning it won't be repeated. This way, the hold_repeat bool can be removed. But yes, this breaks backward-compatibility.
In case this is not doable, adding a new hold_repeat_time parameter should do the trick.
If we can agree on the interface, I can whip up a PR.

As a "temporary hack" what happens if you directly modify the Button's .hold_time property from inside the .when_held callback? I guess you'd also need to "reset" the hold time in the .when_released callback too.

Thanks, it works, it will do for the time being.

from gpiozero import Button
from signal import pause

button = Button(16, pull_up=True, hold_repeat=True)


def when_pressed():
    print("pressed")


def when_held():
    print("held")
    button.hold_time = 0.1


def when_released():
    print("released")
    button.hold_time = 1


print("starting")

button.when_pressed = when_pressed
button.when_held = when_held
button.when_released = when_released

pause()

@lurch
Copy link
Contributor

lurch commented Oct 20, 2023

But yes, this breaks backward-compatibility. In case this is not doable, adding a new hold_repeat_time parameter should do the trick. If we can agree on the interface, I can whip up a PR.

I don't think we should break backwards-compatibility (especially for such a small tweak as this), as we don't want to suddenly break all of the existing user-code that's making use of GpioZero!

I've not given it much thought, but perhaps an "API" something like this works in a backwards-compatible manner?
(here I've just copied the Button's __init__ method as an example)

    def __init__(self, pin=None, *, pull_up=True, active_state=None,
                 bounce_time=None, hold_time=1, hold_repeat=False,
                 hold_repeat_time=None, pin_factory=None):
        if hold_repeat and hold_repeat_time is None:
            hold_repeat_time = hold_time
        # ...and now do everything else...

As a "temporary hack" what happens if you directly modify the Button's .hold_time property from inside the .when_held callback? I guess you'd also need to "reset" the hold time in the .when_released callback too.

Thanks, it works, it will do for the time being.

Awesome! I guess for consistency, since you're setting hold_time to 1 in when_released, you should probably explicitly pass hold_time=1 into the Button constructor too?

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

No branches or pull requests

2 participants