Jump to content

New Keyboard Draw func. Now do redraw only changed buttons.


Recommended Posts

Posted

First version of new redrawing function.

Redraw only changed keys. Not all keyboard. So speed up and redraw flicker gone :)

Except layout change keyboard. For this we must to redraw all.

I have tested for bugs and seems what working fine.

Check this, hope this function will be useful :)


void gwinKeyboardDraw_Normal(GWidgetObject *gw, void *param) {
#define gk ((GKeyboardObject *)gw)

char cap[5];
const char *pcap;
const utf8 *krow;
coord_t x, y, cx, cy;
uint8_t rows, cols, row, col, kcols;
ucode key;
fixed fx, fy;
const GColorSet *pcol;
(void) param;

if (gw->g.vmt != (gwinVMT *)&keyboardVMT) return;

// Get the y parameters
rows = NumKeyRows(gk->keyset);
fy = FIXED(gk->w.g.height) / rows;
for(row = 0; row < rows; row++) {
y = NONFIXED(fy * row + FIXED0_5);
cy = NONFIXED(fy * (row+1) + FIXED0_5) - y;

// Get the current row
krow = (const utf8 *)gk->keyset[row];

// Get the x parameters
cols = UTF8StrLen(krow);
fx = FIXED(gk->w.g.width) / cols;
for(col = 0; col < cols; col=kcols) {

// Choose the color
if (!(gk->w.g.flags & GWIN_FLG_SYSENABLED))
pcol = &gk->w.pstyle->disabled;
else
pcol = &gk->w.pstyle->enabled;

// Get the key
key = UTF8CharAt(krow, col);

// Amalgamate identical keys into one big key
kcols = col+1;
while(UTF8CharAt(krow, kcols) == key)
kcols++;

// if quick update need and keyboard already drawn(if not use this flag, then bug when screen toched before keyboard was drawn)
if( (gk->w.g.flags & GKEYBOARD_FLG_QUICKUPDATE) && !(gk->w.g.flags & GWIN_FLG_BGREDRAW) )
{
// if key down
if( (gk->keyrow != GKEY_BAD_ROWCOL) && (gk->keycol != GKEY_BAD_ROWCOL) )
{
// and previos 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;
}
else//if no previos key
{
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 previos 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);
cx = NONFIXED(fx * kcols + FIXED0_5) - x;

if (key < 0x20) {
pcap = gk->keytable->skeys[key-1].keycap;
} else {
cap[UCode2UTF8((utf8 *)cap, key)] = 0;
pcap = cap;
}

switch(*pcap) {
case '\001': // Shift (up arrow)
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);/* _ */
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/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:
gdispGFillStringBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcap, gw->g.font, pcol->text, pcol->fill, justifyCenter);
}

gdispGDrawBox(gw->g.display, gw->g.x+x, gw->g.y+y, cx, cy, pcol->text); // Frame

//if key up and we already clear previos 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 from cycle if we do all work, for time economy
if( (row >= gk->keyrow && col >= gk->keycol) && (row >= gk->lastkeyrow && col >= gk->lastkeycol) ) return;
}
}
#undef gk
}

Posted

Yes, we received your e-mail and we will reply shorty.

Sorry for the delays - we've never been busier before.

Right now we are testing the code that you published in this thread. Seems to work very well! Should be in the repository by tomorrow.

~ Tectu

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...