Line data Source code
1 : /* ✔ */ 2 : 3 : #pragma once 4 : 5 : #include <AH/Hardware/Button.hpp> 6 : #include <Def/Def.hpp> 7 : #include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp> 8 : 9 : BEGIN_CS_NAMESPACE 10 : 11 : /** 12 : * @brief A class for momentary buttons and switches that send MIDI events. 13 : * 14 : * The button is debounced, and the button is latched (press once to enable, 15 : * press again to disable) (toggle). 16 : * 17 : * @see Button 18 : */ 19 : template <class Sender> 20 2 : class MIDIButtonLatched : public MIDIOutputElement { 21 : protected: 22 : /** 23 : * @brief Create a new MIDIButtonLatched object on the given pin and 24 : * address. 25 : * 26 : * @param pin 27 : * The digital input pin to read from. 28 : * The internal pull-up resistor will be enabled. 29 : * @param address 30 : * The MIDI address to send to. 31 : * @param sender 32 : * The MIDI sender to use. 33 : */ 34 2 : MIDIButtonLatched(pin_t pin, const MIDICNChannelAddress &address, 35 : const Sender &sender) 36 4 : : button{pin}, address{address}, sender{sender} {} 37 : 38 : public: 39 0 : void begin() final override { button.begin(); } 40 0 : void update() final override { 41 0 : AH::Button::State state = button.update(); 42 0 : if (state == AH::Button::Falling) 43 0 : toggleState(); 44 0 : } 45 : 46 : /// Flip the state (on → off or off → on). 47 : /// Sends the appropriate MIDI event. 48 0 : bool toggleState() { 49 0 : setState(!getState()); 50 0 : return getState(); 51 : } 52 : 53 : /// Get the current state. 54 0 : bool getState() const { return state; } 55 : 56 : /// Set the state to the given value. 57 : /// Sends the appropriate MIDI event. 58 0 : void setState(bool state) { 59 0 : this->state = state; 60 0 : state ? sender.sendOn(address) : sender.sendOff(address); 61 0 : } 62 : 63 : #ifdef INDIVIDUAL_BUTTON_INVERT 64 : void invert() { button.invert(); } 65 : #endif 66 : 67 : /// Get the state of the underlying button. 68 : AH::Button::State getButtonState() const { return button.getState(); } 69 : 70 : private: 71 : AH::Button button; 72 : const MIDICNChannelAddress address; 73 2 : bool state = false; 74 : 75 : public: 76 : Sender sender; 77 : }; 78 : 79 : END_CS_NAMESPACE