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
This commit is contained in:
126
gui/keyboard.cpp
126
gui/keyboard.cpp
@@ -44,11 +44,15 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node)
|
||||
xml_node<>* keylayout;
|
||||
xml_node<>* keyrow;
|
||||
|
||||
for (layoutindex=0; layoutindex<MAX_KEYBOARD_LAYOUTS; layoutindex++)
|
||||
keyboardImg[layoutindex] = NULL;
|
||||
for (layoutindex=0; layoutindex<MAX_KEYBOARD_LAYOUTS; layoutindex++) {
|
||||
layouts[layoutindex].keyboardImg = NULL;
|
||||
memset(layouts[layoutindex].keys, 0, sizeof(Layout::keys));
|
||||
memset(layouts[layoutindex].row_end_y, 0, sizeof(Layout::row_end_y));
|
||||
}
|
||||
|
||||
mRendered = false;
|
||||
currentLayout = 1;
|
||||
CapsLockOn = false;
|
||||
KeyboardHeight = KeyboardWidth = 0;
|
||||
|
||||
if (!node) return;
|
||||
@@ -56,6 +60,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* 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<MAX_KEYBOARD_ROWS; indexy++) {
|
||||
for (int indexx=0; indexx<MAX_KEYBOARD_KEYS; indexx++) {
|
||||
if ((int)keyboard_keys[currentLayout - 1][indexy][indexx].key == KEYBOARD_LAYOUT && (int)keyboard_keys[currentLayout - 1][indexy][indexx].layout == caps_tracking[currentLayout - 1].revert_layout) {
|
||||
if ((int)lay.keys[indexy][indexx].key == KEYBOARD_LAYOUT && (int)lay.keys[indexy][indexx].layout == lay.revert_layout) {
|
||||
int boxheight, boxwidth, x;
|
||||
if (indexy == 0)
|
||||
boxheight = row_heights[currentLayout - 1][indexy];
|
||||
boxheight = lay.row_end_y[indexy];
|
||||
else
|
||||
boxheight = row_heights[currentLayout - 1][indexy] - row_heights[currentLayout - 1][indexy - 1];
|
||||
boxheight = lay.row_end_y[indexy] - lay.row_end_y[indexy - 1];
|
||||
if (indexx == 0) {
|
||||
x = mRenderX;
|
||||
boxwidth = keyboard_keys[currentLayout - 1][indexy][indexx].end_x;
|
||||
boxwidth = lay.keys[indexy][indexx].end_x;
|
||||
} else {
|
||||
x = mRenderX + keyboard_keys[currentLayout - 1][indexy][indexx - 1].end_x;
|
||||
boxwidth = keyboard_keys[currentLayout - 1][indexy][indexx].end_x - keyboard_keys[currentLayout - 1][indexy][indexx - 1].end_x;
|
||||
x = mRenderX + lay.keys[indexy][indexx - 1].end_x;
|
||||
boxwidth = lay.keys[indexy][indexx].end_x - lay.keys[indexy][indexx - 1].end_x;
|
||||
}
|
||||
gr_fill(x, mRenderY + row_heights[currentLayout - 1][indexy - 1], boxwidth, boxheight);
|
||||
gr_fill(x, mRenderY + lay.row_end_y[indexy - 1], boxwidth, boxheight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,24 +262,24 @@ int GUIKeyboard::Render(void)
|
||||
if (hasHighlight && highlightRenderCount != 0) {
|
||||
int boxheight, boxwidth, x;
|
||||
if (rowY == 0)
|
||||
boxheight = row_heights[currentLayout - 1][rowY];
|
||||
boxheight = lay.row_end_y[rowY];
|
||||
else
|
||||
boxheight = row_heights[currentLayout - 1][rowY] - row_heights[currentLayout - 1][rowY - 1];
|
||||
boxheight = lay.row_end_y[rowY] - lay.row_end_y[rowY - 1];
|
||||
if (colX == 0) {
|
||||
x = mRenderX;
|
||||
boxwidth = keyboard_keys[currentLayout - 1][rowY][colX].end_x;
|
||||
boxwidth = lay.keys[rowY][colX].end_x;
|
||||
} else {
|
||||
x = mRenderX + keyboard_keys[currentLayout - 1][rowY][colX - 1].end_x;
|
||||
boxwidth = keyboard_keys[currentLayout - 1][rowY][colX].end_x - keyboard_keys[currentLayout - 1][rowY][colX - 1].end_x;
|
||||
x = mRenderX + lay.keys[rowY][colX - 1].end_x;
|
||||
boxwidth = lay.keys[rowY][colX].end_x - lay.keys[rowY][colX - 1].end_x;
|
||||
}
|
||||
gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
|
||||
gr_fill(x, mRenderY + row_heights[currentLayout - 1][rowY - 1], boxwidth, boxheight);
|
||||
gr_fill(x, mRenderY + lay.row_end_y[rowY - 1], boxwidth, boxheight);
|
||||
if (highlightRenderCount > 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user