From d86f49d3f7bc4e9ec6c3ddffa4723ef624eb66b2 Mon Sep 17 00:00:00 2001 From: that Date: Sun, 15 Mar 2015 00:56:57 +0100 Subject: gui: keyboard: introduce struct Layout and simplify caps handling Also minor cleanups: - move array limits from #defines to a protected enum - zero fill layouts in ctor Change-Id: I8fe0f8465ebc646ad3bf3cc3f8490dbdd384f43d --- gui/keyboard.cpp | 126 +++++++++++++++++++++++++------------------------------ gui/objects.hpp | 23 +++++----- 2 files changed, 71 insertions(+), 78 deletions(-) diff --git a/gui/keyboard.cpp b/gui/keyboard.cpp index 306422f30..914c944f1 100644 --- a/gui/keyboard.cpp +++ b/gui/keyboard.cpp @@ -44,11 +44,15 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) xml_node<>* keylayout; xml_node<>* keyrow; - for (layoutindex=0; layoutindex* node) mHighlightColor = LoadAttrColor(FindNode(node, "highlight"), "color", &hasHighlight); mCapsHighlightColor = LoadAttrColor(FindNode(node, "capshighlight"), "color", &hasCapsHighlight); + // compatibility ugliness: resources should be specified in the layouts themselves instead // Load the images for the different layouts child = FindNode(node, "layout"); if (child) @@ -64,7 +69,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) strcpy(resource, "resource1"); attr = child->first_attribute(resource); while (attr && layoutindex < (MAX_KEYBOARD_LAYOUTS + 1)) { - keyboardImg[layoutindex - 1] = LoadAttrImage(child, resource); + layouts[layoutindex - 1].keyboardImg = LoadAttrImage(child, resource); layoutindex++; resource[8] = (char)(layoutindex + 48); @@ -73,10 +78,10 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) } // Check the first image to get height and width - if (keyboardImg[0] && keyboardImg[0]->GetResource()) + if (layouts[0].keyboardImg && layouts[0].keyboardImg->GetResource()) { - KeyboardWidth = keyboardImg[0]->GetWidth(); - KeyboardHeight = keyboardImg[0]->GetHeight(); + KeyboardWidth = layouts[0].keyboardImg->GetWidth(); + KeyboardHeight = layouts[0].keyboardImg->GetHeight(); } // Load all of the layout maps @@ -90,29 +95,15 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) return; } + Layout& lay = layouts[layoutindex - 1]; + child = keylayout->first_node("keysize"); - if (child) { - attr = child->first_attribute("height"); - if (attr) - keyHeight = scale_theme_y(atoi(attr->value())); - else - keyHeight = 0; - attr = child->first_attribute("width"); - if (attr) - keyWidth = scale_theme_x(atoi(attr->value())); - else - keyWidth = 0; - attr = child->first_attribute("capslock"); - if (attr) - caps_tracking[layoutindex - 1].capslock = atoi(attr->value()); - else - caps_tracking[layoutindex - 1].capslock = 1; - attr = child->first_attribute("revert_layout"); - if (attr) - caps_tracking[layoutindex - 1].revert_layout = atoi(attr->value()); - else - caps_tracking[layoutindex - 1].revert_layout = -1; - } + keyHeight = LoadAttrIntScaleY(child, "height", 0); + keyWidth = LoadAttrIntScaleX(child, "width", 0); + // compatibility ugliness: capslock="0" means that this is the caps layout. Also it has nothing to do with keysize. + lay.is_caps = (LoadAttrInt(child, "capslock", 1) == 0); + // compatibility ugliness: revert_layout has nothing to do with keysize. + lay.revert_layout = LoadAttrInt(child, "revert_layout", -1); rowindex = 1; Yindex = 0; @@ -126,7 +117,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) } Yindex += keyHeight; - row_heights[layoutindex - 1][rowindex - 1] = Yindex; + lay.row_end_y[rowindex - 1] = Yindex; keyindex = 1; Xindex = 0; @@ -146,7 +137,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) return; } - if (ParseKey(keyinfo, keyboard_keys[layoutindex - 1][rowindex - 1][keyindex - 1], Xindex, keyWidth, false)) + if (ParseKey(keyinfo, lay.keys[rowindex - 1][keyindex - 1], Xindex, keyWidth, false)) LOGERR("Invalid key info on layout%i, row%i, key%02i.\n", layoutindex, rowindex, keyindex); @@ -161,7 +152,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node) return; } - if (ParseKey(keyinfo, keyboard_keys[layoutindex - 1][rowindex - 1][keyindex - 1], Xindex, keyWidth, true)) + if (ParseKey(keyinfo, lay.keys[rowindex - 1][keyindex - 1], Xindex, keyWidth, true)) LOGERR("Invalid long press key info on layout%i, row%i, long%02i.\n", layoutindex, rowindex, keyindex); } keyindex++; @@ -239,30 +230,30 @@ int GUIKeyboard::Render(void) return 0; } - int ret = 0; + Layout& lay = layouts[currentLayout - 1]; - if (keyboardImg[currentLayout - 1] && keyboardImg[currentLayout - 1]->GetResource()) - gr_blit(keyboardImg[currentLayout - 1]->GetResource(), 0, 0, KeyboardWidth, KeyboardHeight, mRenderX, mRenderY); + if (lay.keyboardImg && lay.keyboardImg->GetResource()) + gr_blit(lay.keyboardImg->GetResource(), 0, 0, KeyboardWidth, KeyboardHeight, mRenderX, mRenderY); // Draw highlight for capslock - if (hasCapsHighlight && caps_tracking[currentLayout - 1].capslock == 0 && caps_tracking[currentLayout - 1].set_capslock) { - int boxheight, boxwidth, x; + if (hasCapsHighlight && lay.is_caps && CapsLockOn) { gr_color(mCapsHighlightColor.red, mCapsHighlightColor.green, mCapsHighlightColor.blue, mCapsHighlightColor.alpha); for (int indexy=0; indexy 0) highlightRenderCount--; } else mRendered = true; - return ret; + return 0; } int GUIKeyboard::Update(void) @@ -317,10 +308,12 @@ GUIKeyboard::Key* GUIKeyboard::HitTestKey(int x, int y) int rely = y - mRenderY; int relx = x - mRenderX; + Layout& lay = layouts[currentLayout - 1]; + // Find the correct row int row; for (row = 0; row < MAX_KEYBOARD_ROWS; ++row) { - if (row_heights[currentLayout - 1][row] > rely) + if (lay.row_end_y[row] > rely) break; } if (row == MAX_KEYBOARD_ROWS) @@ -330,7 +323,7 @@ GUIKeyboard::Key* GUIKeyboard::HitTestKey(int x, int y) int col; int x1 = 0; for (col = 0; col < MAX_KEYBOARD_KEYS; ++col) { - Key& key = keyboard_keys[currentLayout - 1][row][col]; + Key& key = lay.keys[row][col]; if (x1 <= relx && relx < key.end_x && key.key != 0) { // This is the key that was pressed! rowY = row; @@ -409,26 +402,15 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) return 0; } else { Key& key = *initial_key; + Layout& lay = layouts[currentLayout - 1]; if (state == TOUCH_RELEASE && was_held == 0) { DataManager::Vibrate("tw_keyboard_vibrate"); - if ((int)key.key < KEYBOARD_SPECIAL_KEYS && (int)key.key > 0) { - // Regular key - PageManager::NotifyKeyboard(key.key); - if (caps_tracking[currentLayout - 1].capslock == 0 && !caps_tracking[currentLayout - 1].set_capslock) { - // caps lock was not set, change layouts - currentLayout = caps_tracking[currentLayout - 1].revert_layout; - mRendered = false; - } - } else if ((int)key.key == KEYBOARD_LAYOUT) { + if ((int)key.key == KEYBOARD_LAYOUT) { // Switch layouts - if (caps_tracking[currentLayout - 1].capslock == 0 && key.layout == caps_tracking[currentLayout - 1].revert_layout) { - if (!caps_tracking[currentLayout - 1].set_capslock) { - caps_tracking[currentLayout - 1].set_capslock = 1; // Set the caps lock - } else { - caps_tracking[currentLayout - 1].set_capslock = 0; // Unset the caps lock and change layouts - currentLayout = key.layout; - } + if (lay.is_caps && key.layout == lay.revert_layout && !CapsLockOn) { + CapsLockOn = true; // Set the caps lock } else { + CapsLockOn = false; // Unset the caps lock and change layouts currentLayout = key.layout; } mRendered = false; @@ -437,6 +419,14 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) highlightRenderCount = 0; // Send action notification PageManager::NotifyKeyboard(key.key); + } else if ((int)key.key < KEYBOARD_SPECIAL_KEYS && (int)key.key > 0) { + // Regular key + PageManager::NotifyKeyboard(key.key); + if (!CapsLockOn && lay.is_caps) { + // caps lock was not set, change layouts + currentLayout = lay.revert_layout; + mRendered = false; + } } } else if (state == TOUCH_HOLD) { was_held = 1; diff --git a/gui/objects.hpp b/gui/objects.hpp index 6eeefc267..e70053e3b 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -815,9 +815,6 @@ protected: int sUpdate; }; -#define MAX_KEYBOARD_LAYOUTS 5 -#define MAX_KEYBOARD_ROWS 9 -#define MAX_KEYBOARD_KEYS 20 #define KEYBOARD_ACTION 253 #define KEYBOARD_LAYOUT 254 #define KEYBOARD_SWIPE_LEFT 252 @@ -852,23 +849,29 @@ protected: int layout; }; int ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWidth, bool longpress); - struct capslock_tracking_struct + + enum { + MAX_KEYBOARD_LAYOUTS = 5, + MAX_KEYBOARD_ROWS = 9, + MAX_KEYBOARD_KEYS = 20 + }; + struct Layout { - int capslock; - int set_capslock; + ImageResource* keyboardImg; + struct Key keys[MAX_KEYBOARD_ROWS][MAX_KEYBOARD_KEYS]; + int row_end_y[MAX_KEYBOARD_ROWS]; + bool is_caps; int revert_layout; }; + Layout layouts[MAX_KEYBOARD_LAYOUTS]; // Find key at screen coordinates Key* HitTestKey(int x, int y); - ImageResource* keyboardImg[MAX_KEYBOARD_LAYOUTS]; - struct Key keyboard_keys[MAX_KEYBOARD_LAYOUTS][MAX_KEYBOARD_ROWS][MAX_KEYBOARD_KEYS]; - struct capslock_tracking_struct caps_tracking[MAX_KEYBOARD_LAYOUTS]; bool mRendered; std::string mVariable; int currentLayout; - int row_heights[MAX_KEYBOARD_LAYOUTS][MAX_KEYBOARD_ROWS]; + bool CapsLockOn; unsigned int KeyboardWidth, KeyboardHeight; int rowY, colX, highlightRenderCount; bool hasHighlight, hasCapsHighlight; -- cgit v1.2.3