diff --git a/changelog.txt b/changelog.txt index c08f1178..b50aff90 100644 --- a/changelog.txt +++ b/changelog.txt @@ -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 diff --git a/src/gwin/gwin_textedit.c b/src/gwin/gwin_textedit.c index ec67365e..8e639300 100644 --- a/src/gwin/gwin_textedit.c +++ b/src/gwin/gwin_textedit.c @@ -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);