Improving keyboard widget default renderer (thanks to TriZet)
This commit is contained in:
parent
a51e2b3511
commit
b89ce7c7b3
@ -7,6 +7,7 @@ FEATURE: Added support for numerous compilers
|
|||||||
FIX: Improving STM32LTDC driver
|
FIX: Improving STM32LTDC driver
|
||||||
FEATURE: Added support for NIOS-II platform
|
FEATURE: Added support for NIOS-II platform
|
||||||
FEATURE: Added Altera-MAX10-NEEK board support
|
FEATURE: Added Altera-MAX10-NEEK board support
|
||||||
|
FIX: Vastly improving keyboard widget default rendering
|
||||||
|
|
||||||
|
|
||||||
*** Release 2.4 ***
|
*** Release 2.4 ***
|
||||||
|
@ -393,24 +393,27 @@ static const GColorSet *getDrawColors(GWidgetObject *gw) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param) {
|
void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param) {
|
||||||
#define gk ((GKeyboardObject *)gw)
|
#define gk ((GKeyboardObject *)gw)
|
||||||
|
|
||||||
char cap[5];
|
char cap[5];
|
||||||
const char *pcap;
|
const char *pcap;
|
||||||
const utf8 *krow;
|
const utf8 *krow;
|
||||||
coord_t x, y, cx, cy;
|
coord_t x, y, cx, cy;
|
||||||
uint8_t rows, cols, row, col, kcols;
|
uint8_t rows, cols, row, col, kcols;
|
||||||
ucode key;
|
ucode key;
|
||||||
fixed fx, fy;
|
fixed fx, fy;
|
||||||
const GColorSet *pcol;
|
const GColorSet *pcol;
|
||||||
|
|
||||||
(void) param;
|
(void) param;
|
||||||
|
|
||||||
if (gw->g.vmt != (gwinVMT *)&keyboardVMT) return;
|
// Make sure that this is a keyboard widget object
|
||||||
|
if (gw->g.vmt != (gwinVMT *)&keyboardVMT)
|
||||||
|
return;
|
||||||
|
|
||||||
// Get the y parameters
|
// Get the y parameters
|
||||||
rows = NumKeyRows(gk->keyset);
|
rows = NumKeyRows(gk->keyset);
|
||||||
fy = FIXED(gk->w.g.height) / rows;
|
fy = FIXED(gk->w.g.height) / rows;
|
||||||
for(row = 0; row < rows; row++) {
|
for (row = 0; row < rows; row++) {
|
||||||
y = NONFIXED(fy * row + FIXED0_5);
|
y = NONFIXED(fy * row + FIXED0_5);
|
||||||
cy = NONFIXED(fy * (row+1) + FIXED0_5) - y;
|
cy = NONFIXED(fy * (row+1) + FIXED0_5) - y;
|
||||||
|
|
||||||
@ -420,82 +423,159 @@ void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param) {
|
|||||||
// Get the x parameters
|
// Get the x parameters
|
||||||
cols = UTF8StrLen(krow);
|
cols = UTF8StrLen(krow);
|
||||||
fx = FIXED(gk->w.g.width) / cols;
|
fx = FIXED(gk->w.g.width) / cols;
|
||||||
for(col = 0; col < cols; col=kcols) {
|
for (col = 0; col < cols; col=kcols) {
|
||||||
|
|
||||||
// Choose the color
|
// Get the correct color set
|
||||||
if (!(gk->w.g.flags & GWIN_FLG_SYSENABLED))
|
if (!(gk->w.g.flags & GWIN_FLG_SYSENABLED))
|
||||||
pcol = &gk->w.pstyle->disabled;
|
pcol = &gk->w.pstyle->disabled;
|
||||||
else if (gk->keyrow == row && gk->keycol == col)
|
else
|
||||||
pcol = &gk->w.pstyle->pressed;
|
|
||||||
else
|
|
||||||
pcol = &gk->w.pstyle->enabled;
|
pcol = &gk->w.pstyle->enabled;
|
||||||
|
|
||||||
// Get the key
|
// Get the key
|
||||||
key = UTF8CharAt(krow, col);
|
key = UTF8CharAt(krow, col);
|
||||||
|
|
||||||
// Amalgamate identical keys into one big key
|
// Fuse identical keys into one big key
|
||||||
kcols = col+1;
|
kcols = col+1;
|
||||||
while(UTF8CharAt(krow, kcols) == key)
|
while (UTF8CharAt(krow, kcols) == key)
|
||||||
kcols++;
|
kcols++;
|
||||||
|
|
||||||
|
// If quick update needed and keyboard already drawn (if not use this flag, then bug when screen touched before keyboard was drawn)
|
||||||
|
if ( (gk->w.g.flags & GKEYBOARD_FLG_QUICKUPDATE) && !(gk->w.g.flags & GWIN_FLG_BGREDRAW) ) {
|
||||||
|
|
||||||
|
// If key pressed
|
||||||
|
if ( (gk->keyrow != GKEY_BAD_ROWCOL) && (gk->keycol != GKEY_BAD_ROWCOL) ) {
|
||||||
|
|
||||||
|
// And previous key have
|
||||||
|
if ( (gk->lastkeyrow != GKEY_BAD_ROWCOL) && (gk->lastkeycol != GKEY_BAD_ROWCOL) ) {
|
||||||
|
|
||||||
|
if (gk->lastkeyrow == row && gk->lastkeycol == col) {
|
||||||
|
// If keyboard has no "disabled" color
|
||||||
|
if (pcol != &gk->w.pstyle->disabled)
|
||||||
|
pcol = &gk->w.pstyle->enabled;
|
||||||
|
gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no previous key
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (gk->keyrow == row && gk->keycol == col) {
|
||||||
|
if (pcol != &gk->w.pstyle->disabled)
|
||||||
|
pcol = &gk->w.pstyle->pressed;
|
||||||
|
gk->lastkeyrow = row;
|
||||||
|
gk->lastkeycol = col;
|
||||||
|
}
|
||||||
|
else if (gk->lastkeyrow == row && gk->lastkeycol == col)
|
||||||
|
{
|
||||||
|
if (pcol != &gk->w.pstyle->disabled) pcol = &gk->w.pstyle->enabled;
|
||||||
|
}
|
||||||
|
else continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If key up, and need clear the previous key
|
||||||
|
else if ( (gk->lastkeyrow != GKEY_BAD_ROWCOL) && (gk->lastkeycol != GKEY_BAD_ROWCOL) )
|
||||||
|
{
|
||||||
|
if ( (gk->lastkeyrow == row) && (gk->lastkeycol == col) )
|
||||||
|
{
|
||||||
|
if (pcol != &gk->w.pstyle->disabled) pcol = &gk->w.pstyle->enabled;
|
||||||
|
}
|
||||||
|
else continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
|
||||||
|
}
|
||||||
|
|
||||||
x = NONFIXED(fx * col + FIXED0_5);
|
x = NONFIXED(fx * col + FIXED0_5);
|
||||||
cx = NONFIXED(fx * kcols + FIXED0_5) - x;
|
cx = NONFIXED(fx * kcols + FIXED0_5) - x;
|
||||||
|
|
||||||
if (key < 0x20) {
|
if (key < 0x20) {
|
||||||
pcap = gk->keytable->skeys[key-1].keycap;
|
pcap = gk->keytable->skeys[key-1].keycap;
|
||||||
} else {
|
} else {
|
||||||
cap[UCode2UTF8((utf8 *)cap, key)] = 0;
|
cap[UCode2UTF8((utf8 *)cap, key)] = 0;
|
||||||
pcap = cap;
|
pcap = cap;
|
||||||
}
|
}
|
||||||
switch(*pcap) {
|
|
||||||
case '\001': // Shift (up arrow)
|
switch(*pcap) {
|
||||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
|
||||||
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
|
case '\001': // Shift (up-arrow)
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
|
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* _ */
|
|
||||||
break;
|
|
||||||
case '\002': // Shift locked (up arrow - bold)
|
|
||||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
|
||||||
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* _ */
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/5, gw->g.y+y+cy -cy/4, gw->g.x+x+cx/2+cx/5, gw->g.y+y+cy -cy/4, pcol->text); /* ___ */
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy-1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+cx-1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
|
|
||||||
break;
|
|
||||||
case '\b': // Backspace
|
|
||||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
|
||||||
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/3, pcol->text); /* / */
|
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx-cx/8, gw->g.y+y+cy/2, pcol->text); /* -- */
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
|
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
|
||||||
break;
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
|
||||||
case '\r': // Enter
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
|
||||||
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* _ */
|
||||||
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/5, pcol->text); /* | */
|
break;
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y +cy/3, pcol->text); /* / */
|
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, pcol->text); /* -- */
|
case '\002': // Shift locked (underlined up-arrow)
|
||||||
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
|
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||||
break;
|
|
||||||
default:
|
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text); /* / \ */
|
||||||
gdispGFillStringBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcap, gw->g.font, pcol->text, pcol->fill, justifyCenter);
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/4, pcol->text);
|
||||||
}
|
gdispGDrawLine(gw->g.display, gw->g.x+x +cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, pcol->text); /* _ _ */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx -cx/4, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, pcol->text);
|
||||||
gdispGDrawBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->text); // Frame
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* || */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy/2, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text);
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/6, gw->g.y+y+cy -cy/3, gw->g.x+x+cx/2+cx/6, gw->g.y+y+cy -cy/3, pcol->text); /* _ */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx/2-cx/5, gw->g.y+y+cy -cy/4, gw->g.x+x+cx/2+cx/5, gw->g.y+y+cy -cy/4, pcol->text); /* ___ */
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\t': // Tabulator
|
||||||
|
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||||
|
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+1, gw->g.y+y+cy-1, gw->g.x+x+cx-1, gw->g.y+y+cy/2, pcol->text);
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+cx-1, gw->g.y+y+1, gw->g.x+x+cx-1, gw->g.y+y+cy-1, pcol->text);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\b': // Backspace
|
||||||
|
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||||
|
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y +cy/3, pcol->text); /* / */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx-cx/8, gw->g.y+y+cy/2, pcol->text); /* -- */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/8, gw->g.y+y+cy/2, gw->g.x+x+cx/2, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\r': // Enter
|
||||||
|
gdispGFillArea(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->fill);
|
||||||
|
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/5, pcol->text); /* | */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y+cy/3, pcol->text); /* / */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+(cx/3)*2, gw->g.y+y+cy/2, pcol->text); /* -- */
|
||||||
|
gdispGDrawLine(gw->g.display, gw->g.x+x+ cx/3, gw->g.y+y+cy/2, gw->g.x+x+cx/3 +cx/8, gw->g.y+y+cy -cy/3, pcol->text); /* \ */
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // Regular character
|
||||||
|
gdispGFillStringBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcap, gw->g.font, pcol->text, pcol->fill, justifyCenter);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the frame (border around the entire widget)
|
||||||
|
gdispGDrawBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->edge);
|
||||||
|
|
||||||
|
// If key up and we already cleared the previous key
|
||||||
|
if ( (gk->keyrow == GKEY_BAD_ROWCOL) && (gk->keycol == GKEY_BAD_ROWCOL) && (gk->lastkeyrow == row) && (gk->lastkeycol == col) ) {
|
||||||
|
gk->lastkeyrow = gk->lastkeycol = GKEY_BAD_ROWCOL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just quit the cycle if we did all the work in order not to waste any CPU time
|
||||||
|
if ( (row >= gk->keyrow && col >= gk->keycol) && (row >= gk->lastkeyrow && col >= gk->lastkeycol) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user