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

Dependents:   KeyboardTest

LongKeyPressMonitor.cpp

Committer:
osmeest
Date:
2011-02-03
Revision:
3:1310c57aca77

File content as of revision 3:1310c57aca77:

#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