KeyboardManager: a class to manage the polling of a switch-matrix keyboard

Dependents:   KeyboardTest

Revision:
3:1310c57aca77
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LongKeyPressMonitor.cpp	Thu Feb 03 22:01:57 2011 +0000
@@ -0,0 +1,132 @@
+#include <kbd_mgr/LongKeyPressMonitor.h>
+
+namespace kbd_mgr {
+
+LongKeyPressMonitor::AutoRepeatSetupProxy LongKeyPressMonitor::autoRepeat(float initTime, float delay)
+{
+    this->repeatInitTime_ = initTime;
+    this->repeatDelay_ = delay;
+    
+    return AutoRepeatSetupProxy(this);
+} 
+    
+void LongKeyPressMonitor::addAutoRepeatKey(int firstKey, int lastKey)
+{
+    for(int key = firstKey; key <= lastKey; ++key) {
+        this->repeatKeys_.insert(key);
+        this->longPressKeys_.erase(key);
+    }
+}
+
+LongKeyPressMonitor::LongPressSetupProxy LongKeyPressMonitor::longKeyPress(float longPressTime)
+{
+    this->longPressTime_ = longPressTime;
+    return LongPressSetupProxy(this);
+}
+    
+void LongKeyPressMonitor::addLongPressKey(int firstKey, int lastKey)
+{
+    for(int key = firstKey; key <= lastKey; ++key) {
+        this->longPressKeys_.insert(key);
+        this->repeatKeys_.erase(key);
+    }
+}
+
+void LongKeyPressMonitor::handleKeyPress(const KeyEvent &keypress)
+{
+    if (keypress.event == KeyEvent::KeyDown) {
+        invokeHandler(keypress);
+        handleKeyDown(keypress);
+    }
+    else if (keypress.event == KeyEvent::KeyUp) {
+        handleKeyUp(keypress);
+        invokeHandler(keypress);
+    }
+    else {
+        invokeHandler(keypress);
+    }
+}
+
+void LongKeyPressMonitor::handleKeyDown(const KeyEvent &keypress)
+{
+    this->keyDownCount++;
+    if (this->keyDownCount == 1) {
+        handleFirstKeyDown(keypress);
+    }
+    else {
+        handleOtherKeyDown(keypress);
+    }
+}
+
+void LongKeyPressMonitor::handleFirstKeyDown(const KeyEvent &keypress)
+{
+    this->keypress = keypress;
+    
+    if (isAutoRepeatKey(keypress.keyCode)) {
+        this->state = RepeatInitWait;
+        this->timer.attach(this, &LongKeyPressMonitor::handleTimer, this->repeatInitTime_);
+    }
+    else if (isLongPressKey(keypress.keyCode)) {
+        this->state = LongPressWait;
+        this->timer.attach(this, &LongKeyPressMonitor::handleTimer, this->longPressTime_);
+    }
+}
+
+void LongKeyPressMonitor::handleOtherKeyDown(const KeyEvent &keypress)
+{
+    this->state = Invalid;
+    this->timer.detach();
+}
+
+void LongKeyPressMonitor::handleKeyUp(const KeyEvent &keypress)
+{
+    this->keyDownCount--;
+
+    if (this->state == Invalid || this->state == RepeatInitWait || this->state == LongPressWait) {
+        KeyEvent pressed(keypress, KeyEvent::KeyPress);
+        invokeHandler(pressed);
+    }
+    
+    if (this->keyDownCount == 0) {
+        handleLastKeyUp(keypress);
+    }
+}
+    
+void LongKeyPressMonitor::handleLastKeyUp(const KeyEvent &keypress)
+{
+    this->state = Idle;
+}
+    
+void LongKeyPressMonitor::handleTimer()
+{
+    switch(this->state) {
+    case RepeatInitWait:
+    case Repeating:
+        handleRepeatTimer();
+        break;
+    case LongPressWait:
+        handleLongPressTimer();
+        break;
+    default:
+        break;
+    }
+}
+
+void LongKeyPressMonitor::handleRepeatTimer()
+{
+    KeyEvent repeated(this->keypress, 
+        (this->state == RepeatInitWait ? KeyEvent::KeyPress : KeyEvent::RepeatedKeyPress));
+    invokeHandler(repeated);
+    
+    this->state = Repeating;
+    this->timer.attach(this, &LongKeyPressMonitor::handleTimer, this->repeatDelay_);
+}
+
+void LongKeyPressMonitor::handleLongPressTimer()
+{
+    KeyEvent longPressed(keypress, KeyEvent::LongKeyPress);
+    invokeHandler(longPressed);
+    this->state = LongPressReported;
+}
+
+} // kbd_mgr