From 8834a0ffc0be61218ab86bf209cb6cd53a18a565 Mon Sep 17 00:00:00 2001 From: that Date: Tue, 5 Jan 2016 23:29:30 +0100 Subject: gui: add keyboard support for Ctrl layer and more special keys - rename NotifyKeyboard to NotifyCharInput - input: handle arrow keys in NotifyKey with standard KEY_* codes - fix page handler to return 0 from NotifyKey if key was handled - fix GUIAction::NotifyKey to not swallow all keys - change home button code from KEY_HOME to KEY_HOMEPAGE (to avoid collision with Home/End, conforms to Android 3.0+) Change-Id: Ib138afa492df8d0c1975415e8b5334c8778ccc90 --- gui/action.cpp | 9 ++-- gui/hardwarekeyboard.cpp | 78 ++++++++++++++++++---------------- gui/input.cpp | 106 +++++++++++++++++++++++++++-------------------- gui/keyboard.cpp | 105 ++++++++++++++++++++++++++++++++++++---------- gui/objects.hpp | 44 ++++++++++---------- gui/pages.cpp | 30 +++++--------- gui/pages.hpp | 6 +-- 7 files changed, 226 insertions(+), 152 deletions(-) diff --git a/gui/action.cpp b/gui/action.cpp index 9f746c348..656c687b9 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -292,12 +292,9 @@ int GUIAction::NotifyTouch(TOUCH_STATE state __unused, int x __unused, int y __u int GUIAction::NotifyKey(int key, bool down) { - if (mKeys.empty()) - return 0; - std::map::iterator itr = mKeys.find(key); if(itr == mKeys.end()) - return 0; + return 1; bool prevState = itr->second; itr->second = down; @@ -312,7 +309,7 @@ int GUIAction::NotifyKey(int key, bool down) } else if(down) { for(itr = mKeys.begin(); itr != mKeys.end(); ++itr) { if(!itr->second) - return 0; + return 1; } // Passed, all req buttons are pressed, reset them and consume release events @@ -1727,7 +1724,7 @@ int GUIAction::twcmd(std::string arg) int GUIAction::getKeyByName(std::string key) { - if (key == "home") return KEY_HOME; + if (key == "home") return KEY_HOMEPAGE; // note: KEY_HOME is cursor movement (like KEY_END) else if (key == "menu") return KEY_MENU; else if (key == "back") return KEY_BACK; else if (key == "search") return KEY_SEARCH; diff --git a/gui/hardwarekeyboard.cpp b/gui/hardwarekeyboard.cpp index 1f34c5e1d..9ca607c0d 100644 --- a/gui/hardwarekeyboard.cpp +++ b/gui/hardwarekeyboard.cpp @@ -35,31 +35,14 @@ HardwareKeyboard::~HardwareKeyboard() static int TranslateKeyCode(int key_code) { switch (key_code) { - case KEY_HOMEPAGE: // Home key on Asus Transformer hardware keyboard - return KEY_HOME; case KEY_SLEEP: // Lock key on Asus Transformer hardware keyboard return KEY_POWER; } return key_code; } -int HardwareKeyboard::KeyDown(int key_code) +static int KeyCodeToChar(int key_code, bool shiftkey, bool ctrlkey) { -#ifdef _EVENT_LOGGING - LOGE("HardwareKeyboard::KeyDown %i\n", key_code); -#endif - key_code = TranslateKeyCode(key_code); - - // determine if any Shift key is held down - bool shiftkey = false; - std::set::iterator it = mPressedKeys.find(KEY_LEFTSHIFT); - if (it == mPressedKeys.end()) - it = mPressedKeys.find(KEY_RIGHTSHIFT); - if (it != mPressedKeys.end()) - shiftkey = true; - - mPressedKeys.insert(key_code); - int keyboard = -1; switch (key_code) { @@ -285,6 +268,9 @@ int HardwareKeyboard::KeyDown(int key_code) case KEY_BACKSPACE: keyboard = KEYBOARD_BACKSPACE; break; + case KEY_TAB: + keyboard = KEYBOARD_TAB; + break; case KEY_ENTER: keyboard = KEYBOARD_ACTION; break; @@ -354,18 +340,6 @@ int HardwareKeyboard::KeyDown(int key_code) else keyboard = '\''; break; - case KEY_UP: // Up arrow - keyboard = KEYBOARD_ARROW_UP; - break; - case KEY_DOWN: // Down arrow - keyboard = KEYBOARD_ARROW_DOWN; - break; - case KEY_LEFT: // Left arrow - keyboard = KEYBOARD_ARROW_LEFT; - break; - case KEY_RIGHT: // Right arrow - keyboard = KEYBOARD_ARROW_RIGHT; - break; #ifdef _EVENT_LOGGING default: @@ -373,14 +347,44 @@ int HardwareKeyboard::KeyDown(int key_code) break; #endif } - if (keyboard != -1) { - mLastKeyChar = keyboard; - // NotifyKeyboard means: "report character to input widget". KEYBOARD_* codes are special, others are ASCII chars. - if (!PageManager::NotifyKeyboard(keyboard)) + if (ctrlkey) + { + if (keyboard >= 96) + keyboard -= 96; + else + keyboard = -1; + } + return keyboard; +} + +bool HardwareKeyboard::IsKeyDown(int key_code) +{ + std::set::iterator it = mPressedKeys.find(key_code); + return (it != mPressedKeys.end()); +} + +int HardwareKeyboard::KeyDown(int key_code) +{ +#ifdef _EVENT_LOGGING + LOGE("HardwareKeyboard::KeyDown %i\n", key_code); +#endif + key_code = TranslateKeyCode(key_code); + mPressedKeys.insert(key_code); + + bool ctrlkey = IsKeyDown(KEY_LEFTCTRL) || IsKeyDown(KEY_RIGHTCTRL); + bool shiftkey = IsKeyDown(KEY_LEFTSHIFT) || IsKeyDown(KEY_RIGHTSHIFT); + + int ch = KeyCodeToChar(key_code, shiftkey, ctrlkey); + + if (ch != -1) { + mLastKeyChar = ch; + if (!PageManager::NotifyCharInput(ch)) return 1; // Return 1 to enable key repeat } else { mLastKeyChar = 0; - PageManager::NotifyKey(key_code, true); + mLastKey = key_code; + if (!PageManager::NotifyKey(key_code, true)) + return 1; // Return 1 to enable key repeat } return 0; } @@ -405,7 +409,9 @@ int HardwareKeyboard::KeyRepeat() LOGE("HardwareKeyboard::KeyRepeat: %i\n", mLastKeyChar); #endif if (mLastKeyChar) - PageManager::NotifyKeyboard(mLastKeyChar); + PageManager::NotifyCharInput(mLastKeyChar); + else if (mLastKey) + PageManager::NotifyKey(mLastKey, true); return 0; } diff --git a/gui/input.cpp b/gui/input.cpp index ca27ea812..68bd163b9 100644 --- a/gui/input.cpp +++ b/gui/input.cpp @@ -469,7 +469,7 @@ int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y) if (GetSelection(x, y) >= 0) { // When changing focus, we don't scroll or change the cursor location PageManager::SetKeyBoardFocus(0); - PageManager::NotifyKeyboard(0); + PageManager::NotifyCharInput(0); SetInputFocus(1); DrawCursor = true; mRendered = false; @@ -561,7 +561,66 @@ int GUIInput::NotifyVarChange(const std::string& varName, const std::string& val return 0; } -int GUIInput::NotifyKeyboard(int key) +int GUIInput::NotifyKey(int key, bool down) +{ + if (!HasInputFocus || !down) + return 1; + + string variableValue; + switch (key) + { + case KEY_LEFT: + if (mCursorLocation == 0 && skipChars == 0) + return 0; // we're already at the beginning + if (mCursorLocation == -1) { + DataManager::GetValue(mVariable, variableValue); + if (variableValue.size() == 0) + return 0; + mCursorLocation = variableValue.size() - skipChars - 1; + } else if (mCursorLocation == 0) { + skipChars--; + HandleTextLocation(-1002); + } else { + mCursorLocation--; + HandleTextLocation(-1002); + } + mRendered = false; + return 0; + + case KEY_RIGHT: + if (mCursorLocation == -1) + return 0; // we're already at the end + mCursorLocation++; + DataManager::GetValue(mVariable, variableValue); + if (variableValue.size() <= mCursorLocation + skipChars) + mCursorLocation = -1; + HandleTextLocation(-1001); + mRendered = false; + return 0; + + case KEY_HOME: + case KEY_UP: + DataManager::GetValue(mVariable, variableValue); + if (variableValue.size() == 0) + return 0; + mCursorLocation = 0; + skipChars = 0; + mRendered = false; + HandleTextLocation(-1002); + return 0; + + case KEY_END: + case KEY_DOWN: + mCursorLocation = -1; + mRendered = false; + HandleTextLocation(-1003); + return 0; + } + + return 1; +} + +int GUIInput::NotifyCharInput(int key) { string variableValue; @@ -617,48 +676,7 @@ int GUIInput::NotifyKeyboard(int key) isLocalChange = false; mRendered = false; return 0; - } else if (key == KEYBOARD_ARROW_LEFT) { - if (mCursorLocation == 0 && skipChars == 0) - return 0; // we're already at the beginning - if (mCursorLocation == -1) { - DataManager::GetValue(mVariable, variableValue); - if (variableValue.size() == 0) - return 0; - mCursorLocation = variableValue.size() - skipChars - 1; - } else if (mCursorLocation == 0) { - skipChars--; - HandleTextLocation(-1002); - } else { - mCursorLocation--; - HandleTextLocation(-1002); - } - mRendered = false; - return 0; - } else if (key == KEYBOARD_ARROW_RIGHT) { - if (mCursorLocation == -1) - return 0; // we're already at the end - mCursorLocation++; - DataManager::GetValue(mVariable, variableValue); - if (variableValue.size() <= mCursorLocation + skipChars) - mCursorLocation = -1; - HandleTextLocation(-1001); - mRendered = false; - return 0; - } else if (key == KEYBOARD_HOME || key == KEYBOARD_ARROW_UP) { - DataManager::GetValue(mVariable, variableValue); - if (variableValue.size() == 0) - return 0; - mCursorLocation = 0; - skipChars = 0; - mRendered = false; - HandleTextLocation(-1002); - return 0; - } else if (key == KEYBOARD_END || key == KEYBOARD_ARROW_DOWN) { - mCursorLocation = -1; - mRendered = false; - HandleTextLocation(-1003); - return 0; - } else if (key < KEYBOARD_SPECIAL_KEYS && key > 0) { + } else if (key >= 32) { // Regular key if (HasAllowed && AllowedList.find((char)key) == string::npos) { return 0; diff --git a/gui/keyboard.cpp b/gui/keyboard.cpp index e55fb1b66..3b8fdc9ae 100644 --- a/gui/keyboard.cpp +++ b/gui/keyboard.cpp @@ -16,6 +16,7 @@ along with TWRP. If not, see . */ +#include #include #include #include "../data.hpp" @@ -31,13 +32,15 @@ extern "C" { #include "rapidxml.hpp" #include "objects.hpp" +bool GUIKeyboard::CtrlActive = false; + GUIKeyboard::GUIKeyboard(xml_node<>* node) : GUIObject(node) { int layoutindex, rowindex, keyindex, Xindex, Yindex, keyHeight = 0, keyWidth = 0; currentKey = NULL; highlightRenderCount = 0; - hasHighlight = hasCapsHighlight = false; + hasHighlight = hasCapsHighlight = hasCtrlHighlight = false; char resource[10], layout[8], row[5], key[6], longpress[7]; xml_attribute<>* attr; xml_node<>* child; @@ -58,6 +61,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) mHighlightColor = LoadAttrColor(FindNode(node, "highlight"), "color", &hasHighlight); mCapsHighlightColor = LoadAttrColor(FindNode(node, "capshighlight"), "color", &hasCapsHighlight); + mCtrlHighlightColor = LoadAttrColor(FindNode(node, "ctrlhighlight"), "color", &hasCtrlHighlight); child = FindNode(node, "keymargin"); mKeyMarginX = LoadAttrIntScaleX(child, "x", 0); @@ -228,10 +232,11 @@ int GUIKeyboard::ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWid keychar = *ptr; } else if (*ptr == 'c') { // This is an ASCII character code: "c:{number}" keychar = atoi(ptr + 2); + } else if (*ptr == 'k') { // This is a Linux keycode from input.h: "k:{number}" + keychar = -atoi(ptr + 2); } else if (*ptr == 'l') { // This is a different layout: "layout{number}" - keychar = KEYBOARD_LAYOUT; key.layout = atoi(ptr + 6); - } else if (*ptr == 'a') { // This is an action: "action" + } else if (*ptr == 'a') { // This is an action: "action" (the Enter key) keychar = KEYBOARD_ACTION; } else return -1; @@ -273,8 +278,8 @@ void GUIKeyboard::LoadKeyLabels(xml_node<>* parent, int layout) void GUIKeyboard::DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH) { - unsigned char keychar = key.key; - if (!keychar) + int keychar = key.key; + if (!keychar && !key.layout) return; // key background @@ -291,7 +296,13 @@ void GUIKeyboard::DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH) string labelText; ImageResource* labelImage = NULL; if (keychar > 32 && keychar < 127) { + // TODO: this will eventually need UTF-8 support labelText = (char) keychar; + if (CtrlActive) { + int ctrlchar = KeyCharToCtrlChar(keychar); + if (ctrlchar != keychar) + labelText = std::string("^") + (char)(ctrlchar + 64); + } gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha); } else { @@ -343,6 +354,15 @@ void GUIKeyboard::DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH) } } +int GUIKeyboard::KeyCharToCtrlChar(int key) +{ + // convert upper and lower case to ctrl chars + // Ctrl+A to Ctrl+_ (we don't support entering null bytes) + if (key >= 65 && key <= 127 && key != 96) + return key & 0x1f; + return key; // pass on others (already ctrl chars, numbers, etc.) unchanged +} + int GUIKeyboard::Render(void) { if (!isConditionTrue()) @@ -385,11 +405,17 @@ int GUIKeyboard::Render(void) DrawKey(key, keyX, keyY, keyW, keyH); // Draw highlight for capslock - if (hasCapsHighlight && lay.is_caps && CapsLockOn && (int)key.key == KEYBOARD_LAYOUT && key.layout == lay.revert_layout) { + if (hasCapsHighlight && lay.is_caps && CapsLockOn && key.layout > 0 && key.layout == lay.revert_layout) { gr_color(mCapsHighlightColor.red, mCapsHighlightColor.green, mCapsHighlightColor.blue, mCapsHighlightColor.alpha); gr_fill(keyX, keyY, keyW, keyH); } + // Draw highlight for control + if (hasCtrlHighlight && key.key == -KEY_LEFTCTRL && CtrlActive) { + gr_color(mCtrlHighlightColor.red, mCtrlHighlightColor.green, mCtrlHighlightColor.blue, mCtrlHighlightColor.alpha); + gr_fill(keyX, keyY, keyW, keyH); + } + // Highlight current key if (hasHighlight && &key == currentKey && highlightRenderCount != 0) { gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha); @@ -444,7 +470,7 @@ GUIKeyboard::Key* GUIKeyboard::HitTestKey(int x, int y) int x1 = 0; for (col = 0; col < MAX_KEYBOARD_KEYS; ++col) { Key& key = lay.keys[row][col]; - if (x1 <= relx && relx < key.end_x && key.key != 0) { + if (x1 <= relx && relx < key.end_x && (key.key != 0 || key.layout != 0)) { // This is the key that was pressed! return &key; } @@ -476,19 +502,20 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) break; case TOUCH_RELEASE: + // TODO: we might want to notify of key releases here if (x < startX - (mRenderW * 0.5)) { if (highlightRenderCount != 0) { highlightRenderCount = 0; mRendered = false; } - PageManager::NotifyKeyboard(KEYBOARD_SWIPE_LEFT); + PageManager::NotifyCharInput(KEYBOARD_SWIPE_LEFT); return 0; } else if (x > startX + (mRenderW * 0.5)) { if (highlightRenderCount != 0) { highlightRenderCount = 0; mRendered = false; } - PageManager::NotifyKeyboard(KEYBOARD_SWIPE_RIGHT); + PageManager::NotifyCharInput(KEYBOARD_SWIPE_RIGHT); return 0; } // fall through @@ -520,10 +547,11 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) return 0; } else { Key& key = *currentKey; + bool repeatKey = false; Layout& lay = layouts[currentLayout - 1]; if (state == TOUCH_RELEASE && was_held == 0) { DataManager::Vibrate("tw_keyboard_vibrate"); - if ((int)key.key == KEYBOARD_LAYOUT) { + if (key.layout > 0) { // Switch layouts if (lay.is_caps && key.layout == lay.revert_layout && !CapsLockOn) { CapsLockOn = true; // Set the caps lock @@ -532,14 +560,30 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) currentLayout = key.layout; } mRendered = false; - } else if ((int)key.key == KEYBOARD_ACTION) { + } else if (key.key == KEYBOARD_ACTION) { // Action highlightRenderCount = 0; // Send action notification - PageManager::NotifyKeyboard(key.key); - } else if ((int)key.key < KEYBOARD_SPECIAL_KEYS && (int)key.key > 0) { + PageManager::NotifyCharInput(key.key); + } else if (key.key == -KEY_LEFTCTRL) { + CtrlActive = !CtrlActive; // toggle Control key state + mRendered = false; // render Ctrl key highlight + } else if (key.key != 0) { // Regular key - PageManager::NotifyKeyboard(key.key); + if (key.key > 0) { + // ASCII code or character + int keycode = key.key; + if (CtrlActive) { + CtrlActive = false; + mRendered = false; + keycode = KeyCharToCtrlChar(key.key); + } + PageManager::NotifyCharInput(keycode); + } else { + // Linux key code + PageManager::NotifyKey(-key.key, true); + PageManager::NotifyKey(-key.key, false); + } if (!CapsLockOn && lay.is_caps) { // caps lock was not set, change layouts currentLayout = lay.revert_layout; @@ -548,19 +592,32 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) } } else if (state == TOUCH_HOLD) { was_held = 1; - if ((int)key.key == KEYBOARD_BACKSPACE) { - // Repeat backspace - PageManager::NotifyKeyboard(key.key); - } else if ((int)key.longpresskey < KEYBOARD_SPECIAL_KEYS && (int)key.longpresskey > 0) { + if (key.longpresskey > 0) { // Long Press Key DataManager::Vibrate("tw_keyboard_vibrate"); - PageManager::NotifyKeyboard(key.longpresskey); + PageManager::NotifyCharInput(key.longpresskey); } + else + repeatKey = true; } else if (state == TOUCH_REPEAT) { was_held = 1; - if ((int)key.key == KEYBOARD_BACKSPACE) { + repeatKey = true; + } + if (repeatKey) { + if (key.key == KEYBOARD_BACKSPACE) { // Repeat backspace - PageManager::NotifyKeyboard(key.key); + PageManager::NotifyCharInput(key.key); + } + switch (key.key) + { + // Repeat arrows + case -KEY_LEFT: + case -KEY_RIGHT: + case -KEY_UP: + case -KEY_DOWN: + PageManager::NotifyKey(-key.key, true); + PageManager::NotifyKey(-key.key, false); + break; } } } @@ -569,3 +626,9 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) return 0; } + +void GUIKeyboard::SetPageFocus(int inFocus) +{ + if (inFocus) + CtrlActive = false; +} diff --git a/gui/objects.hpp b/gui/objects.hpp index 4e7ea29f4..5e0960777 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -103,10 +103,8 @@ public: // Return 0 on success (and consume key), >0 to pass key to next handler, and <0 on error virtual int NotifyKey(int key __unused, bool down __unused) { return 1; } - // GetRenderPos - Returns the current position of the object virtual int GetActionPos(int& x, int& y, int& w, int& h) { x = mActionX; y = mActionY; w = mActionW; h = mActionH; return 0; } - // SetRenderPos - Update the position of the object // Return 0 on success, <0 on error virtual int SetActionPos(int x, int y, int w = 0, int h = 0); @@ -166,9 +164,9 @@ public: virtual ~InputObject() {} public: - // NotifyKeyboard - Notify of keyboard input + // NotifyCharInput - Notify of character input (usually from the onscreen or hardware keyboard) // Return 0 on success (and consume key), >0 to pass key to next handler, and <0 on error - virtual int NotifyKeyboard(int key __unused) { return 1; } + virtual int NotifyCharInput(int ch __unused) { return 1; } virtual int SetInputFocus(int focus) { HasInputFocus = focus; return 1; } @@ -856,18 +854,13 @@ protected: int sUpdate; }; -#define KEYBOARD_ACTION 253 -#define KEYBOARD_LAYOUT 254 -#define KEYBOARD_SWIPE_LEFT 252 -#define KEYBOARD_SWIPE_RIGHT 251 -#define KEYBOARD_ARROW_LEFT 250 -#define KEYBOARD_ARROW_RIGHT 249 -#define KEYBOARD_HOME 248 -#define KEYBOARD_END 247 -#define KEYBOARD_ARROW_UP 246 -#define KEYBOARD_ARROW_DOWN 245 -#define KEYBOARD_SPECIAL_KEYS 245 -#define KEYBOARD_BACKSPACE 8 +// these are ASCII codes reported via NotifyCharInput +// other special keys (arrows etc.) are reported via NotifyKey +#define KEYBOARD_ACTION 13 // CR +#define KEYBOARD_BACKSPACE 8 // Backspace +#define KEYBOARD_TAB 9 // Tab +#define KEYBOARD_SWIPE_LEFT 21 // Ctrl+U to delete line, same as in readline (used by shell etc.) +#define KEYBOARD_SWIPE_RIGHT 11 // Ctrl+K, same as in readline class GUIKeyboard : public GUIObject, public RenderObject, public ActionObject { @@ -880,18 +873,20 @@ public: virtual int Update(void); virtual int NotifyTouch(TOUCH_STATE state, int x, int y); virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + virtual void SetPageFocus(int inFocus); protected: struct Key { - unsigned char key; // ASCII code or one of the special KEYBOARD_* codes above - unsigned char longpresskey; + int key; // positive: ASCII/Unicode code; negative: Linux key code (KEY_*) + int longpresskey; int end_x; int layout; }; int ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWidth, bool longpress); void LoadKeyLabels(xml_node<>* parent, int layout); void DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH); + int KeyCharToCtrlChar(int key); enum { MAX_KEYBOARD_LAYOUTS = 5, @@ -901,7 +896,7 @@ protected: struct Layout { ImageResource* keyboardImg; - struct Key keys[MAX_KEYBOARD_ROWS][MAX_KEYBOARD_KEYS]; + Key keys[MAX_KEYBOARD_ROWS][MAX_KEYBOARD_KEYS]; int row_end_y[MAX_KEYBOARD_ROWS]; bool is_caps; int revert_layout; @@ -910,7 +905,7 @@ protected: struct KeyLabel { - unsigned char key; // same as in struct Key + int key; // same as in struct Key int layout_from; // 1-based; 0 for labels that apply to all layouts int layout_to; // same as Key.layout string text; // key label text @@ -925,11 +920,13 @@ protected: std::string mVariable; int currentLayout; bool CapsLockOn; + static bool CtrlActive; // all keyboards share a common Control key state so that the Control key can be on a separate keyboard instance int highlightRenderCount; Key* currentKey; - bool hasHighlight, hasCapsHighlight; + bool hasHighlight, hasCapsHighlight, hasCtrlHighlight; COLOR mHighlightColor; COLOR mCapsHighlightColor; + COLOR mCtrlHighlightColor; COLOR mFontColor; // for centered key labels COLOR mFontColorSmall; // for centered key labels FontResource* mFont; // for main key labels @@ -966,7 +963,8 @@ public: // Return 0 on success, >0 to ignore remainder of touch, and <0 on error virtual int NotifyTouch(TOUCH_STATE state, int x, int y); - virtual int NotifyKeyboard(int key); + virtual int NotifyKey(int key, bool down); + virtual int NotifyCharInput(int ch); protected: virtual int GetSelection(int x, int y); @@ -1024,7 +1022,9 @@ public: // called by multi-key actions to suppress key-release notifications void ConsumeKeyRelease(int key); + bool IsKeyDown(int key_code); private: + int mLastKey; int mLastKeyChar; std::set mPressedKeys; }; diff --git a/gui/pages.cpp b/gui/pages.cpp index 4a65c69e4..c097c39bd 100644 --- a/gui/pages.cpp +++ b/gui/pages.cpp @@ -584,15 +584,13 @@ int Page::NotifyKey(int key, bool down) { std::vector::reverse_iterator iter; - // Don't try to handle a lack of handlers - if (mActions.size() == 0) - return 1; - int ret = 1; // We work backwards, from top-most element to bottom-most element for (iter = mActions.rbegin(); iter != mActions.rend(); iter++) { ret = (*iter)->NotifyKey(key, down); + if (ret == 0) + return 0; if (ret < 0) { LOGERR("An action handler has returned an error\n"); ret = 1; @@ -601,22 +599,18 @@ int Page::NotifyKey(int key, bool down) return ret; } -int Page::NotifyKeyboard(int key) +int Page::NotifyCharInput(int ch) { std::vector::reverse_iterator iter; - // Don't try to handle a lack of handlers - if (mInputs.size() == 0) - return 1; - // We work backwards, from top-most element to bottom-most element for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++) { - int ret = (*iter)->NotifyKeyboard(key); + int ret = (*iter)->NotifyCharInput(ch); if (ret == 0) return 0; else if (ret < 0) - LOGERR("A keyboard handler has returned an error"); + LOGERR("A char input handler has returned an error"); } return 1; } @@ -625,10 +619,6 @@ int Page::SetKeyBoardFocus(int inFocus) { std::vector::reverse_iterator iter; - // Don't try to handle a lack of handlers - if (mInputs.size() == 0) - return 1; - // We work backwards, from top-most element to bottom-most element for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++) { @@ -1155,12 +1145,12 @@ int PageSet::NotifyKey(int key, bool down) return (mCurrentPage ? mCurrentPage->NotifyKey(key, down) : -1); } -int PageSet::NotifyKeyboard(int key) +int PageSet::NotifyCharInput(int ch) { if (!mOverlays.empty()) - return mOverlays.back()->NotifyKeyboard(key); + return mOverlays.back()->NotifyCharInput(ch); - return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1); + return (mCurrentPage ? mCurrentPage->NotifyCharInput(ch) : -1); } int PageSet::SetKeyBoardFocus(int inFocus) @@ -1654,9 +1644,9 @@ int PageManager::NotifyKey(int key, bool down) return (mCurrentSet ? mCurrentSet->NotifyKey(key, down) : -1); } -int PageManager::NotifyKeyboard(int key) +int PageManager::NotifyCharInput(int ch) { - return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1); + return (mCurrentSet ? mCurrentSet->NotifyCharInput(ch) : -1); } int PageManager::SetKeyBoardFocus(int inFocus) diff --git a/gui/pages.hpp b/gui/pages.hpp index e7ad55e94..87e1fb527 100644 --- a/gui/pages.hpp +++ b/gui/pages.hpp @@ -64,7 +64,7 @@ public: virtual int Update(void); virtual int NotifyTouch(TOUCH_STATE state, int x, int y); virtual int NotifyKey(int key, bool down); - virtual int NotifyKeyboard(int key); + virtual int NotifyCharInput(int ch); virtual int SetKeyBoardFocus(int inFocus); virtual int NotifyVarChange(std::string varName, std::string value); virtual void SetPageFocus(int inFocus); @@ -108,7 +108,7 @@ public: int Update(void); int NotifyTouch(TOUCH_STATE state, int x, int y); int NotifyKey(int key, bool down); - int NotifyKeyboard(int key); + int NotifyCharInput(int ch); int SetKeyBoardFocus(int inFocus); int NotifyVarChange(std::string varName, std::string value); @@ -155,7 +155,7 @@ public: static int Update(void); static int NotifyTouch(TOUCH_STATE state, int x, int y); static int NotifyKey(int key, bool down); - static int NotifyKeyboard(int key); + static int NotifyCharInput(int ch); static int SetKeyBoardFocus(int inFocus); static int NotifyVarChange(std::string varName, std::string value); -- cgit v1.2.3