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