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()
CHANGE: Upgrade GFILE FATFS support from V0.10b to V0.13
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 ***
@ -93,7 +95,7 @@ FEATURE: Added support for IAR and EDG compilers
FIX: Fixed crash when loading GIF image without enough memory available
FEATURE: Added games/minesweeper demo
FEATURE: Added games/justget10 demo
*** Release 2.5 ***
FEATURE: Added support for numerous compilers

View File

@ -26,22 +26,58 @@
#define gh2obj ((GTexteditObject *)gh)
#define gw2obj ((GTexteditObject *)gw)
static bool_t resizeText(GWidgetObject* gw, size_t pos, int32_t diff) {
char *p, *q;
size_t sz;
static void TextEditRemoveChar(GWidgetObject* gw) {
char *p;
const char *q;
unsigned sz;
unsigned pos;
p = (char *)gw->text;
sz = strlen(p)+1;
if (diff < 0)
memcpy(p+pos, p+pos-diff, sz-pos+diff);
if (!(p = gfxRealloc(p, sz, sz+diff)))
return FALSE;
sz = strlen(gw->text);
pos = gw2obj->cursorPos;
q = gw->text+pos;
if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) {
// 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;
if (diff > 0) {
q = p + sz;
p += pos;
while(--q >= p)
q[diff] = q[0];
}
static bool_t TextEditAddChars(GWidgetObject* gw, unsigned cnt) {
char *p;
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;
}
@ -117,7 +153,7 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
if (!gw2obj->cursorPos)
return;
gw2obj->cursorPos--;
resizeText(gw, gw2obj->cursorPos, -1);
TextEditRemoveChar(gw);
break;
case GKEY_TAB:
case GKEY_LF:
@ -129,7 +165,7 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
// Delete
if (!gw->text[gw2obj->cursorPos])
return;
resizeText(gw, gw2obj->cursorPos, -1);
TextEditRemoveChar(gw);
break;
default:
// Ignore any other control characters
@ -137,15 +173,15 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
return;
// 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;
// Make space
resizeText(gw, gw2obj->cursorPos, pke->bytecount);
// Insert the character
memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount);
gw2obj->cursorPos += pke->bytecount;
if (TextEditAddChars(gw, pke->bytecount)) {
// Insert the characters
memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount);
gw2obj->cursorPos += pke->bytecount;
}
break;
}
}
@ -196,24 +232,13 @@ static const gwidgetVMT texteditVMT = {
GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit, size_t maxSize)
{
char *p;
// Create the underlying widget
if (!(wt = (GTexteditObject*)_gwidgetCreate(g, &wt->w, pInit, &texteditVMT)))
return 0;
wt->maxSize = maxSize;
// Reallocate the text (if necessary)
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
// Set cursor position
wt->cursorPos = strlen(wt->w.text);
gwinSetVisible(&wt->w.g, pInit->g.show);