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
|