Control Surface  1.1.0
MIDI Control Surface library for Arduino
Selector.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Selectable.hpp"
5 #include <AH/Debug/Debug.hpp>
6 #include <Def/Def.hpp>
7 
9 
10 /**
11  * @brief An enumeration to set the behavior of selectors that are incremented
12  * (decremented) beyond their maximum (minimum) setting.
13  */
14 enum class Wrap : bool {
15  Clamp = false, ///< When the maximum (minimum) setting is reached,
16  ///< clamp to the maximum (minimum) setting.
17  ///< @todo Rename to `Clamp`?
18  Wrap = true, ///< When the maximum (minimum) setting is reached,
19  ///< wrap around to the minimum (maximum) setting.
20  NoWrap = false,
21 };
22 
23 /// A callback for the GenericSelector class that does nothing.
25  /// Initialize.
26  void begin() {}
27  /// Refresh, called periodically.
28  void update() {}
29  /// Called when the setting changes.
30  void update(setting_t oldSetting, setting_t newSetting) {
31  (void)oldSetting, (void)newSetting;
32  }
33 };
34 
35 /// Base class for all Selectors exposing the `get` method, so it can be used
36 /// by display elements etc, without having to provide the full generic type.
37 ///
38 /// A `set` method is not provided, because that would require either more
39 /// virtual functions, or a rather large refactoring.
40 class SelectorBase {
41  protected:
42  /// Constructor.
43  SelectorBase() = default;
44 
45  public:
46  /// Get the current selection/setting.
47  setting_t get() const { return setting; }
48 
49  protected:
50  /// The selection of the selector. It is saved in the selector as well as
51  /// the selectable, because you need it in order to implement
52  /// increment/decrement methods.
54 };
55 
56 template <setting_t N, class Callback = EmptySelectorCallback>
57 class GenericSelector : public SelectorBase, public AH::Updatable<> {
58  public:
59  /**
60  * @brief Constructor.
61  *
62  * @param selectable
63  * The selectable object to manage. When the value of the selector
64  * changes, it changes the selection of this selectable.
65  * @param callback
66  * The callback to call when the value changes. Used for (visual)
67  * feedback from the selector (e.g. LEDs or some different kind of
68  * display).
69  */
72 
73  void begin() override {
74  callback.begin();
75  reset();
76  }
77 
78  void update() override { callback.update(); }
79 
80  /// Reset the selection to the initial selection.
81  void reset() { set(selectable.getInitialSelection()); }
82 
83  /**
84  * @brief Select the given selection
85  *
86  * @param newSetting
87  * The new setting to select [0, N-1].
88  */
89  void set(setting_t newSetting) {
90  newSetting = selectable.validateSetting(newSetting);
91  selectable.select(newSetting);
92  if (get() != newSetting) {
93  callback.update(get(), newSetting);
94  setting = newSetting;
95  }
96  }
97 
98  /**
99  * @brief Add one to the setting, wrap around or clamp, depending on the
100  * parameter, if the new setting would be out of range.
101  *
102  * @param wrap
103  * Wrap or clamp if the new setting would be out of range.
104  */
105  void increment(Wrap wrap) {
106  setting_t setting = this->get();
107  setting++;
108  if (setting == N) {
109  if (wrap == Wrap::Wrap)
110  setting = 0;
111  else
112  return;
113  }
114  this->set(setting);
115  }
116 
117  /**
118  * @brief Subtract one from the setting, wrap around or clamp, depending
119  * on the parameter, if the new setting would be out of range.
120  *
121  * @param wrap
122  * Wrap or clamp if the new setting would be out of range.
123  */
124  void decrement(Wrap wrap) {
125  setting_t setting = this->get();
126  if (setting == 0) {
127  if (wrap == Wrap::Wrap)
128  setting = N;
129  else
130  return;
131  }
132  setting--;
133  this->set(setting);
134  }
135 
136  private:
138 
139  public:
140  Callback callback;
141 };
142 
143 /**
144  * @brief A Selector with an empty callback.
145  *
146  * @tparam N
147  * The number of possible settings.
148  */
149 template <setting_t N>
150 class Selector : public GenericSelector<N> {
151  public:
152  /// Constructor
154 };
155 
Selector
A Selector with an empty callback.
Definition: Selector.hpp:150
EmptySelectorCallback::update
void update()
Refresh, called periodically.
Definition: Selector.hpp:28
EmptySelectorCallback::update
void update(setting_t oldSetting, setting_t newSetting)
Called when the setting changes.
Definition: Selector.hpp:30
SelectorBase::setting
setting_t setting
The selection of the selector.
Definition: Selector.hpp:53
GenericSelector::decrement
void decrement(Wrap wrap)
Subtract one from the setting, wrap around or clamp, depending on the parameter, if the new setting w...
Definition: Selector.hpp:124
GenericSelector::selectable
Selectable< N > & selectable
Definition: Selector.hpp:137
AH::Updatable
A super class for object that have to be updated regularly.
Definition: Updatable.hpp:25
SelectorBase::get
setting_t get() const
Get the current selection/setting.
Definition: Selector.hpp:47
Selector::Selector
Selector(Selectable< N > &selectable)
Constructor.
Definition: Selector.hpp:153
SelectorBase::SelectorBase
SelectorBase()=default
Constructor.
Updatable.hpp
SelectorBase
Base class for all Selectors exposing the get method, so it can be used by display elements etc,...
Definition: Selector.hpp:40
Def.hpp
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
Selectable.hpp
Selectable
Definition: Selectable.hpp:11
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
EmptySelectorCallback
A callback for the GenericSelector class that does nothing.
Definition: Selector.hpp:24
Wrap::NoWrap
GenericSelector::set
void set(setting_t newSetting)
Select the given selection.
Definition: Selector.hpp:89
EmptySelectorCallback::begin
void begin()
Initialize.
Definition: Selector.hpp:26
GenericSelector::GenericSelector
GenericSelector(Selectable< N > &selectable, const Callback &callback)
Constructor.
Definition: Selector.hpp:70
Wrap
Wrap
An enumeration to set the behavior of selectors that are incremented (decremented) beyond their maxim...
Definition: Selector.hpp:14
GenericSelector
Definition: Selector.hpp:57
GenericSelector::update
void update() override
Update this updatable.
Definition: Selector.hpp:78
GenericSelector::callback
Callback callback
Definition: Selector.hpp:140
GenericSelector::increment
void increment(Wrap wrap)
Add one to the setting, wrap around or clamp, depending on the parameter, if the new setting would be...
Definition: Selector.hpp:105
setting_t
uint8_t setting_t
The type used for Selectors.
Definition: Def.hpp:50
Wrap::Wrap
When the maximum (minimum) setting is reached, wrap around to the minimum (maximum) setting.
Debug.hpp
GenericSelector::begin
void begin() override
Initialize this updatable.
Definition: Selector.hpp:73
Wrap::Clamp
When the maximum (minimum) setting is reached, clamp to the maximum (minimum) setting.
GenericSelector::reset
void reset()
Reset the selection to the initial selection.
Definition: Selector.hpp:81