summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthat <github@that.at>2016-01-05 23:29:30 +0100
committerthat <github@that.at>2016-01-07 22:30:39 +0100
commit8834a0ffc0be61218ab86bf209cb6cd53a18a565 (patch)
tree1229c2413a373d799831f4e9c6ebe087c4c53fb5
parentFix translation spellings (diff)
downloadandroid_bootable_recovery-8834a0ffc0be61218ab86bf209cb6cd53a18a565.tar
android_bootable_recovery-8834a0ffc0be61218ab86bf209cb6cd53a18a565.tar.gz
android_bootable_recovery-8834a0ffc0be61218ab86bf209cb6cd53a18a565.tar.bz2
android_bootable_recovery-8834a0ffc0be61218ab86bf209cb6cd53a18a565.tar.lz
android_bootable_recovery-8834a0ffc0be61218ab86bf209cb6cd53a18a565.tar.xz
android_bootable_recovery-8834a0ffc0be61218ab86bf209cb6cd53a18a565.tar.zst
android_bootable_recovery-8834a0ffc0be61218ab86bf209cb6cd53a18a565.zip
-rw-r--r--gui/action.cpp9
-rw-r--r--gui/hardwarekeyboard.cpp78
-rw-r--r--gui/input.cpp106
-rw-r--r--gui/keyboard.cpp105
-rw-r--r--gui/objects.hpp44
-rw-r--r--gui/pages.cpp30
-rw-r--r--gui/pages.hpp6
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<int, bool>::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<int>::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<int>::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 <http://www.gnu.org/licenses/>.
*/
+#include <linux/input.h>
#include <stdlib.h>
#include <string.h>
#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<int> 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<ActionObject*>::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<InputObject*>::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<InputObject*>::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);