Merge branch 'master' of git.ugfx.io:uGFX/uGFX
This commit is contained in:
commit
285c6528e6
10 changed files with 1322 additions and 107 deletions
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
ARCH =
|
ARCH =
|
||||||
SRCFLAGS = -ggdb -O0
|
SRCFLAGS = -ggdb -O0
|
||||||
CFLAGS = `sdl2-config --libs --cflags`
|
CFLAGS = $(sdl2-config --cflags)
|
||||||
CXXFLAGS =
|
CXXFLAGS =
|
||||||
ASFLAGS =
|
ASFLAGS =
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
|
@ -34,7 +34,7 @@ LDFLAGS =
|
||||||
SRC =
|
SRC =
|
||||||
OBJS =
|
OBJS =
|
||||||
DEFS =
|
DEFS =
|
||||||
LIBS =
|
LIBS = $(sdl2-config --libs)
|
||||||
INCPATH =
|
INCPATH =
|
||||||
LIBPATH =
|
LIBPATH =
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,11 @@ FIX: Fixed to allow gwinSetText with static text on a TextEdit control
|
||||||
FIX: Fixed to ChibiOS realloc on a TextEdit control
|
FIX: Fixed to ChibiOS realloc on a TextEdit control
|
||||||
FEATURE: Added support for CMSIS V2.0 operating systems (eg RTX5)
|
FEATURE: Added support for CMSIS V2.0 operating systems (eg RTX5)
|
||||||
REMOVED: Removed long deprecated functions gfxSemCounter() and gfxSemCounterI()
|
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()
|
||||||
|
FEATURE: Implemented the JPG image decoder
|
||||||
|
|
||||||
|
|
||||||
*** Release 2.7 ***
|
*** Release 2.7 ***
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -141,10 +141,10 @@ bool_t gfxSemWaitI(gfxSem *psem)
|
||||||
{
|
{
|
||||||
#if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3)
|
#if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3)
|
||||||
if (psem->sem.s_cnt <= 0)
|
if (psem->sem.s_cnt <= 0)
|
||||||
return GFalse;
|
return FALSE;
|
||||||
#elif (CH_KERNEL_MAJOR == 4)
|
#elif (CH_KERNEL_MAJOR == 4)
|
||||||
if (psem->sem.cnt <= 0)
|
if (psem->sem.cnt <= 0)
|
||||||
return GFalse;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
chSemFastWaitI(&psem->sem);
|
chSemFastWaitI(&psem->sem);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#define gw ((GImageObject *)gh)
|
#define gw ((GImageObject *)gh)
|
||||||
|
|
||||||
static void ImageDestroy(GWindowObject *gh) {
|
static void ImageDestroy(GWindowObject *gh) {
|
||||||
|
// Stop the timer
|
||||||
|
#if GWIN_NEED_IMAGE_ANIMATION
|
||||||
|
gtimerStop(&gw->timer);
|
||||||
|
#endif
|
||||||
if (gdispImageIsOpen(&gw->image))
|
if (gdispImageIsOpen(&gw->image))
|
||||||
gdispImageClose(&gw->image);
|
gdispImageClose(&gw->image);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,54 +26,54 @@
|
||||||
#define gh2obj ((GTexteditObject *)gh)
|
#define gh2obj ((GTexteditObject *)gh)
|
||||||
#define gw2obj ((GTexteditObject *)gw)
|
#define gw2obj ((GTexteditObject *)gw)
|
||||||
|
|
||||||
static void TextEditRemoveChar(GWidgetObject* gw) {
|
static void TextEditRemoveChar(GHandle gh) {
|
||||||
char *p;
|
char *p;
|
||||||
const char *q;
|
const char *q;
|
||||||
unsigned sz;
|
unsigned sz;
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
|
||||||
sz = strlen(gw->text);
|
sz = strlen(gh2obj->w.text);
|
||||||
pos = gw2obj->cursorPos;
|
pos = gh2obj->cursorPos;
|
||||||
q = gw->text+pos;
|
q = gh2obj->w.text+pos;
|
||||||
|
|
||||||
if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) {
|
if (!(gh->flags & GWIN_FLG_ALLOCTXT)) {
|
||||||
// Allocate and then copy
|
// Allocate and then copy
|
||||||
if (!(p = gfxAlloc(sz)))
|
if (!(p = gfxAlloc(sz)))
|
||||||
return;
|
return;
|
||||||
if (pos)
|
if (pos)
|
||||||
memcpy(p, gw->text, pos);
|
memcpy(p, gh2obj->w.text, pos);
|
||||||
memcpy(p+pos, q+1, sz-pos);
|
memcpy(p+pos, q+1, sz-pos);
|
||||||
gw->g.flags |= GWIN_FLG_ALLOCTXT;
|
gh->flags |= GWIN_FLG_ALLOCTXT;
|
||||||
} else {
|
} else {
|
||||||
// Copy and then reallocate
|
// Copy and then reallocate
|
||||||
memcpy((char *)q, q+1, sz-pos);
|
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;
|
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;
|
char *p;
|
||||||
const char *q;
|
const char *q;
|
||||||
unsigned sz;
|
unsigned sz;
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
|
||||||
// Get the size of the text buffer
|
// Get the size of the text buffer
|
||||||
sz = strlen(gw->text)+1;
|
sz = strlen(gh2obj->w.text)+1;
|
||||||
pos = gw2obj->cursorPos;
|
pos = gh2obj->cursorPos;
|
||||||
|
|
||||||
if (!(gw->g.flags & GWIN_FLG_ALLOCTXT)) {
|
if (!(gh->flags & GWIN_FLG_ALLOCTXT)) {
|
||||||
if (!(p = gfxAlloc(sz+cnt)))
|
if (!(p = gfxAlloc(sz+cnt)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
memcpy(p, gw->text, pos);
|
memcpy(p, gh2obj->w.text, pos);
|
||||||
memcpy(p+pos+cnt, gw->text+pos, sz-pos);
|
memcpy(p+pos+cnt, gh2obj->w.text+pos, sz-pos);
|
||||||
gw->g.flags |= GWIN_FLG_ALLOCTXT;
|
gh->flags |= GWIN_FLG_ALLOCTXT;
|
||||||
gw->text = p;
|
gh2obj->w.text = p;
|
||||||
} else {
|
} else {
|
||||||
if (!(p = gfxRealloc((char *)gw->text, sz, sz+cnt)))
|
if (!(p = gfxRealloc((char *)gh2obj->w.text, sz, sz+cnt)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gw->text = p;
|
gh2obj->w.text = p;
|
||||||
q = p+pos;
|
q = p+pos;
|
||||||
p += sz;
|
p += sz;
|
||||||
while(--p >= q)
|
while(--p >= q)
|
||||||
|
@ -117,76 +117,13 @@ static void TextEditMouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
|
||||||
|
|
||||||
// Is it a special key?
|
// Is it a special key?
|
||||||
if (pke->keystate & GKEYSTATE_SPECIAL) {
|
if (pke->keystate & GKEYSTATE_SPECIAL) {
|
||||||
|
|
||||||
// Arrow keys to move the cursor
|
// Arrow keys to move the cursor
|
||||||
switch ((uint8_t)pke->c[0]) {
|
gwinTextEditSendSpecialKey(&gw->g, (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;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
gwinTextEditSendKey(&gw->g, pke->c, pke->bytecount);
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -246,6 +183,89 @@ GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit
|
||||||
return (GHandle)wt;
|
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)
|
void gwinTexteditDefaultDraw(GWidgetObject* gw, void* param)
|
||||||
{
|
{
|
||||||
const char* p;
|
const char* p;
|
||||||
|
|
|
@ -63,6 +63,32 @@ extern "C" {
|
||||||
GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit, size_t maxSize);
|
GHandle gwinGTexteditCreate(GDisplay* g, GTexteditObject* wt, GWidgetInit* pInit, size_t maxSize);
|
||||||
#define gwinTexteditCreate(wt, pInit, maxSize) gwinGTexteditCreate(GDISP, wt, pInit, 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
|
* @defgroup Renderings_Textedit Renderings
|
||||||
*
|
*
|
||||||
|
|
|
@ -356,6 +356,20 @@ bool_t gwinAttachListener(GListener *pl);
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance);
|
bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance);
|
||||||
|
/**
|
||||||
|
* @brief Detach a toggle from a widget
|
||||||
|
* @return TRUE on success
|
||||||
|
*
|
||||||
|
* @param[in] gh The widget handle
|
||||||
|
* @param[in] role The function the toggle will perform for the widget
|
||||||
|
*
|
||||||
|
* @note See the documentation on the specific widget to see the possible
|
||||||
|
* values for the role parameter. If it is out of range, this function
|
||||||
|
* will return FALSE
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
bool_t gwinDetachToggle(GHandle gh, uint16_t role);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (GFX_USE_GINPUT && GINPUT_NEED_DIAL) || defined(__DOXYGEN__)
|
#if (GFX_USE_GINPUT && GINPUT_NEED_DIAL) || defined(__DOXYGEN__)
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
|
|
||||||
# Requirements:
|
# Requirements:
|
||||||
#
|
#
|
||||||
# OSX_SDK The location of the SDK eg. OSX_SDK = /Developer/SDKs/MacOSX10.7.sdk
|
# OSX_SDK The location of the SDK eg. OSX_SDK = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
|
||||||
# OSX_ARCH The architecture flags eg. OSX_ARCH = -mmacosx-version-min=10.3
|
# OSX_ARCH The architecture flags eg. OSX_ARCH = -mmacosx-version-min=10.12
|
||||||
#
|
#
|
||||||
|
|
||||||
SRCFLAGS += -isysroot $(OSX_SDK) $(OSX_ARCH)
|
SRCFLAGS += -isysroot $(OSX_SDK) $(OSX_ARCH)
|
||||||
LDFLAGS += -pthread -Wl,-syslibroot,$(OSX_SDK) $(OSX_ARCH)
|
LDFLAGS += -pthread -Wl,-syslibroot,$(OSX_SDK) $(OSX_ARCH)
|
||||||
OPT_CPU = x86
|
OPT_CPU = x64
|
||||||
|
|
Loading…
Add table
Reference in a new issue