Fix gwinTextEdit() problems

release/v2.9
inmarket 2017-08-09 09:02:33 +10:00
parent e16f97ce26
commit f1db3e940d
2 changed files with 62 additions and 35 deletions

View File

@ -40,6 +40,8 @@ FEATURE: Added RA6963 driver
FIX: Fixed clipping issue in gdispGDrawString() FIX: Fixed clipping issue in gdispGDrawString()
CHANGE: Upgrade GFILE FATFS support from V0.10b to V0.13 CHANGE: Upgrade GFILE FATFS support from V0.10b to V0.13
FEATURE: Added UC1610 driver FEATURE: Added UC1610 driver
FIX: Fixed to allow gwinSetText with static text on a TextEdit control
FIX: Fixed to ChibiOS realloc on a TextEdit control
*** Release 2.7 *** *** Release 2.7 ***
@ -93,7 +95,7 @@ FEATURE: Added support for IAR and EDG compilers
FIX: Fixed crash when loading GIF image without enough memory available FIX: Fixed crash when loading GIF image without enough memory available
FEATURE: Added games/minesweeper demo FEATURE: Added games/minesweeper demo
FEATURE: Added games/justget10 demo FEATURE: Added games/justget10 demo
*** Release 2.5 *** *** Release 2.5 ***
FEATURE: Added support for numerous compilers FEATURE: Added support for numerous compilers

View File

@ -26,22 +26,58 @@
#define gh2obj ((GTexteditObject *)gh) #define gh2obj ((GTexteditObject *)gh)
#define gw2obj ((GTexteditObject *)gw) #define gw2obj ((GTexteditObject *)gw)
static bool_t resizeText(GWidgetObject* gw, size_t pos, int32_t diff) { static void TextEditRemoveChar(GWidgetObject* gw) {
char *p, *q; char *p;
size_t sz; const char *q;
unsigned sz;
unsigned pos;
p = (char *)gw->text; sz = strlen(gw->text);
sz = strlen(p)+1; pos = gw2obj->cursorPos;
if (diff < 0) q = gw->text+pos;
memcpy(p+pos, p+pos-diff, sz-pos+diff);
if (!(p = gfxRealloc(p, sz, sz+diff))) if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) {
return FALSE; // Allocate and then copy
if (!(p = gfxAlloc(sz)))
return;
if (pos)
memcpy(p, gw->text, pos);
memcpy(p+pos, q+1, sz-pos);
gw->g.flags |= GWIN_FLG_ALLOCTXT;
} else {
// Copy and then reallocate
memcpy((char *)q, q+1, sz-pos);
if (!(p = gfxRealloc((char *)gw->text, sz+1, sz))) // This should never fail as we are making it smaller
return;
}
gw->text = p; gw->text = p;
if (diff > 0) { }
q = p + sz;
p += pos; static bool_t TextEditAddChars(GWidgetObject* gw, unsigned cnt) {
while(--q >= p) char *p;
q[diff] = q[0]; const char *q;
unsigned sz;
unsigned pos;
// Get the size of the text buffer
sz = strlen(gw->text)+1;
pos = gw2obj->cursorPos;
if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) {
if (!(p = gfxAlloc(sz+cnt)))
return FALSE;
memcpy(p, gw->text, pos);
memcpy(p+pos+cnt, gw->text+pos, sz-pos);
gw->g.flags |= GWIN_FLG_ALLOCTXT;
gw->text = p;
} else {
if (!(p = gfxRealloc((char *)gw->text, sz, sz+cnt)))
return FALSE;
gw->text = p;
q = p+pos;
p += sz;
while(--p >= q)
p[cnt] = p[0];
} }
return TRUE; return TRUE;
} }
@ -117,7 +153,7 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
if (!gw2obj->cursorPos) if (!gw2obj->cursorPos)
return; return;
gw2obj->cursorPos--; gw2obj->cursorPos--;
resizeText(gw, gw2obj->cursorPos, -1); TextEditRemoveChar(gw);
break; break;
case GKEY_TAB: case GKEY_TAB:
case GKEY_LF: case GKEY_LF:
@ -129,7 +165,7 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
// Delete // Delete
if (!gw->text[gw2obj->cursorPos]) if (!gw->text[gw2obj->cursorPos])
return; return;
resizeText(gw, gw2obj->cursorPos, -1); TextEditRemoveChar(gw);
break; break;
default: default:
// Ignore any other control characters // Ignore any other control characters
@ -137,15 +173,15 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
return; return;
// Keep the edit length to less than the maximum // Keep the edit length to less than the maximum
if (gw2obj->maxSize && gw2obj->cursorPos+pke->bytecount > gw2obj->maxSize) if (gw2obj->maxSize && strlen(gw->text)+pke->bytecount > gw2obj->maxSize)
return; return;
// Make space // Make space
resizeText(gw, gw2obj->cursorPos, pke->bytecount); if (TextEditAddChars(gw, pke->bytecount)) {
// Insert the characters
// Insert the character memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount);
memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount); gw2obj->cursorPos += pke->bytecount;
gw2obj->cursorPos += pke->bytecount; }
break; break;
} }
} }
@ -196,24 +232,13 @@ static const gwidgetVMT texteditVMT = {
GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit, size_t maxSize) GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit, size_t maxSize)
{ {
char *p;
// Create the underlying widget // Create the underlying widget
if (!(wt = (GTexteditObject*)_gwidgetCreate(g, &wt->w, pInit, &texteditVMT))) if (!(wt = (GTexteditObject*)_gwidgetCreate(g, &wt->w, pInit, &texteditVMT)))
return 0; return 0;
wt->maxSize = maxSize; wt->maxSize = maxSize;
// Reallocate the text (if necessary) // Set cursor position
if (!(wt->w.g.flags & GWIN_FLG_ALLOCTXT)) {
if (!(p = gfxAlloc(wt->maxSize+1)))
return 0;
strncpy(p, wt->w.text, wt->maxSize);
wt->w.text = p;
wt->w.g.flags |= GWIN_FLG_ALLOCTXT;
}
// Set text and cursor position
wt->cursorPos = strlen(wt->w.text); wt->cursorPos = strlen(wt->w.text);
gwinSetVisible(&wt->w.g, pInit->g.show); gwinSetVisible(&wt->w.g, pInit->g.show);