AceButton  1.8.1
An adjustable, compact, event-driven button library for Arduino.
ButtonConfig.h
1 /*
2 MIT License
3 
4 Copyright (c) 2018 Brian T. Park
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
25 #ifndef ACE_BUTTON_BUTTON_CONFIG_H
26 #define ACE_BUTTON_BUTTON_CONFIG_H
27 
28 #include <Arduino.h>
29 #include "IEventHandler.h"
30 
31 // https://stackoverflow.com/questions/295120
32 #if defined(__GNUC__) || defined(__clang__)
33  #define ACE_BUTTON_DEPRECATED __attribute__((deprecated))
34 #elif defined(_MSC_VER)
35  #define ACE_BUTTON_DEPRECATED __declspec(deprecated)
36 #else
37  #pragma message("WARNING: Implement ACE_BUTTON_DEPRECATED for this compiler")
38  #define ACE_BUTTON_DEPRECATED
39 #endif
40 
41 namespace ace_button {
42 
43 class AceButton;
44 
66 class ButtonConfig {
67  public:
68  // Various timing constants, in milliseconds.
69  //
70  // Note that the timing constants are stored as uint16_t (2
71  // bytes) instead of unsigned long (4 bytes) which is the type returned by
72  // the millis() system method. It turns out that we can store and perform
73  // all timing calculations using uint16_t without ill effect, as long as the
74  // polling of AceButton::check() happens more frequently than the rollover
75  // time of a uint16_t (i.e. 65.536 seconds) and certain precautions (e.g.
76  // AceButton::checkOrphanedClick()) are taken before a uint16_t rollover
77  // happens. In theory, these additional precautions would be needed even if
78  // an 'unsigned long' is used but almost no one does them because they
79  // assume that their code won't be running continuously for the rollover
80  // time of an 'unsigned long' (i.e. 49.7 days).
81 
83  static const uint16_t kDebounceDelay = 20;
84 
86  static const uint16_t kClickDelay = 200;
87 
89  static const uint16_t kDoubleClickDelay = 400;
90 
92  static const uint16_t kLongPressDelay = 1000;
93 
95  static const uint16_t kRepeatPressDelay = 1000;
96 
98  static const uint16_t kRepeatPressInterval = 200;
99 
100  // Various features controlled by feature flags.
101 
107  typedef uint16_t FeatureFlagType;
108 
110  static const FeatureFlagType kFeatureClick = 0x01;
111 
118 
120  static const FeatureFlagType kFeatureLongPress = 0x04;
121 
124 
127 
134 
137 
140 
148 
154 
168 
176  typedef void (*EventHandler)(AceButton* button, uint8_t eventType,
177  uint8_t buttonState);
178 
180  ButtonConfig() = default;
181 
182  #if ! defined(ARDUINO_ARCH_AVR)
183 
212  virtual ~ButtonConfig() = default;
213  #endif
214 
216  uint16_t getDebounceDelay() const { return mDebounceDelay; }
217 
219  uint16_t getClickDelay() const { return mClickDelay; }
220 
225  uint16_t getDoubleClickDelay() const {
226  return mDoubleClickDelay;
227  }
228 
230  uint16_t getLongPressDelay() const {
231  return mLongPressDelay;
232  }
233 
240  uint16_t getRepeatPressDelay() const {
241  return mRepeatPressDelay;
242  }
243 
247  uint16_t getRepeatPressInterval() const {
248  return mRepeatPressInterval;
249  }
250 
252  void setDebounceDelay(uint16_t debounceDelay) {
253  mDebounceDelay = debounceDelay;
254  }
255 
257  void setClickDelay(uint16_t clickDelay) {
258  mClickDelay = clickDelay;
259  }
260 
262  void setDoubleClickDelay(uint16_t doubleClickDelay) {
263  mDoubleClickDelay = doubleClickDelay;
264  }
265 
267  void setLongPressDelay(uint16_t longPressDelay) {
268  mLongPressDelay = longPressDelay;
269  }
270 
272  void setRepeatPressDelay(uint16_t repeatPressDelay) {
273  mRepeatPressDelay = repeatPressDelay;
274  }
275 
277  void setRepeatPressInterval(uint16_t repeatPressInterval) {
278  mRepeatPressInterval = repeatPressInterval;
279  }
280 
281  // The getClock() and readButton() are external dependencies that normally
282  // would be injected using separate classes, but in the interest of saving
283  // RAM in an embedded environment, we expose them in this class instead.
284 
293  virtual unsigned long getClock() { return millis(); }
294 
303  virtual int readButton(uint8_t pin) {
304  return digitalRead(pin);
305  }
306 
307  // These methods provide access to various feature flags that control the
308  // functionality of the AceButton.
309 
311  bool isFeature(FeatureFlagType features) const {
312  return mFeatureFlags & features;
313  }
314 
316  void setFeature(FeatureFlagType features) {
317  mFeatureFlags |= features;
318  }
319 
321  void clearFeature(FeatureFlagType features) {
322  mFeatureFlags &= ~features;
323  }
324 
330  void resetFeatures() {
331  // NOTE: If any additional kInternalFeatureXxx flag is added, it must be
332  // added here like this:
333  // mFeatureFlags &= (kInternalFeatureIEventHandler | kInternalFeatureXxx)
334  mFeatureFlags &= kInternalFeatureIEventHandler;
335  }
336 
337  // EventHandler
338 
348  EventHandler getEventHandler() const ACE_BUTTON_DEPRECATED {
349  return reinterpret_cast<EventHandler>(mEventHandler);
350  }
351 
356  void dispatchEvent(AceButton* button, uint8_t eventType,
357  uint8_t buttonState) const {
358 
359  if (! mEventHandler) return;
360 
362  IEventHandler* eventHandler =
363  reinterpret_cast<IEventHandler*>(mEventHandler);
364  eventHandler->handleEvent(button, eventType, buttonState);
365  } else {
366  EventHandler eventHandler =
367  reinterpret_cast<EventHandler>(mEventHandler);
368  eventHandler(button, eventType, buttonState);
369  }
370  }
371 
376  void setEventHandler(EventHandler eventHandler) {
377  mEventHandler = reinterpret_cast<void*>(eventHandler);
379  }
380 
385  void setIEventHandler(IEventHandler* eventHandler) {
386  mEventHandler = eventHandler;
388  }
389 
395  return &sSystemButtonConfig;
396  }
397 
398  private:
403  static ButtonConfig sSystemButtonConfig;
404 
405  // Disable copy-constructor and assignment operator
406  ButtonConfig(const ButtonConfig&) = delete;
407  ButtonConfig& operator=(const ButtonConfig&) = delete;
408 
410  void* mEventHandler = nullptr;
411 
413  FeatureFlagType mFeatureFlags = 0;
414 
415  uint16_t mDebounceDelay = kDebounceDelay;
416  uint16_t mClickDelay = kClickDelay;
417  uint16_t mDoubleClickDelay = kDoubleClickDelay;
418  uint16_t mLongPressDelay = kLongPressDelay;
419  uint16_t mRepeatPressDelay = kRepeatPressDelay;
420  uint16_t mRepeatPressInterval = kRepeatPressInterval;
421 };
422 
423 }
424 #endif
ace_button::ButtonConfig::getRepeatPressDelay
uint16_t getRepeatPressDelay() const
Milliseconds that a button needs to be Pressed down before the start of the sequence of RepeatPressed...
Definition: ButtonConfig.h:240
ace_button::ButtonConfig::getLongPressDelay
uint16_t getLongPressDelay() const
Milliseconds for a long press event.
Definition: ButtonConfig.h:230
ace_button::ButtonConfig::kFeatureSuppressClickBeforeDoubleClick
static const FeatureFlagType kFeatureSuppressClickBeforeDoubleClick
Flag to suppress kEventClicked before a kEventDoubleClicked.
Definition: ButtonConfig.h:147
ace_button::ButtonConfig::kFeatureSuppressAfterClick
static const FeatureFlagType kFeatureSuppressAfterClick
Flag to suppress kEventReleased after a kEventClicked.
Definition: ButtonConfig.h:126
ace_button::ButtonConfig::kFeatureClick
static const FeatureFlagType kFeatureClick
Flag to activate the AceButton::kEventClicked event.
Definition: ButtonConfig.h:110
ace_button::ButtonConfig::setDebounceDelay
void setDebounceDelay(uint16_t debounceDelay)
Set the debounceDelay.
Definition: ButtonConfig.h:252
ace_button::ButtonConfig::kInternalFeatureIEventHandler
static const FeatureFlagType kInternalFeatureIEventHandler
Internal flag to indicate that mEventHandler is an IEventHandler object pointer instead of an EventHa...
Definition: ButtonConfig.h:153
ace_button::ButtonConfig::getEventHandler
EventHandler getEventHandler() const ACE_BUTTON_DEPRECATED
Return the eventHandler function pointer.
Definition: ButtonConfig.h:348
ace_button::ButtonConfig::setIEventHandler
void setIEventHandler(IEventHandler *eventHandler)
Install the IEventHandler object pointer.
Definition: ButtonConfig.h:385
ace_button::ButtonConfig::getClock
virtual unsigned long getClock()
Return the milliseconds of the internal clock.
Definition: ButtonConfig.h:293
ace_button::ButtonConfig::kFeatureRepeatPress
static const FeatureFlagType kFeatureRepeatPress
Flag to activate the AceButton::kEventRepeatPressed event.
Definition: ButtonConfig.h:123
ace_button::IEventHandler
Interface of the class that will handle the button event.
Definition: IEventHandler.h:39
ace_button::ButtonConfig::kDebounceDelay
static const uint16_t kDebounceDelay
Default value returned by getDebounceDelay().
Definition: ButtonConfig.h:83
ace_button::IEventHandler::handleEvent
virtual void handleEvent(AceButton *button, uint8_t eventType, uint8_t buttonState)=0
Handle the button event.
ace_button::ButtonConfig::setEventHandler
void setEventHandler(EventHandler eventHandler)
Install the EventHandler function pointer.
Definition: ButtonConfig.h:376
ace_button::ButtonConfig::setLongPressDelay
void setLongPressDelay(uint16_t longPressDelay)
Set the longPressDelay.
Definition: ButtonConfig.h:267
ace_button::ButtonConfig::dispatchEvent
void dispatchEvent(AceButton *button, uint8_t eventType, uint8_t buttonState) const
Dispatch the event to the handler.
Definition: ButtonConfig.h:356
ace_button::ButtonConfig::kRepeatPressDelay
static const uint16_t kRepeatPressDelay
Default value returned by getRepeatPressDelay().
Definition: ButtonConfig.h:95
ace_button::ButtonConfig::getDebounceDelay
uint16_t getDebounceDelay() const
Milliseconds to wait for debouncing.
Definition: ButtonConfig.h:216
ace_button::ButtonConfig::kFeatureSuppressAfterLongPress
static const FeatureFlagType kFeatureSuppressAfterLongPress
Flag to suppress kEventReleased after a kEventLongPressed.
Definition: ButtonConfig.h:136
ace_button::ButtonConfig::isFeature
bool isFeature(FeatureFlagType features) const
Check if the given features are enabled.
Definition: ButtonConfig.h:311
ace_button::AceButton
An Adjustable Compact Event-driven (ACE) Button library that debounces and dispatches button events t...
Definition: AceButton.h:51
ace_button::ButtonConfig::getDoubleClickDelay
uint16_t getDoubleClickDelay() const
Milliseconds between the first and second click to register as a double-click.
Definition: ButtonConfig.h:225
ace_button::ButtonConfig::getSystemButtonConfig
static ButtonConfig * getSystemButtonConfig()
Return a pointer to the singleton instance of the ButtonConfig which is attached to all AceButton ins...
Definition: ButtonConfig.h:394
ace_button::ButtonConfig::getClickDelay
uint16_t getClickDelay() const
Milliseconds to wait for a possible click.
Definition: ButtonConfig.h:219
ace_button::ButtonConfig::kFeatureSuppressAfterDoubleClick
static const FeatureFlagType kFeatureSuppressAfterDoubleClick
Flag to suppress kEventReleased after a kEventDoubleClicked.
Definition: ButtonConfig.h:133
ace_button::ButtonConfig
Class that defines the timing parameters and event handler of an AceButton or a group of AceButton in...
Definition: ButtonConfig.h:66
ace_button::ButtonConfig::setRepeatPressDelay
void setRepeatPressDelay(uint16_t repeatPressDelay)
Set the repeatPressDelay.
Definition: ButtonConfig.h:272
ace_button::ButtonConfig::EventHandler
void(* EventHandler)(AceButton *button, uint8_t eventType, uint8_t buttonState)
The event handler signature.
Definition: ButtonConfig.h:176
ace_button::ButtonConfig::kDoubleClickDelay
static const uint16_t kDoubleClickDelay
Default value returned by getDoubleClickDelay().
Definition: ButtonConfig.h:89
ace_button::ButtonConfig::~ButtonConfig
virtual ~ButtonConfig()=default
If the ButtonConfig is created and deleted on the heap, a virtual destructor is technically required ...
ace_button::ButtonConfig::setDoubleClickDelay
void setDoubleClickDelay(uint16_t doubleClickDelay)
Set the doubleClickDelay.
Definition: ButtonConfig.h:262
ace_button::ButtonConfig::ButtonConfig
ButtonConfig()=default
Constructor.
ace_button::ButtonConfig::kLongPressDelay
static const uint16_t kLongPressDelay
Default value returned by getLongPressDelay().
Definition: ButtonConfig.h:92
ace_button::ButtonConfig::getRepeatPressInterval
uint16_t getRepeatPressInterval() const
Milliseconds between two successive RepeatPressed events.
Definition: ButtonConfig.h:247
ace_button::ButtonConfig::setClickDelay
void setClickDelay(uint16_t clickDelay)
Set the clickDelay.
Definition: ButtonConfig.h:257
ace_button::ButtonConfig::setRepeatPressInterval
void setRepeatPressInterval(uint16_t repeatPressInterval)
Set the repeatPressInterval.
Definition: ButtonConfig.h:277
ace_button::ButtonConfig::kRepeatPressInterval
static const uint16_t kRepeatPressInterval
Default value returned by getRepeatPressInterval().
Definition: ButtonConfig.h:98
ace_button::ButtonConfig::resetFeatures
void resetFeatures()
Disable all (externally visible) features.
Definition: ButtonConfig.h:330
ace_button::ButtonConfig::clearFeature
void clearFeature(FeatureFlagType features)
Disable the given features.
Definition: ButtonConfig.h:321
ace_button::ButtonConfig::kFeatureDoubleClick
static const FeatureFlagType kFeatureDoubleClick
Flag to activate the AceButton::kEventDoubleClicked event.
Definition: ButtonConfig.h:117
ace_button::ButtonConfig::kFeatureSuppressAll
static const FeatureFlagType kFeatureSuppressAll
Convenience flag to suppress all suppressions.
Definition: ButtonConfig.h:162
ace_button::ButtonConfig::setFeature
void setFeature(FeatureFlagType features)
Enable the given features.
Definition: ButtonConfig.h:316
ace_button::ButtonConfig::kClickDelay
static const uint16_t kClickDelay
Default value returned by getClickDelay().
Definition: ButtonConfig.h:86
ace_button::ButtonConfig::kFeatureLongPress
static const FeatureFlagType kFeatureLongPress
Flag to activate the AceButton::kEventLongPress event.
Definition: ButtonConfig.h:120
ace_button::ButtonConfig::kFeatureSuppressAfterRepeatPress
static const FeatureFlagType kFeatureSuppressAfterRepeatPress
Flag to suppress kEventReleased after a kEventRepeatPressed.
Definition: ButtonConfig.h:139
ace_button::ButtonConfig::FeatureFlagType
uint16_t FeatureFlagType
Type of the feature flag.
Definition: ButtonConfig.h:107
ace_button::ButtonConfig::readButton
virtual int readButton(uint8_t pin)
Return the HIGH or LOW state of the button.
Definition: ButtonConfig.h:303