Line data Source code
1 : /* ✔ */ 2 : 3 : #pragma once 4 : 5 : #include "Button.hpp" 6 : 7 : BEGIN_AH_NAMESPACE 8 : 9 : /** 10 : * @brief A class for buttons that increment and decrement some counter or 11 : * setting. 12 : * 13 : * It behaves the same way as a computer keyboard: when you press the increment 14 : * (decrement) button, it increments (decrements) the counter once. 15 : * If you keep on pressing it for longer than a certain threshold, it keeps on 16 : * incrementing (decrementing) at a faster rate, until you release it. 17 : * If both the increment and the decrement button are pressed at once, it resets 18 : * the counter. 19 : * 20 : * @ingroup AH_HardwareUtils 21 : */ 22 : class IncrementDecrementButtons { 23 : public: 24 : /** 25 : * @brief Create a IncrementDecrementButtons object. 26 : * 27 : * @param incrementButton 28 : * The button to increment the counter. 29 : * The button is copied. 30 : * @param decrementButton 31 : * The button to decrement the counter. 32 : * The button is copied. 33 : */ 34 12 : IncrementDecrementButtons(const Button &incrementButton, 35 : const Button &decrementButton) 36 12 : : incrementButton(incrementButton), decrementButton(decrementButton) {} 37 : 38 : /// @see Button::begin 39 7 : void begin() { 40 7 : incrementButton.begin(); 41 7 : decrementButton.begin(); 42 7 : } 43 : 44 : /** 45 : * @brief An enumeration of the different actions to be performed by the 46 : * counter. 47 : * @todo Add states for initial press. 48 : */ 49 : enum State { 50 : Nothing = 0, ///< The counter should not be incremented. 51 : IncrementShort, ///< The counter must be incremented (after short press). 52 : IncrementLong, ///< The counter must be incremented (after long press). 53 : IncrementHold, ///< The counter must be incremented (still pressed). 54 : DecrementShort, ///< The counter must be decremented (after short press). 55 : DecrementLong, ///< The counter must be decremented (after long press). 56 : DecrementHold, ///< The counter must be decremented (still pressed). 57 : Reset, ///< The counter should be reset to the initial value. 58 : }; 59 : 60 : /** 61 : * @brief Update and return the state of the increment/decrement button. 62 : */ 63 38 : State update() { return state = updateImplementation(); } 64 : 65 : /** 66 : * @brief Return the state of the increment/decrement button without 67 : * updating it. 68 : * 69 : * Returns the same value as the last @ref update call. 70 : */ 71 : State getState() const { return state; } 72 : 73 : /// @see Button::invert 74 : void invert() { 75 : incrementButton.invert(); 76 : decrementButton.invert(); 77 : } 78 : 79 : protected: 80 : State updateImplementation(); 81 : 82 : private: 83 : Button incrementButton; 84 : Button decrementButton; 85 : 86 : enum { 87 : Initial, 88 : LongPress, 89 : AfterReset, 90 : } longPressState = Initial; 91 : unsigned long longPressRepeat; 92 : State state = Nothing; 93 : }; 94 : 95 : END_AH_NAMESPACE