Merge branch 'master' of git.ugfx.io:uGFX/uGFX
This commit is contained in:
commit
285c6528e6
@ -26,7 +26,7 @@
|
||||
|
||||
ARCH =
|
||||
SRCFLAGS = -ggdb -O0
|
||||
CFLAGS = `sdl2-config --libs --cflags`
|
||||
CFLAGS = $(sdl2-config --cflags)
|
||||
CXXFLAGS =
|
||||
ASFLAGS =
|
||||
LDFLAGS =
|
||||
@ -34,7 +34,7 @@ LDFLAGS =
|
||||
SRC =
|
||||
OBJS =
|
||||
DEFS =
|
||||
LIBS =
|
||||
LIBS = $(sdl2-config --libs)
|
||||
INCPATH =
|
||||
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
|
||||
FEATURE: Added support for CMSIS V2.0 operating systems (eg RTX5)
|
||||
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 ***
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -471,7 +471,7 @@ void _gkeyboardInit(void) {
|
||||
static const GKeyboardVMT * const dclist[] = {GINPUT_KEYBOARD_DRIVER_LIST};
|
||||
|
||||
for(i = 0; i < sizeof(dclist)/sizeof(dclist[0]); i++) {
|
||||
if (!(dclist[i]->d.flags & GKEYBOARD_VFLG_DYNAMICONLY))
|
||||
if (!(dclist[i]->d.flags & GKEYBOARD_VFLG_DYNAMICONLY))
|
||||
gdriverRegister(&dclist[i]->d, 0);
|
||||
}
|
||||
}
|
||||
@ -481,8 +481,8 @@ void _gkeyboardInit(void) {
|
||||
{
|
||||
extern const GKeyboardVMT const GKEYBOARDVMT_OnlyOne[1];
|
||||
|
||||
if (!(GKEYBOARDVMT_OnlyOne->d.flags & GKEYBOARD_VFLG_DYNAMICONLY))
|
||||
gdriverRegister(&GKEYBOARDVMT_OnlyOne->d, 0);
|
||||
if (!(GKEYBOARDVMT_OnlyOne->d.flags & GKEYBOARD_VFLG_DYNAMICONLY))
|
||||
gdriverRegister(&GKEYBOARDVMT_OnlyOne->d, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -493,43 +493,43 @@ void _gkeyboardDeinit(void) {
|
||||
}
|
||||
|
||||
bool_t _gkeyboardInitDriver(GDriver *g, void *param, unsigned driverinstance, unsigned systeminstance) {
|
||||
#define k ((GKeyboard *)g)
|
||||
#define k ((GKeyboard *)g)
|
||||
(void) param;
|
||||
(void) systeminstance;
|
||||
(void) systeminstance;
|
||||
|
||||
// The initial keyboard layout comes from the VMT
|
||||
k->pLayout = gkvmt(k)->defLayout;
|
||||
|
||||
// Init the mouse
|
||||
if (!gkvmt(k)->init((GKeyboard *)g, driverinstance))
|
||||
return FALSE;
|
||||
if (!gkvmt(k)->init((GKeyboard *)g, driverinstance))
|
||||
return FALSE;
|
||||
|
||||
// Ensure the Poll timer is started
|
||||
if (!gtimerIsActive(&KeyboardTimer))
|
||||
gtimerStart(&KeyboardTimer, KeyboardPoll, 0, TRUE, GINPUT_KEYBOARD_POLL_PERIOD);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
|
||||
#undef k
|
||||
#undef k
|
||||
}
|
||||
|
||||
void _gkeyboardPostInitDriver(GDriver *g) {
|
||||
#define k ((GKeyboard *)g)
|
||||
#define k ((GKeyboard *)g)
|
||||
|
||||
// Run the init sequence from the layout microcode.
|
||||
microengine(k, 0, FLAG_INIT);
|
||||
|
||||
#undef k
|
||||
#undef k
|
||||
}
|
||||
|
||||
void _gkeyboardDeInitDriver(GDriver *g) {
|
||||
(void) g;
|
||||
(void) g;
|
||||
}
|
||||
|
||||
GSourceHandle ginputGetKeyboard(unsigned instance) {
|
||||
if (instance == GKEYBOARD_ALL_INSTANCES)
|
||||
return (GSourceHandle)&KeyboardTimer;
|
||||
return (GSourceHandle)gdriverGetInstance(GDRIVER_TYPE_KEYBOARD, instance);
|
||||
return (GSourceHandle)gdriverGetInstance(GDRIVER_TYPE_KEYBOARD, instance);
|
||||
}
|
||||
|
||||
bool_t ginputGetKeyboardStatus(unsigned instance, GEventKeyboard *pe) {
|
||||
|
@ -141,10 +141,10 @@ bool_t gfxSemWaitI(gfxSem *psem)
|
||||
{
|
||||
#if (CH_KERNEL_MAJOR == 2) || (CH_KERNEL_MAJOR == 3)
|
||||
if (psem->sem.s_cnt <= 0)
|
||||
return GFalse;
|
||||
return FALSE;
|
||||
#elif (CH_KERNEL_MAJOR == 4)
|
||||
if (psem->sem.cnt <= 0)
|
||||
return GFalse;
|
||||
return FALSE;
|
||||
#endif
|
||||
chSemFastWaitI(&psem->sem);
|
||||
return TRUE;
|
||||
|
@ -19,6 +19,10 @@
|
||||
#define gw ((GImageObject *)gh)
|
||||
|
||||
static void ImageDestroy(GWindowObject *gh) {
|
||||
// Stop the timer
|
||||
#if GWIN_NEED_IMAGE_ANIMATION
|
||||
gtimerStop(&gw->timer);
|
||||
#endif
|
||||
if (gdispImageIsOpen(&gw->image))
|
||||
gdispImageClose(&gw->image);
|
||||
}
|
||||
@ -129,7 +133,7 @@ GHandle gwinGImageCreate(GDisplay *g, GImageObject *gobj, GWindowInit *pInit) {
|
||||
#if GWIN_NEED_IMAGE_ANIMATION
|
||||
gtimerInit(&gobj->timer);
|
||||
#endif
|
||||
|
||||
|
||||
gwinSetVisible((GHandle)gobj, pInit->show);
|
||||
|
||||
return (GHandle)gobj;
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -356,6 +356,20 @@ bool_t gwinAttachListener(GListener *pl);
|
||||
* @api
|
||||
*/
|
||||
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
|
||||
|
||||
#if (GFX_USE_GINPUT && GINPUT_NEED_DIAL) || defined(__DOXYGEN__)
|
||||
|
@ -9,10 +9,10 @@
|
||||
|
||||
# Requirements:
|
||||
#
|
||||
# OSX_SDK The location of the SDK eg. OSX_SDK = /Developer/SDKs/MacOSX10.7.sdk
|
||||
# OSX_ARCH The architecture flags eg. OSX_ARCH = -mmacosx-version-min=10.3
|
||||
# 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.12
|
||||
#
|
||||
|
||||
SRCFLAGS += -isysroot $(OSX_SDK) $(OSX_ARCH)
|
||||
LDFLAGS += -pthread -Wl,-syslibroot,$(OSX_SDK) $(OSX_ARCH)
|
||||
OPT_CPU = x86
|
||||
OPT_CPU = x64
|
||||
|
Loading…
Reference in New Issue
Block a user