aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2017-08-26 11:15:56 +1000
committerinmarket <andrewh@inmarket.com.au>2017-08-26 11:15:56 +1000
commit0388755df1e3d65aa6d17f90965bcf5037c204ab (patch)
tree93aacdd84eed6b046631dff5ebd968430cbcc4d3 /src
parent04c23b408da0f1f4bc5aa7978be7aeb77f1cdd5d (diff)
downloaduGFX-0388755df1e3d65aa6d17f90965bcf5037c204ab.tar.gz
uGFX-0388755df1e3d65aa6d17f90965bcf5037c204ab.tar.bz2
uGFX-0388755df1e3d65aa6d17f90965bcf5037c204ab.zip
Add gwinTextEditSendKey() and gwinTextEditSendSpecialKey()
Diffstat (limited to 'src')
-rw-r--r--src/gwin/gwin_textedit.c190
-rw-r--r--src/gwin/gwin_textedit.h26
2 files changed, 131 insertions, 85 deletions
diff --git a/src/gwin/gwin_textedit.c b/src/gwin/gwin_textedit.c
index 8e639300..61c28c66 100644
--- a/src/gwin/gwin_textedit.c
+++ b/src/gwin/gwin_textedit.c
@@ -26,54 +26,54 @@
#define gh2obj ((GTexteditObject *)gh)
#define gw2obj ((GTexteditObject *)gw)
-static void TextEditRemoveChar(GWidgetObject* gw) {
+static void TextEditRemoveChar(GHandle gh) {
char *p;
const char *q;
unsigned sz;
unsigned pos;
- sz = strlen(gw->text);
- pos = gw2obj->cursorPos;
- q = gw->text+pos;
+ sz = strlen(gh2obj->w.text);
+ pos = gh2obj->cursorPos;
+ q = gh2obj->w.text+pos;
- if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) {
+ if (!(gh->flags & GWIN_FLG_ALLOCTXT)) {
// Allocate and then copy
if (!(p = gfxAlloc(sz)))
return;
if (pos)
- memcpy(p, gw->text, pos);
+ memcpy(p, gh2obj->w.text, pos);
memcpy(p+pos, q+1, sz-pos);
- gw->g.flags |= GWIN_FLG_ALLOCTXT;
+ gh->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
+ if (!(p = gfxRealloc((char *)gh2obj->w.text, sz+1, sz))) // This should never fail as we are making it smaller
return;
}
- gw->text = p;
+ gh2obj->w.text = p;
}
-static bool_t TextEditAddChars(GWidgetObject* gw, unsigned cnt) {
+static bool_t TextEditAddChars(GHandle gh, 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;
+ sz = strlen(gh2obj->w.text)+1;
+ pos = gh2obj->cursorPos;
- if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) {
+ if (!(gh->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;
+ memcpy(p, gh2obj->w.text, pos);
+ memcpy(p+pos+cnt, gh2obj->w.text+pos, sz-pos);
+ gh->flags |= GWIN_FLG_ALLOCTXT;
+ gh2obj->w.text = p;
} else {
- if (!(p = gfxRealloc((char *)gw->text, sz, sz+cnt)))
+ if (!(p = gfxRealloc((char *)gh2obj->w.text, sz, sz+cnt)))
return FALSE;
- gw->text = p;
+ gh2obj->w.text = p;
q = p+pos;
p += sz;
while(--p >= q)
@@ -117,76 +117,13 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
// Is it a special key?
if (pke->keystate & GKEYSTATE_SPECIAL) {
-
// Arrow keys to move the cursor
- switch ((uint8_t)pke->c[0]) {
- case GKEY_LEFT:
- if (!gw2obj->cursorPos)
- return;
- gw2obj->cursorPos--;
- break;
- case GKEY_RIGHT:
- if (!gw->text[gw2obj->cursorPos])
- return;
- gw2obj->cursorPos++;
- break;
- case GKEY_HOME:
- if (!gw2obj->cursorPos)
- return;
- gw2obj->cursorPos = 0;
- break;
- case GKEY_END:
- if (!gw->text[gw2obj->cursorPos])
- return;
- gw2obj->cursorPos = strlen(gw->text);
- break;
- default:
- return;
- }
-
- } else {
+ gwinTextEditSendSpecialKey(&gw->g, (uint8_t)pke->c[0]);
+ return;
- // Normal key press
- switch((uint8_t)pke->c[0]) {
- case GKEY_BACKSPACE:
- // Backspace
- if (!gw2obj->cursorPos)
- return;
- gw2obj->cursorPos--;
- TextEditRemoveChar(gw);
- break;
- case GKEY_TAB:
- case GKEY_LF:
- case GKEY_CR:
- // Move to the next field
- _gwinMoveFocus();
- return;
- case GKEY_DEL:
- // Delete
- if (!gw->text[gw2obj->cursorPos])
- return;
- TextEditRemoveChar(gw);
- break;
- default:
- // Ignore any other control characters
- if ((uint8_t)pke->c[0] < GKEY_SPACE)
- return;
-
- // Keep the edit length to less than the maximum
- if (gw2obj->maxSize && strlen(gw->text)+pke->bytecount > gw2obj->maxSize)
- return;
-
- // Make space
- if (TextEditAddChars(gw, pke->bytecount)) {
- // Insert the characters
- memcpy((char *)gw->text+gw2obj->cursorPos, pke->c, pke->bytecount);
- gw2obj->cursorPos += pke->bytecount;
- }
- break;
- }
}
- _gwinUpdate((GHandle)gw);
+ gwinTextEditSendKey(&gw->g, pke->c, pke->bytecount);
}
#endif
@@ -246,6 +183,89 @@ GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit
return (GHandle)wt;
}
+#if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD
+ void gwinTextEditSendSpecialKey(GHandle gh, uint8_t key) {
+ // Is it a valid handle?
+ if (gh->vmt != (gwinVMT*)&texteditVMT)
+ return;
+
+ // Arrow keys to move the cursor
+ switch (key) {
+ case GKEY_LEFT:
+ if (!gh2obj->cursorPos)
+ return;
+ gh2obj->cursorPos--;
+ break;
+ case GKEY_RIGHT:
+ if (!gh2obj->w.text[gh2obj->cursorPos])
+ return;
+ gh2obj->cursorPos++;
+ break;
+ case GKEY_HOME:
+ if (!gh2obj->cursorPos)
+ return;
+ gh2obj->cursorPos = 0;
+ break;
+ case GKEY_END:
+ if (!gh2obj->w.text[gh2obj->cursorPos])
+ return;
+ gh2obj->cursorPos = strlen(gh2obj->w.text);
+ break;
+ default:
+ return;
+ }
+
+ _gwinUpdate(gh);
+ }
+
+ void gwinTextEditSendKey(GHandle gh, char *key, unsigned len) {
+ // Is it a valid handle?
+ if (gh->vmt != (gwinVMT*)&texteditVMT || !key || !len)
+ return;
+
+ // Normal key press
+ switch((uint8_t)key[0]) {
+ case GKEY_BACKSPACE:
+ // Backspace
+ if (!gh2obj->cursorPos)
+ return;
+ gh2obj->cursorPos--;
+ TextEditRemoveChar(gh);
+ break;
+ case GKEY_TAB:
+ case GKEY_LF:
+ case GKEY_CR:
+ // Move to the next field
+ _gwinMoveFocus();
+ return;
+ case GKEY_DEL:
+ // Delete
+ if (!gh2obj->w.text[gh2obj->cursorPos])
+ return;
+ TextEditRemoveChar(gh);
+ break;
+ default:
+ // Ignore any other control characters
+ if ((uint8_t)key[0] < GKEY_SPACE)
+ return;
+
+ // Keep the edit length to less than the maximum
+ if (gh2obj->maxSize && strlen(gh2obj->w.text)+len > gh2obj->maxSize)
+ return;
+
+ // Make space
+ if (TextEditAddChars(gh, len)) {
+ // Insert the characters
+ memcpy((char *)gh2obj->w.text+gh2obj->cursorPos, key, len);
+ gh2obj->cursorPos += len;
+ }
+ break;
+ }
+
+ _gwinUpdate(gh);
+ }
+#endif
+
void gwinTexteditDefaultDraw(GWidgetObject* gw, void* param)
{
const char* p;
diff --git a/src/gwin/gwin_textedit.h b/src/gwin/gwin_textedit.h
index ed2f634d..8cf6c03e 100644
--- a/src/gwin/gwin_textedit.h
+++ b/src/gwin/gwin_textedit.h
@@ -64,6 +64,32 @@ GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit
#define gwinTexteditCreate(wt, pInit, maxSize) gwinGTexteditCreate(GDISP, wt, pInit, maxSize)
/**
+ * @brief Send a special key to the textedit such as GKEY_LEFT, GKEY_RIGHT, GKEY_HOME, GKEY_END
+ *
+ * @param[in] gh The window handle (must be a textedit window)
+ * @param[in] key The special key to send.
+ * @pre Requires GINPUT_NEED_KEYBOARD or GWIN_NEED_KEYBOARD to be on
+ * @api
+ */
+void gwinTextEditSendSpecialKey(GHandle gh, uint8_t key);
+
+/**
+ * @brief Send a normal utf8 character to the textedit
+ *
+ * @param[in] gh The window handle (must be a textedit window)
+ * @param[in] pkey The pointer to the utf8 character to send.
+ * @param[in] len The length of the utf8 character in bytes.
+ * @note This must ONLY be called with a single utf8 character at a time. Don't attempt to
+ * send a string of characters in the one call.
+ * @note Characters are interpreted as if they came directly from a keyboard ie a backspace
+ * character will perform the backspace operation, a tab will send the focus to the next
+ * control etc.
+ * @pre Requires GINPUT_NEED_KEYBOARD or GWIN_NEED_KEYBOARD to be on
+ * @api
+ */
+void gwinTextEditSendKey(GHandle gh, char *pkey, unsigned len);
+
+/**
* @defgroup Renderings_Textedit Renderings
*
* @brief Built-in rendering functions for the textedit widget.