summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gui/keyboard.cpp265
-rw-r--r--gui/objects.hpp5
2 files changed, 120 insertions, 150 deletions
diff --git a/gui/keyboard.cpp b/gui/keyboard.cpp
index 8ab2280a1..f35a5d318 100644
--- a/gui/keyboard.cpp
+++ b/gui/keyboard.cpp
@@ -35,7 +35,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node)
: GUIObject(node)
{
int layoutindex, rowindex, keyindex, Xindex, Yindex, keyHeight = 0, keyWidth = 0;
- rowY = colX = -1;
+ currentKey = NULL;
highlightRenderCount = 0;
hasHighlight = hasCapsHighlight = false;
char resource[10], layout[8], row[5], key[6], longpress[7];
@@ -79,6 +79,7 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node)
child = FindNode(node, "longpress");
mLongpressFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel-longpress"));
mLongpressFontColor = LoadAttrColor(child, "textcolor", COLOR(128,128,128,255));
+ LoadPlacement(child, &longpressOffsetX, &longpressOffsetY);
LoadKeyLabels(node, 0); // load global key labels
@@ -270,6 +271,78 @@ 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)
+ return;
+
+ // key background
+ COLOR& c = (keychar >= 32 && keychar < 127) ? mKeyColorAlphanumeric : mKeyColorOther;
+ gr_color(c.red, c.green, c.blue, c.alpha);
+ keyX += mKeyMarginX;
+ keyY += mKeyMarginY;
+ keyW -= mKeyMarginX * 2;
+ keyH -= mKeyMarginY * 2;
+ gr_fill(keyX, keyY, keyW, keyH);
+
+ // key label
+ FontResource* labelFont = mFont;
+ string labelText;
+ ImageResource* labelImage = NULL;
+ if (keychar > 32 && keychar < 127) {
+ labelText = (char) keychar;
+ gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
+ }
+ else {
+ // search for a special key label
+ for (std::vector<KeyLabel>::iterator it = mKeyLabels.begin(); it != mKeyLabels.end(); ++it) {
+ if (it->layout_from > 0 && it->layout_from != currentLayout)
+ continue; // this label is for another layout
+ if (it->key == key.key && it->layout_to == key.layout)
+ {
+ // found a label
+ labelText = it->text;
+ labelImage = it->image;
+ break;
+ }
+ }
+ labelFont = mSmallFont;
+ gr_color(mFontColorSmall.red, mFontColorSmall.green, mFontColorSmall.blue, mFontColorSmall.alpha);
+ }
+
+ if (labelImage)
+ {
+ int w = labelImage->GetWidth();
+ int h = labelImage->GetHeight();
+ int x = keyX + (keyW - w) / 2;
+ int y = keyY + (keyH - h) / 2;
+ gr_blit(labelImage->GetResource(), 0, 0, w, h, x, y);
+ }
+ else if (!labelText.empty())
+ {
+ void* fontResource = labelFont->GetResource();
+ int textW = gr_measureEx(labelText.c_str(), fontResource);
+ int textH = labelFont->GetHeight();
+ int textX = keyX + (keyW - textW) / 2;
+ int textY = keyY + (keyH - textH) / 2;
+ gr_textEx(textX, textY, labelText.c_str(), fontResource);
+ }
+
+ // longpress key label (only if font is defined)
+ keychar = key.longpresskey;
+ if (keychar > 32 && keychar < 127 && mLongpressFont->GetResource()) {
+ void* fontResource = mLongpressFont->GetResource();
+ gr_color(mLongpressFontColor.red, mLongpressFontColor.green, mLongpressFontColor.blue, mLongpressFontColor.alpha);
+ string text(1, keychar);
+ int textH = mLongpressFont->GetHeight();
+ int textW = gr_measureEx(text.c_str(), fontResource);
+ int textX = keyX + keyW - longpressOffsetX - textW;
+ int textY = keyY + longpressOffsetY;
+ gr_textEx(textX, textY, text.c_str(), fontResource);
+ }
+}
+
int GUIKeyboard::Render(void)
{
if (!isConditionTrue())
@@ -280,159 +353,55 @@ int GUIKeyboard::Render(void)
Layout& lay = layouts[currentLayout - 1];
+ bool drawKeys = false;
if (lay.keyboardImg && lay.keyboardImg->GetResource())
+ // keyboard is image based
gr_blit(lay.keyboardImg->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY);
else {
+ // keyboard is software drawn
+ // fill background
gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, mBackgroundColor.alpha);
gr_fill(mRenderX, mRenderY, mRenderW, mRenderH);
- // draw keys
- int y1 = 0;
- for (int row = 0; row < MAX_KEYBOARD_ROWS; ++row) {
- int rowY = mRenderY + y1;
- int rowH = lay.row_end_y[row] - y1;
- y1 = lay.row_end_y[row];
- int x1 = 0;
- for (int col = 0; col < MAX_KEYBOARD_KEYS; ++col) {
- Key& key = lay.keys[row][col];
- int keyY = rowY;
- int keyH = rowH;
- int keyX = mRenderX + x1;
- int keyW = key.end_x - x1;
- x1 = key.end_x;
-
- unsigned char keychar = key.key;
- if (!keychar)
- continue;
-
- // draw a single key
- // key background
- COLOR& c = (keychar >= 32 && keychar < 127) ? mKeyColorAlphanumeric : mKeyColorOther;
- gr_color(c.red, c.green, c.blue, c.alpha);
- keyX += mKeyMarginX;
- keyY += mKeyMarginY;
- keyW -= mKeyMarginX * 2;
- keyH -= mKeyMarginY * 2;
- gr_fill(keyX, keyY, keyW, keyH);
-
- // key label
- FontResource* labelFont = mFont;
- string labelText;
- ImageResource* labelImage = NULL;
- if (keychar > 32 && keychar < 127) {
- labelText = (char) keychar;
- gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
- }
- else {
- /*
- static const char* shiftLabels[] = {"abc", "ABC", "?123", "~\\{"};
- switch (keychar) {
- case KEYBOARD_LAYOUT:
- labelText = shiftLabels[key.layout - 1];
- break;
- case KEYBOARD_BACKSPACE:
- labelText = "Bksp";
- break;
- case KEYBOARD_ACTION:
- labelText = "Enter";
- break;
- }
- */
- // search for a special key label
- for (std::vector<KeyLabel>::iterator it = mKeyLabels.begin(); it != mKeyLabels.end(); ++it) {
- if (it->layout_from > 0 && it->layout_from != currentLayout)
- continue; // this label is for another layout
- if (it->key == key.key && it->layout_to == key.layout)
- {
- // found a label
- labelText = it->text;
- labelImage = it->image;
- break;
- }
- }
- labelFont = mSmallFont;
- gr_color(mFontColorSmall.red, mFontColorSmall.green, mFontColorSmall.blue, mFontColorSmall.alpha);
- }
-
- if (labelImage)
- {
- int w = labelImage->GetWidth();
- int h = labelImage->GetHeight();
- int x = keyX + (keyW - w) / 2;
- int y = keyY + (keyH - h) / 2;
- gr_blit(labelImage->GetResource(), 0, 0, w, h, x, y);
- }
- else if (!labelText.empty())
- {
- void* fontResource = labelFont->GetResource();
- int textW = gr_measureEx(labelText.c_str(), fontResource);
- int textH = labelFont->GetHeight();
- int textX = keyX + (keyW - textW) / 2;
- int textY = keyY + (keyH - textH) / 2;
- gr_textEx(textX, textY, labelText.c_str(), fontResource);
- }
+ drawKeys = true;
+ }
- // longpress key label (only if font is defined)
- keychar = key.longpresskey;
- if (keychar > 32 && keychar < 127 && mLongpressFont->GetResource()) {
- void* fontResource = mLongpressFont->GetResource();
- gr_color(mLongpressFontColor.red, mLongpressFontColor.green, mLongpressFontColor.blue, mLongpressFontColor.alpha);
- string text(1, keychar);
- int textH = mLongpressFont->GetHeight();
- int textW = gr_measureEx(text.c_str(), fontResource);
- int textX = keyX + keyW - 5 - textW; // TODO: configure these offsets
- int textY = keyY + 0;
- gr_textEx(textX, textY, text.c_str(), fontResource);
- }
+ // draw keys
+ int y1 = 0;
+ for (int row = 0; row < MAX_KEYBOARD_ROWS; ++row) {
+ int rowY = mRenderY + y1;
+ int rowH = lay.row_end_y[row] - y1;
+ y1 = lay.row_end_y[row];
+ int x1 = 0;
+ for (int col = 0; col < MAX_KEYBOARD_KEYS; ++col) {
+ Key& key = lay.keys[row][col];
+ int keyY = rowY;
+ int keyH = rowH;
+ int keyX = mRenderX + x1;
+ int keyW = key.end_x - x1;
+ x1 = key.end_x;
+
+ // Draw key for software drawn keyboard
+ if (drawKeys)
+ 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) {
+ gr_color(mCapsHighlightColor.red, mCapsHighlightColor.green, mCapsHighlightColor.blue, mCapsHighlightColor.alpha);
+ gr_fill(keyX, keyY, keyW, keyH);
}
- }
- }
- // Draw highlight for capslock
- // TODO: integrate with key drawing
- 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)lay.keys[indexy][indexx].key == KEYBOARD_LAYOUT && (int)lay.keys[indexy][indexx].layout == lay.revert_layout) {
- int boxheight, boxwidth, x;
- if (indexy == 0)
- boxheight = lay.row_end_y[indexy];
- else
- boxheight = lay.row_end_y[indexy] - lay.row_end_y[indexy - 1];
- if (indexx == 0) {
- x = mRenderX;
- boxwidth = lay.keys[indexy][indexx].end_x;
- } else {
- 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 + lay.row_end_y[indexy - 1], boxwidth, boxheight);
- }
+ // Highlight current key
+ if (hasHighlight && &key == currentKey && highlightRenderCount != 0) {
+ gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha);
+ gr_fill(keyX, keyY, keyW, keyH);
}
}
}
- // TODO: integrate with key drawing
- if (hasHighlight && highlightRenderCount != 0) {
- int boxheight, boxwidth, x;
- if (rowY == 0)
- boxheight = lay.row_end_y[rowY];
- else
- boxheight = lay.row_end_y[rowY] - lay.row_end_y[rowY - 1];
- if (colX == 0) {
- x = mRenderX;
- boxwidth = lay.keys[rowY][colX].end_x;
- } else {
- 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 + lay.row_end_y[rowY - 1], boxwidth, boxheight);
- if (highlightRenderCount > 0)
- highlightRenderCount--;
- } else
+ if (!hasHighlight || highlightRenderCount == 0)
mRendered = true;
-
+ else if (highlightRenderCount > 0)
+ highlightRenderCount--;
return 0;
}
@@ -477,8 +446,6 @@ GUIKeyboard::Key* GUIKeyboard::HitTestKey(int x, int y)
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;
- colX = col;
return &key;
}
x1 = key.end_x;
@@ -489,7 +456,6 @@ GUIKeyboard::Key* GUIKeyboard::HitTestKey(int x, int y)
int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y)
{
static int was_held = 0, startX = 0;
- static Key* initial_key = 0;
if (!isConditionTrue()) return -1;
@@ -498,8 +464,8 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y)
case TOUCH_START:
was_held = 0;
startX = x;
- initial_key = HitTestKey(x, y);
- if (initial_key)
+ currentKey = HitTestKey(x, y);
+ if (currentKey)
highlightRenderCount = -1;
else
highlightRenderCount = 0;
@@ -528,7 +494,7 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y)
// fall through
case TOUCH_HOLD:
case TOUCH_REPEAT:
- if (!initial_key) {
+ if (!currentKey) {
if (highlightRenderCount != 0) {
highlightRenderCount = 0;
mRendered = false;
@@ -544,15 +510,16 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y)
mRendered = false;
}
- if (HitTestKey(x, y) != initial_key) {
+ if (HitTestKey(x, y) != currentKey) {
// We dragged off of the starting key
+ currentKey = NULL;
if (highlightRenderCount != 0) {
highlightRenderCount = 0;
mRendered = false;
}
return 0;
} else {
- Key& key = *initial_key;
+ Key& key = *currentKey;
Layout& lay = layouts[currentLayout - 1];
if (state == TOUCH_RELEASE && was_held == 0) {
DataManager::Vibrate("tw_keyboard_vibrate");
diff --git a/gui/objects.hpp b/gui/objects.hpp
index 881b39050..be1f9734f 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -853,6 +853,7 @@ protected:
};
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);
enum {
MAX_KEYBOARD_LAYOUTS = 5,
@@ -886,7 +887,8 @@ protected:
std::string mVariable;
int currentLayout;
bool CapsLockOn;
- int rowY, colX, highlightRenderCount;
+ int highlightRenderCount;
+ Key* currentKey;
bool hasHighlight, hasCapsHighlight;
COLOR mHighlightColor;
COLOR mCapsHighlightColor;
@@ -895,6 +897,7 @@ protected:
FontResource* mFont; // for main key labels
FontResource* mSmallFont; // for key labels like "?123"
FontResource* mLongpressFont; // for the small longpress label in the upper right corner
+ int longpressOffsetX, longpressOffsetY; // distance of the longpress label from the key corner
COLOR mLongpressFontColor;
COLOR mBackgroundColor; // keyboard background color
COLOR mKeyColorAlphanumeric; // key background color