From 40611e264d9fc8b05db05ec4dc410e919af7f98d Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Sat, 27 Jul 2013 22:55:32 +0200 Subject: [PATCH] some more list work --- include/gwin/list.h | 18 +++++ src/gwin/list.c | 177 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 185 insertions(+), 10 deletions(-) diff --git a/include/gwin/list.h b/include/gwin/list.h index 46e32d5c..307226c9 100644 --- a/include/gwin/list.h +++ b/include/gwin/list.h @@ -57,6 +57,24 @@ GHandle gwinListCreate(GListObject *widget, GWidgetInit *pInit); int gwinListAddItem(GHandle gh, const char* item, bool_t useAlloc); +char* gwinListItemGetText(GHandle gh, int item); + +int gwinListFindText(GHandle gh, const char* text); + +void gwinListItemSetParam(GHandle gh, int item, uint16_t param); + +uint16_t gwinListItemGetParam(GHandle gh, int item); + +void nListDeleteAll(GHandle gh); + +void gwinListItemDelete(GHandle gh, int item); + +int gwinListItemCount(GHandle gh); + +bool_t gwinListItemIsSelected(GHandle gh, int item); + +int gwinListGetSelected(GHandle gh); + #ifdef __cplusplus } #endif diff --git a/src/gwin/list.c b/src/gwin/list.c index 11fd01cb..9b9ab7c6 100644 --- a/src/gwin/list.c +++ b/src/gwin/list.c @@ -22,6 +22,8 @@ #include "gwin/class_gwin.h" #include +#define BORDER 3 + #define widget(gh) ((GListObject *)gh) #define GLIST_FLG_MULTISELECT (GWIN_FIRST_CONTROL_FLAG << 0) @@ -42,7 +44,6 @@ typedef struct ListItem { uint16_t flags; #define LISTITEM_ALLOCEDTEXT 0x0001 - #define LISTITEM_SELECTED 0x0002 uint16_t param; // A parameter the user can specify himself const char* text; #if GWIN_LIST_IMAGES @@ -77,17 +78,18 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { (void)param; uint16_t i, fheight; - const gfxQueueASyncItem* qi; + gfxQueueASyncItem* qi; + const GColorSet* pcol; fheight = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight); gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, Black); - for (qi = gfxQueueASyncPeek(&gcw->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i += fheight + 4) { + for (qi = gfxQueueASyncPeek(&gcw->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i += fheight + 2*BORDER) { if (((ListItem*)qi)->flags & GLIST_FLG_SELECTED) - gdispFillStringBox(gw->g.x + 3, gw->g.y + 3 + i, gw->g.width - 6, fheight, ((ListItem*)qi)->text, gwinGetDefaultFont(), White, Black, justifyLeft); + gdispFillStringBox(gw->g.x + BORDER, gw->g.y + BORDER + i, gw->g.width - 2*BORDER, fheight, ((ListItem*)qi)->text, gwinGetDefaultFont(), White, Black, justifyLeft); else - gdispFillStringBox(gw->g.x + 3, gw->g.y + 3 + i, gw->g.width - 6, fheight, ((ListItem*)qi)->text, gwinGetDefaultFont(), Black, White, justifyLeft); + gdispFillStringBox(gw->g.x + BORDER, gw->g.y + BORDER + i, gw->g.width - 2*BORDER, fheight, ((ListItem*)qi)->text, gwinGetDefaultFont(), Black, White, justifyLeft); } #undef gcw @@ -101,9 +103,9 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { (void) x; uint16_t i, item_id, item_height; - const gfxQueueASyncItem* qi; + gfxQueueASyncItem* qi; - item_height = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight) + 2; + item_height = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight) + 2*BORDER; item_id = (y - gw->g.y) / item_height; @@ -115,6 +117,11 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { } _gwidgetRedraw((GHandle)gw); + + // Do not generate an event if an empty section of the list has has been selected + if (item_id < 0 || item_id > gcw->cnt - 1) + return; + sendListEvent(gw, item_id); #undef gcw @@ -123,10 +130,11 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) { #endif static void _destroy(GHandle gh) { - const gfxQueueASyncItem* qi; + gfxQueueASyncItem* qi; while((qi = gfxQueueASyncGet(&((GListObject *)gh)->list_head))) gfxFree((void *)qi); + _gwidgetDestroy(gh); } @@ -134,7 +142,7 @@ static const gwidgetVMT listVMT = { { "List", // The class name sizeof(GListObject), // The object size - _destroy, // The destroy routine + _destroy, // The destroy routine _gwidgetRedraw, // The redraw routine 0, // The after-clear routine }, @@ -203,13 +211,58 @@ int gwinListAddItem(GHandle gh, const char* item_name, bool_t useAlloc) { // increment the total amount of entries in the list widget widget(gh)->cnt++; + // return the position in the list (-1 because we start with index 0) return widget(gh)->cnt-1; } +char* gwinListItemGetText(GHandle gh, int item) { + gfxQueueASyncItem* qi; + uint16_t i; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return 0; + + // watch out for an invalid item + if (item < 0 || item > (widget(gh)->cnt) - 1) + return 0; + + qi = gfxQueueASyncPeek(&widget(gh)->list_head); + + for (i = 0; i < item; i++) { + qi = gfxQueueASyncNext(qi); + } + + return ((ListItem*)qi)->text; +} + +int gwinListFindText(GHandle gh, const char* text) { + gfxQueueASyncItem* qi; + uint16_t i; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return -1; + + // watch out for NULL pointers + if (!text) + return -1; + + qi = gfxQueueASyncPeek(&widget(gh)->list_head); + + for(qi = gfxQueueASyncPeek(&widget(gh)->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) { + if (strcmp(((ListItem *)qi)->text, text) == 0) + return i; + } + + return -1; +} + int gwinListGetSelected(GHandle gh) { - const gfxQueueASyncItem *qi; + gfxQueueASyncItem *qi; int i; + // is it a valid handle? if (gh->vmt != (gwinVMT *)&listVMT) return -1; @@ -221,6 +274,110 @@ int gwinListGetSelected(GHandle gh) { return -1; } +void gwinListItemSetParam(GHandle gh, int item, uint16_t param) { + gfxQueueASyncItem* qi; + uint16_t i; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return; + + // watch out for an invalid item + if (item < 0 || item > (widget(gh)->cnt) - 1) + return; + + qi = gfxQueueASyncPeek(&widget(gh)->list_head); + + for (i = 0; i < item; i++) { + ((ListItem*)qi)->param = param; + } + + return; +} + +void gwinListDeleteAll(GHandle gh) { + gfxQueueASyncItem* qi; + + while((qi = gfxQueueASyncGet(&((GListObject *)gh)->list_head))) + gfxFree((void *)qi); +} + +void gwinListItemDelete(GHandle gh, int item) { + gfxQueueASyncItem* qi; + uint16_t i; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return; + + // watch out for an invalid item + if (item < 0 || item > (widget(gh)->cnt) - 1) + return; + + qi = gfxQueueASyncPeek(&widget(gh)->list_head); + + // get our item pointer + for (i = 0; i < item; i++) { + qi = gfxQueueASyncNext(qi); + } + + gfxQueueASyncRemove(&widget(gh)->list_head, qi); + gfxFree((void*)qi); +} + +uint16_t gwinListItemGetParam(GHandle gh, int item) { + gfxQueueASyncItem* qi; + uint16_t i; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return 0; + + // watch out for an invalid item + if (item < 0 || item > (widget(gh)->cnt) - 1) + return 0; + + qi = gfxQueueASyncPeek(&widget(gh)->list_head); + + for (i = 0; i < item; i++) { + qi = gfxQueueASyncNext(qi); + } + + return ((ListItem*)qi)->param; +} + +bool_t gwinListItemIsSelected(GHandle gh, int item) { + gfxQueueASyncItem* qi; + uint16_t i; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return FALSE; + + // watch out for an invalid item + if (item < 0 || item > (widget(gh)->cnt) - 1) + return FALSE; + + qi = gfxQueueASyncPeek(&widget(gh)->list_head); + + for (i = 0; i < item; i++) { + qi = gfxQueueASyncNext(qi); + } + + if (((ListItem*)qi)->flags & GLIST_FLG_SELECTED) + return TRUE; + else + return FALSE; +} + +int gwinListItemCount(GHandle gh) { + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return 0; + + return widget(gh)->cnt; +} + #endif // GFX_USE_GWIN && GWIN_NEED_LIST /** @} */