mathertel / OneButton

An Arduino library for using a single button for multiple purpose input.
http://www.mathertel.de/Arduino/OneButtonLibrary.aspx
Other
954 stars 230 forks source link

Add event handlers and pin/state getters #66

Closed rochdi80tn closed 3 years ago

rochdi80tn commented 4 years ago

This is the implementation idea annouced in issue #65

A child class will look as this :


class Switch : public OneButton {
public:
        int some_attribute;

    // core methods
    // =================
    // constructor and destructor
    Switch(int pin, int activeLow = true, bool pullupActive = true);
    Switch();

        // events
    // -- overrided from OneButton class -----------
    void clickEvent() override;
    void pressEvent() override;
    void longPressStartEvent() override;
    void longPressStopEvent()  override;
    void duringLongPressEvent() override;
    void doubleClickEvent() override;
};

Switch::Switch(int pin, int activeLow, bool pullupActive) 
                                   : OneButton(pin, activeLow, pullupActive){
  // other initializations if needed
}

// events
void Switch::clickEvent()  {
    // do something linked to the Switch click event
   // like using the some_attribute

}
void Switch::pressEvent()  {
     /// implement the press event handler
}
 // etc...

This will be very helpfull if someone have a bunch of buttons and that the action is handled the same way. Ex. linking buttons to toggle state of specefic output pin. We need just to define the output pin as an attribute, keep track of the state of the output pin value and in the clickEvent handler do a digitalWrite with the toggled value...

rochdi80tn commented 4 years ago

Okay further investigating on this I did a workarround to implement what I need without changing the OneButton nor extending it ...


// Handler wrapper function for a single click:
static void __handleClick(void* s) { ((Switch*)s)->clickEvent(); }

// Handler wrapper function for a double click:
static void __handleDoubleClick(void* s) { ((Switch*)s)->doubleClickEvent(); }

// Handler wrapper function for a long press start :
static void __handleLongPressStart(void* s) { ((Switch*)s)->longPressStartEvent(); }

// Handler wrapper function for a long press stop:
static void __handleLongPressStop(void* s) { ((Switch*)s)->longPressStopEvent(); }

// Handler wrapper function for a during long press:
static void __handleDuringLongPress(void* s) { ((Switch*)s)->duringLongPressEvent(); }

// core methods
// =================
// constructor and destructor
Switch::Switch(int pin, int activeLow, bool pullupActive){
    btn = new OneButton(pin, activeLow, pullupActive);
    btn->attachClick(__handleClick, this);
    btn->attachDoubleClick(__handleDoubleClick, this);
    btn->attachLongPressStart(__handleLongPressStart, this);
    btn->attachLongPressStop(__handleLongPressStop, this);
    btn->attachDuringLongPress(__handleDuringLongPress, this);

    init();
}
// ....

// events
void Switch::clickEvent()  {
   #ifdef DEBUG
    Serial.println("\n" + toString()+" clickEvent()");
  #endif
    // further action for the button beeign cliecked
}

where


class Switch  {
public:
    OneButton* btn = NULL;

    // core methods
    // =================
    // constructor and destructor
    Switch(int pin, int activeLow = true, bool pullupActive = true);

        // events
    void clickEvent();
    void pressEvent();
    void longPressStartEvent();
    void longPressStopEvent();
    void duringLongPressEvent();
    void doubleClickEvent();

        // ...

}
mathertel commented 3 years ago

I like the idea in case you have multiple buttons with same interaction behavior. As you did findout, this can be done on top of he existing OneButton without any modifications so I will not merge the request.

I looked into your code and found that you did a quiet nice modifications using _doubleClickEnabled variable. I will used this approach (see _maxClicks) in version 2.0.

rochdi80tn commented 3 years ago

No problem @mathertel. I might suggest though to add the workaround for handling multiple buttons with same interaction behavior to library documentation. This could be useful to others having the same need.