diff options
author | inmarket <inmarket@ugfx.io> | 2017-08-09 09:02:33 +1000 |
---|---|---|
committer | inmarket <inmarket@ugfx.io> | 2017-08-09 09:02:33 +1000 |
commit | f1db3e940df898186e1472ede45cf9ad40c0f3fb (patch) | |
tree | 0a9b1a5d78ce3547f1f396d2b4852ceb84ffe9c7 /src/gwin | |
parent | e16f97ce2600a3bc7b1ae5bd66a1186bb1217010 (diff) | |
download | uGFX-f1db3e940df898186e1472ede45cf9ad40c0f3fb.tar.gz uGFX-f1db3e940df898186e1472ede45cf9ad40c0f3fb.tar.bz2 uGFX-f1db3e940df898186e1472ede45cf9ad40c0f3fb.zip |
Fix gwinTextEdit() problems
Diffstat (limited to 'src/gwin')
-rw-r--r-- | src/gwin/gwin_textedit.c | 95 |
1 files changed, 60 insertions, 35 deletions
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; - - 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; +static void TextEditRemoveChar(GWidgetObject* gw) { + char *p; + const char *q; + unsigned sz; + unsigned pos; + + 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); |