KeyboardManager: a class to manage the polling of a switch-matrix keyboard
Diff: kbd_mgr/LongKeyPressMonitor.h
- Revision:
- 3:1310c57aca77
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kbd_mgr/LongKeyPressMonitor.h Thu Feb 03 22:01:57 2011 +0000 @@ -0,0 +1,115 @@ +#ifndef LONG_KEY_PRESS_MONITOR_H_ +#define LONG_KEY_PRESS_MONITOR_H_ + +#include <kbd_mgr/KeyPressEventServer.h> +#include <set> + +#include "mbed.h" + +namespace kbd_mgr { + +/** + * @brief A key press event handler that detects long key presses and report them as specified. + * This class offers two specific reactions for long key presses. Either a specific long key press is reported + * or the key press event is auto repeated. The timing for both kind of reactions can be specified independently. + * The monitor reacts on key code, not on mapped key char. If a mapped key char is present in the event, it is retained + * in the generated key press events. + */ +class LongKeyPressMonitor : public KeyPressEventServer, public KeyPressEventHandler { +public: + LongKeyPressMonitor() : + repeatKeys_(), repeatInitTime_(0), repeatDelay_(0), longPressKeys_(), longPressTime_(0), + state(Idle), keyDownCount(0), timer() + { } + + class AutoRepeatSetupProxy { + public: + AutoRepeatSetupProxy(LongKeyPressMonitor *monitor) : monitor_(monitor) { } + AutoRepeatSetupProxy& operator()(int key) { this->monitor_->addAutoRepeatKey(key, key); return *this; } + AutoRepeatSetupProxy& operator()(int firstKey, int lastKey) { this->monitor_->addAutoRepeatKey(firstKey, lastKey); return *this; } + + private: + LongKeyPressMonitor *monitor_; + }; + + friend class AutoRepeatSetupProxy; + + /** + * @brief Sets up auto-repeat keys. + * This method takes the timing parameters. It returns a special class that allows specifying the keys + * between brackets. Eg: + * - monitor.autoRepeat(0.3, 0.1)(1)(2)(4,8) + * Sets up auto repeat after 300ms, every 100ms for keys 1, 2 and 4 to 8. + */ + AutoRepeatSetupProxy autoRepeat(float initTime, float delay); + + + class LongPressSetupProxy { + public: + LongPressSetupProxy(LongKeyPressMonitor *monitor) : monitor_(monitor) { } + LongPressSetupProxy& operator()(int key) { this->monitor_->addLongPressKey(key, key); return *this; } + LongPressSetupProxy& operator()(int firstKey, int lastKey) { this->monitor_->addLongPressKey(firstKey, lastKey); return *this; } + + private: + LongKeyPressMonitor *monitor_; + }; + + friend class LongPressSetupProxy; + + /** + * @brief Sets up long key press keys. + * This method takes the timing parameters. It returns a special class that allows specifying the keys + * between brackets. Eg: + * - monitor.longKeyPress(0.5)(3)(12,14) + * Sets up report of long key press after 500ms for keys 3 and 12 to 14. + */ + LongPressSetupProxy longKeyPress(float longPressTime); + + /** + * @brief KeyPressEventHandler interface + */ + virtual void handleKeyPress(const KeyEvent &keypress); + +private: + void addAutoRepeatKey(int firstKey, int lastKey); + bool isAutoRepeatKey(int key) const { return this->repeatKeys_.find(key) != this->repeatKeys_.end(); } + void addLongPressKey(int firstKey, int lastKey); + bool isLongPressKey(int key) const { return this->longPressKeys_.find(key) != this->longPressKeys_.end(); } + + void handleKeyDown(const KeyEvent &keypress); + void handleFirstKeyDown(const KeyEvent &keypress); + void handleOtherKeyDown(const KeyEvent &keypress); + void handleKeyUp(const KeyEvent &keypress); + void handleLastKeyUp(const KeyEvent &keypress); + + void handleTimer(); + void handleRepeatTimer(); + void handleLongPressTimer(); + + typedef std::set<int> KeySet; + + KeySet repeatKeys_; + float repeatInitTime_; + float repeatDelay_; + + KeySet longPressKeys_; + float longPressTime_; + + enum State { + Idle, + RepeatInitWait, + Repeating, + LongPressWait, + LongPressReported, + Invalid + }; + + State state; + KeyEvent keypress; + int keyDownCount; + Timeout timer; +}; + +} // kbd_mgr + +#endif // LONG_KEY_PRESS_MONITOR_H_