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
This commit is contained in:
+3
-6
@@ -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;
|
||||
|
||||
+42
-36
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+62
-44
@@ -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;
|
||||
|
||||
+84
-21
@@ -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;
|
||||
}
|
||||
|
||||
+22
-22
@@ -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;
|
||||
};
|
||||
|
||||
+10
-20
@@ -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)
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user