Add gwinTextEditSendKey() and gwinTextEditSendSpecialKey()
This commit is contained in:
parent
04c23b408d
commit
0388755df1
@ -47,6 +47,7 @@ REMOVED: Removed long deprecated functions gfxSemCounter() and gfxSemCounterI()
|
||||
FIX: gwinDetachToggle() is now a visible part of the API
|
||||
CHANGE: Update OSX makefiles (allows for 64bit building)
|
||||
FIX: Fixed resetting a timer on gwinImage objects when using animated GIFs
|
||||
FEATURE: Added gwinTextEditSendKey() and gwinTextEditSendSpecialKey()
|
||||
|
||||
|
||||
*** Release 2.7 ***
|
||||
|
@ -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;
|
||||
}
|
||||
gwinTextEditSendSpecialKey(&gw->g, (uint8_t)pke->c[0]);
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
// 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;
|
||||
|
@ -63,6 +63,32 @@ extern "C" {
|
||||
GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit, size_t maxSize);
|
||||
#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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user