[WIP] gui: software drawn keyboard (code only)
Change-Id: I9f05c85f8d43ab012228a78b79220a27876a299d
This commit is contained in:
+163
-12
@@ -53,13 +53,35 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node)
|
||||
mRendered = false;
|
||||
currentLayout = 1;
|
||||
CapsLockOn = false;
|
||||
KeyboardHeight = KeyboardWidth = 0;
|
||||
|
||||
if (!node) return;
|
||||
|
||||
mHighlightColor = LoadAttrColor(FindNode(node, "highlight"), "color", &hasHighlight);
|
||||
mCapsHighlightColor = LoadAttrColor(FindNode(node, "capshighlight"), "color", &hasCapsHighlight);
|
||||
|
||||
child = FindNode(node, "keymargin");
|
||||
mKeyMarginX = LoadAttrIntScaleX(child, "x", 0);
|
||||
mKeyMarginY = LoadAttrIntScaleY(child, "y", 0);
|
||||
|
||||
child = FindNode(node, "background");
|
||||
mBackgroundColor = LoadAttrColor(child, "color", COLOR(32,32,32,255));
|
||||
|
||||
child = FindNode(node, "key-alphanumeric");
|
||||
mFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel"));
|
||||
mFontColor = LoadAttrColor(child, "textcolor", COLOR(255,255,255,255));
|
||||
mKeyColorAlphanumeric = LoadAttrColor(child, "color", COLOR(0,0,0,0));
|
||||
|
||||
child = FindNode(node, "key-other");
|
||||
mSmallFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel-small"));
|
||||
mFontColorSmall = LoadAttrColor(child, "textcolor", COLOR(192,192,192,255));
|
||||
mKeyColorOther = LoadAttrColor(child, "color", COLOR(0,0,0,0));
|
||||
|
||||
child = FindNode(node, "longpress");
|
||||
mLongpressFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel-longpress"));
|
||||
mLongpressFontColor = LoadAttrColor(child, "textcolor", COLOR(128,128,128,255));
|
||||
|
||||
LoadKeyLabels(node, 0); // load global key labels
|
||||
|
||||
// compatibility ugliness: resources should be specified in the layouts themselves instead
|
||||
// Load the images for the different layouts
|
||||
child = FindNode(node, "layout");
|
||||
@@ -80,8 +102,8 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node)
|
||||
// Check the first image to get height and width
|
||||
if (layouts[0].keyboardImg && layouts[0].keyboardImg->GetResource())
|
||||
{
|
||||
KeyboardWidth = layouts[0].keyboardImg->GetWidth();
|
||||
KeyboardHeight = layouts[0].keyboardImg->GetHeight();
|
||||
mRenderW = layouts[0].keyboardImg->GetWidth();
|
||||
mRenderH = layouts[0].keyboardImg->GetHeight();
|
||||
}
|
||||
|
||||
// Load all of the layout maps
|
||||
@@ -95,6 +117,8 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node)
|
||||
return;
|
||||
}
|
||||
|
||||
LoadKeyLabels(keylayout, layoutindex); // load per-layout key labels
|
||||
|
||||
Layout& lay = layouts[layoutindex - 1];
|
||||
|
||||
child = keylayout->first_node("keysize");
|
||||
@@ -170,8 +194,8 @@ GUIKeyboard::GUIKeyboard(xml_node<>* node)
|
||||
|
||||
int x, y;
|
||||
// Load the placement
|
||||
LoadPlacement(FindNode(node, "placement"), &x, &y);
|
||||
SetRenderPos(x, y, KeyboardWidth, KeyboardHeight);
|
||||
LoadPlacement(FindNode(node, "placement"), &x, &y, &mRenderW, &mRenderH);
|
||||
SetRenderPos(x, y, mRenderW, mRenderH);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -181,6 +205,7 @@ GUIKeyboard::~GUIKeyboard()
|
||||
|
||||
int GUIKeyboard::ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWidth, bool longpress)
|
||||
{
|
||||
key.layout = 0;
|
||||
int keychar = 0;
|
||||
if (strlen(keyinfo) == 1) {
|
||||
// This is a single key, simple definition
|
||||
@@ -222,6 +247,29 @@ int GUIKeyboard::ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWid
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GUIKeyboard::LoadKeyLabels(xml_node<>* parent, int layout)
|
||||
{
|
||||
for (xml_node<>* child = parent->first_node(); child; child = child->next_sibling()) {
|
||||
std::string name = child->name();
|
||||
if (name == "keylabel") {
|
||||
std::string keydef = LoadAttrString(child, "key", "");
|
||||
Key tempkey;
|
||||
int dummyX;
|
||||
if (ParseKey(keydef.c_str(), tempkey, dummyX, 0, false) == 0) {
|
||||
KeyLabel keylabel;
|
||||
keylabel.key = tempkey.key;
|
||||
keylabel.layout_from = layout;
|
||||
keylabel.layout_to = tempkey.layout;
|
||||
keylabel.text = LoadAttrString(child, "text", "");
|
||||
keylabel.image = LoadAttrImage(child, "resource");
|
||||
mKeyLabels.push_back(keylabel);
|
||||
} else {
|
||||
LOGERR("Ignoring invalid keylabel in layout %d: '%s'.\n", layout, keydef.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GUIKeyboard::Render(void)
|
||||
{
|
||||
if (!isConditionTrue())
|
||||
@@ -233,9 +281,114 @@ int GUIKeyboard::Render(void)
|
||||
Layout& lay = layouts[currentLayout - 1];
|
||||
|
||||
if (lay.keyboardImg && lay.keyboardImg->GetResource())
|
||||
gr_blit(lay.keyboardImg->GetResource(), 0, 0, KeyboardWidth, KeyboardHeight, mRenderX, mRenderY);
|
||||
gr_blit(lay.keyboardImg->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY);
|
||||
else {
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 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++) {
|
||||
@@ -259,6 +412,7 @@ int GUIKeyboard::Render(void)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: integrate with key drawing
|
||||
if (hasHighlight && highlightRenderCount != 0) {
|
||||
int boxheight, boxwidth, x;
|
||||
if (rowY == 0)
|
||||
@@ -292,10 +446,7 @@ int GUIKeyboard::Update(void)
|
||||
|
||||
int GUIKeyboard::SetRenderPos(int x, int y, int w, int h)
|
||||
{
|
||||
mRenderX = x;
|
||||
mRenderY = y;
|
||||
mRenderW = KeyboardWidth;
|
||||
mRenderH = KeyboardHeight;
|
||||
RenderObject::SetRenderPos(x, y, w, h);
|
||||
SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
|
||||
return 0;
|
||||
}
|
||||
@@ -359,14 +510,14 @@ int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y)
|
||||
break;
|
||||
|
||||
case TOUCH_RELEASE:
|
||||
if (x < startX - (KeyboardWidth * 0.5)) {
|
||||
if (x < startX - (mRenderW * 0.5)) {
|
||||
if (highlightRenderCount != 0) {
|
||||
highlightRenderCount = 0;
|
||||
mRendered = false;
|
||||
}
|
||||
PageManager::NotifyKeyboard(KEYBOARD_SWIPE_LEFT);
|
||||
return 0;
|
||||
} else if (x > startX + (KeyboardWidth * 0.5)) {
|
||||
} else if (x > startX + (mRenderW * 0.5)) {
|
||||
if (highlightRenderCount != 0) {
|
||||
highlightRenderCount = 0;
|
||||
mRendered = false;
|
||||
|
||||
+21
-1
@@ -852,6 +852,7 @@ protected:
|
||||
int layout;
|
||||
};
|
||||
int ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWidth, bool longpress);
|
||||
void LoadKeyLabels(xml_node<>* parent, int layout);
|
||||
|
||||
enum {
|
||||
MAX_KEYBOARD_LAYOUTS = 5,
|
||||
@@ -868,6 +869,16 @@ protected:
|
||||
};
|
||||
Layout layouts[MAX_KEYBOARD_LAYOUTS];
|
||||
|
||||
struct KeyLabel
|
||||
{
|
||||
unsigned char 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
|
||||
ImageResource* image; // image (overrides text if defined)
|
||||
};
|
||||
std::vector<KeyLabel> mKeyLabels;
|
||||
|
||||
// Find key at screen coordinates
|
||||
Key* HitTestKey(int x, int y);
|
||||
|
||||
@@ -875,11 +886,20 @@ protected:
|
||||
std::string mVariable;
|
||||
int currentLayout;
|
||||
bool CapsLockOn;
|
||||
unsigned int KeyboardWidth, KeyboardHeight;
|
||||
int rowY, colX, highlightRenderCount;
|
||||
bool hasHighlight, hasCapsHighlight;
|
||||
COLOR mHighlightColor;
|
||||
COLOR mCapsHighlightColor;
|
||||
COLOR mFontColor; // for centered key labels
|
||||
COLOR mFontColorSmall; // for centered key labels
|
||||
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
|
||||
COLOR mLongpressFontColor;
|
||||
COLOR mBackgroundColor; // keyboard background color
|
||||
COLOR mKeyColorAlphanumeric; // key background color
|
||||
COLOR mKeyColorOther; // key background color
|
||||
int mKeyMarginX, mKeyMarginY; // space around key boxes - applied to left/right and top/bottom
|
||||
};
|
||||
|
||||
// GUIInput - Used for keyboard input
|
||||
|
||||
Reference in New Issue
Block a user