diff --git a/src/gwin/gwin_list.c b/src/gwin/gwin_list.c index b5bb531d..2e3cb8e5 100644 --- a/src/gwin/gwin_list.c +++ b/src/gwin/gwin_list.c @@ -569,6 +569,65 @@ const char* gwinListGetSelectedText(GHandle gh) { return gwinListItemGetText(gh, gwinListGetSelected(gh)); } +void gwinListSetSelected(GHandle gh, int item, bool_t doSelect) { + const gfxQueueASyncItem * qi; + int i; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return; + + // watch out for an invalid item + if (item < 0 || item >= gh2obj->cnt) + return; + + // If not a multiselect mode - clear previous selected item + if (doSelect && !(gh->flags & GLIST_FLG_MULTISELECT)) { + for(qi = gfxQueueASyncPeek(&gh2obj->list_head); qi; qi = gfxQueueASyncNext(qi)) { + if (qi2li->flags & GLIST_FLG_SELECTED) { + qi2li->flags &= ~GLIST_FLG_SELECTED; + break; + } + } + } + + // Find item and set selected or not + for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) { + if (i == item) { + if (doSelect) + qi2li->flags |= GLIST_FLG_SELECTED; + else + qi2li->flags &= ~GLIST_FLG_SELECTED; + break; + } + } + _gwinUpdate(gh); +} + +void gwinListViewItem(GHandle gh, int item) { + coord_t iheight; + + // is it a valid handle? + if (gh->vmt != (gwinVMT *)&listVMT) + return; + + // watch out for an invalid item + if (item < 0 || item >= gh2obj->cnt) + return; + + // Work out a possible new top for the list + iheight = gdispGetFontMetric(gh->font, fontHeight) + VERTICAL_PADDING; + gh2obj->top = iheight * item; + + // Adjust the list + if (gh2obj->top > gh2obj->cnt * iheight - gh->height-2) + gh2obj->top = gh2obj->cnt * iheight - gh->height-2; + if (gh2obj->top < 0) + gh2obj->top = 0; + + _gwinUpdate(gh); +} + #if GWIN_NEED_LIST_IMAGES void gwinListItemSetImage(GHandle gh, int item, gdispImage *pimg) { const gfxQueueASyncItem * qi; diff --git a/src/gwin/gwin_list.h b/src/gwin/gwin_list.h index a55d4cb8..28506778 100644 --- a/src/gwin/gwin_list.h +++ b/src/gwin/gwin_list.h @@ -264,6 +264,37 @@ int gwinListGetSelected(GHandle gh); */ const char* gwinListGetSelectedText(GHandle gh); +/** + * @brief Set whether a specific item is selected or not + * + * @param[in] gh The widget handle (must be a list handle) + * @param[in] item The item ID + * @param[in] doSelect TRUE to select the item or FALSE to deselect the item + * + * @note Changing the selection using this api call will NOT send the list selection + * change event. + * @note With a single select list selecting an item with this call will deselect + * any existing selected item. De-selecting an item with this call will not + * cause a new item to be automatically selected. + * @note De-selecting an item that is not selected will not effect any items that + * are selected, even in single-select mode. + * @api + */ +void gwinListSetSelected(GHandle gh, int item, bool_t doSelect); + +/** + * @brief Scroll the list so the specified item is in view + * + * @param[in] gh The widget handle (must be a list handle) + * @param[in] item The item ID + * + * @note This will typically scroll the selected item to the top of the list + * unless the item is in the last page of list items. + * + * @api + */ +void gwinListViewItem(GHandle gh, int item); + #if GWIN_NEED_LIST_IMAGES || defined(__DOXYGEN__) /** * @brief Set the image for a list item