Merge branch 'master' into fonts
This commit is contained in:
commit
157ec08034
150
demos/modules/gwin/list/gfxconf.h
Normal file
150
demos/modules/gwin/list/gfxconf.h
Normal file
@ -0,0 +1,150 @@
|
||||
/**
|
||||
* This file has a different license to the rest of the GFX system.
|
||||
* You can copy, modify and distribute this file as you see fit.
|
||||
* You do not need to publish your source modifications to this file.
|
||||
* The only thing you are not permitted to do is to relicense it
|
||||
* under a different license.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copy this file into your project directory and rename it as gfxconf.h
|
||||
* Edit your copy to turn on the GFX features you want to use.
|
||||
*/
|
||||
|
||||
#ifndef _GFXCONF_H
|
||||
#define _GFXCONF_H
|
||||
|
||||
/* The operating system to use - one of these must be defined */
|
||||
//#define GFX_USE_OS_CHIBIOS FALSE
|
||||
//#define GFX_USE_OS_WIN32 FALSE
|
||||
//#define GFX_USE_OS_LINUX TRUE
|
||||
//#define GFX_USE_OS_OSX FALSE
|
||||
|
||||
/* GFX subsystems to turn on */
|
||||
#define GFX_USE_GDISP TRUE
|
||||
#define GFX_USE_TDISP FALSE
|
||||
#define GFX_USE_GWIN TRUE
|
||||
#define GFX_USE_GEVENT TRUE
|
||||
#define GFX_USE_GTIMER TRUE
|
||||
#define GFX_USE_GQUEUE TRUE
|
||||
#define GFX_USE_GINPUT TRUE
|
||||
#define GFX_USE_GADC FALSE
|
||||
#define GFX_USE_GAUDIN FALSE
|
||||
#define GFX_USE_GAUDOUT FALSE
|
||||
#define GFX_USE_GMISC FALSE
|
||||
|
||||
/* Features for the GDISP subsystem */
|
||||
#define GDISP_NEED_VALIDATION TRUE
|
||||
#define GDISP_NEED_CLIP TRUE
|
||||
#define GDISP_NEED_TEXT TRUE
|
||||
#define GDISP_NEED_CIRCLE TRUE
|
||||
#define GDISP_NEED_ELLIPSE TRUE
|
||||
#define GDISP_NEED_ARC FALSE
|
||||
#define GDISP_NEED_CONVEX_POLYGON TRUE
|
||||
#define GDISP_NEED_SCROLL FALSE
|
||||
#define GDISP_NEED_PIXELREAD FALSE
|
||||
#define GDISP_NEED_CONTROL FALSE
|
||||
#define GDISP_NEED_QUERY FALSE
|
||||
#define GDISP_NEED_IMAGE FALSE
|
||||
#define GDISP_NEED_MULTITHREAD FALSE
|
||||
#define GDISP_NEED_ASYNC FALSE
|
||||
#define GDISP_NEED_MSGAPI FALSE
|
||||
|
||||
/* GDISP - builtin fonts */
|
||||
#define GDISP_INCLUDE_FONT_SMALL FALSE
|
||||
#define GDISP_INCLUDE_FONT_LARGER FALSE
|
||||
#define GDISP_INCLUDE_FONT_UI1 FALSE
|
||||
#define GDISP_INCLUDE_FONT_UI2 TRUE
|
||||
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
|
||||
|
||||
/* GDISP image decoders */
|
||||
#define GDISP_NEED_IMAGE_NATIVE FALSE
|
||||
#define GDISP_NEED_IMAGE_GIF FALSE
|
||||
#define GDISP_NEED_IMAGE_BMP FALSE
|
||||
#define GDISP_NEED_IMAGE_JPG FALSE
|
||||
#define GDISP_NEED_IMAGE_PNG FALSE
|
||||
#define GDISP_NEED_IMAGE_ACCOUNTING FALSE
|
||||
|
||||
/* Optional image support that can be turned off */
|
||||
/*
|
||||
#define GDISP_NEED_IMAGE_BMP_1 TRUE
|
||||
#define GDISP_NEED_IMAGE_BMP_4 TRUE
|
||||
#define GDISP_NEED_IMAGE_BMP_4_RLE TRUE
|
||||
#define GDISP_NEED_IMAGE_BMP_8 TRUE
|
||||
#define GDISP_NEED_IMAGE_BMP_8_RLE TRUE
|
||||
#define GDISP_NEED_IMAGE_BMP_16 TRUE
|
||||
#define GDISP_NEED_IMAGE_BMP_24 TRUE
|
||||
#define GDISP_NEED_IMAGE_BMP_32 TRUE
|
||||
*/
|
||||
|
||||
/* Features for the TDISP subsystem. */
|
||||
#define TDISP_NEED_MULTITHREAD FALSE
|
||||
|
||||
/* Features for the GWIN subsystem. */
|
||||
#define GWIN_NEED_WINDOWMANAGER TRUE
|
||||
#define GWIN_NEED_CONSOLE FALSE
|
||||
#define GWIN_NEED_GRAPH FALSE
|
||||
#define GWIN_NEED_WIDGET TRUE
|
||||
#define GWIN_NEED_BUTTON FALSE
|
||||
#define GWIN_NEED_SLIDER FALSE
|
||||
#define GWIN_NEED_CHECKBOX FALSE
|
||||
#define GWIN_NEED_IMAGE FALSE
|
||||
#define GWIN_NEED_RADIO FALSE
|
||||
#define GWIN_NEED_LIST TRUE
|
||||
|
||||
/* Features for the GEVENT subsystem. */
|
||||
#define GEVENT_ASSERT_NO_RESOURCE FALSE
|
||||
|
||||
/* Features for the GTIMER subsystem. */
|
||||
/* NONE */
|
||||
|
||||
/* Features for the GQUEUE subsystem. */
|
||||
#define GQUEUE_NEED_ASYNC TRUE
|
||||
#define GQUEUE_NEED_GSYNC FALSE
|
||||
#define GQUEUE_NEED_FSYNC FALSE
|
||||
|
||||
/* Features for the GINPUT subsystem. */
|
||||
#define GINPUT_NEED_MOUSE TRUE
|
||||
#define GINPUT_NEED_KEYBOARD FALSE
|
||||
#define GINPUT_NEED_TOGGLE FALSE
|
||||
#define GINPUT_NEED_DIAL FALSE
|
||||
|
||||
/* Features for the GADC subsystem. */
|
||||
/* NONE */
|
||||
|
||||
/* Features for the GAUDIN subsystem. */
|
||||
/* NONE */
|
||||
|
||||
/* Features for the GAUDOUT subsystem. */
|
||||
/* NONE */
|
||||
|
||||
/* Features for the GMISC subsystem. */
|
||||
#define GMISC_NEED_ARRAYOPS FALSE
|
||||
#define GMISC_NEED_FASTTRIG FALSE
|
||||
#define GMISC_NEED_FIXEDTRIG FALSE
|
||||
|
||||
/* Optional Parameters for various subsystems */
|
||||
/*
|
||||
#define GDISP_MAX_FONT_HEIGHT 16
|
||||
#define GEVENT_MAXIMUM_SIZE 32
|
||||
#define GEVENT_MAX_SOURCE_LISTENERS 32
|
||||
#define GTIMER_THREAD_WORKAREA_SIZE 512
|
||||
#define GADC_MAX_LOWSPEED_DEVICES 4
|
||||
#define GWIN_BUTTON_LAZY_RELEASE FALSE
|
||||
#define GWIN_CONSOLE_USE_BASESTREAM FALSE
|
||||
#define GWIN_CONSOLE_USE_FLOAT FALSE
|
||||
#define GWIN_NEED_IMAGE_ANIMATION FALSE
|
||||
*/
|
||||
|
||||
/* Optional Low Level Driver Definitions */
|
||||
/*
|
||||
#define GDISP_USE_CUSTOM_BOARD FALSE
|
||||
#define GDISP_SCREEN_WIDTH 320
|
||||
#define GDISP_SCREEN_HEIGHT 240
|
||||
#define GDISP_USE_FSMC
|
||||
#define GDISP_USE_GPIO
|
||||
#define TDISP_COLUMNS 16
|
||||
#define TDISP_ROWS 2
|
||||
*/
|
||||
|
||||
#endif /* _GFXCONF_H */
|
72
demos/modules/gwin/list/main.c
Normal file
72
demos/modules/gwin/list/main.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include "gfx.h"
|
||||
|
||||
static GListener gl;
|
||||
static GHandle ghList1;
|
||||
|
||||
static void createWidgets(void) {
|
||||
GWidgetInit wi;
|
||||
|
||||
// Apply some default values for GWIN
|
||||
wi.customDraw = 0;
|
||||
wi.customParam = 0;
|
||||
wi.customStyle = 0;
|
||||
wi.g.show = FALSE;
|
||||
|
||||
// Apply the list parameters
|
||||
wi.g.width = 100;
|
||||
wi.g.height = 80;
|
||||
wi.g.y = 10;
|
||||
wi.g.x = 10;
|
||||
wi.text = "List Name";
|
||||
|
||||
// Create the actual list
|
||||
ghList1 = gwinListCreate(NULL, &wi);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
GEvent* pe;
|
||||
|
||||
// Initialize the display
|
||||
gfxInit();
|
||||
|
||||
// Set the widget defaults
|
||||
gwinSetDefaultFont(gdispOpenFont("UI2"));
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(Red);
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// create the widget
|
||||
createWidgets();
|
||||
|
||||
// We want to listen for widget events
|
||||
geventListenerInit(&gl);
|
||||
gwinAttachListener(&gl);
|
||||
|
||||
// Add some items to the list widget
|
||||
gwinListAddItem(ghList1, "Item 0", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 1", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 2", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 3", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 4", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 5", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 6", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 7", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 8", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 9", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 10", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 11", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 12", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 13", FALSE);
|
||||
|
||||
gwinSetVisible(ghList1, TRUE);
|
||||
|
||||
while(1) {
|
||||
// Get an Event
|
||||
pe = geventEventWait(&gl, TIME_INFINITE);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -47,7 +47,7 @@
|
||||
#define GDISP_NEED_CIRCLE TRUE
|
||||
#define GDISP_NEED_ELLIPSE FALSE
|
||||
#define GDISP_NEED_ARC FALSE
|
||||
#define GDISP_NEED_CONVEX_POLYGON FALSE
|
||||
#define GDISP_NEED_CONVEX_POLYGON TRUE
|
||||
#define GDISP_NEED_SCROLL FALSE
|
||||
#define GDISP_NEED_PIXELREAD FALSE
|
||||
#define GDISP_NEED_CONTROL FALSE
|
||||
@ -78,6 +78,7 @@
|
||||
#define GWIN_NEED_LABEL TRUE
|
||||
#define GWIN_NEED_IMAGE TRUE
|
||||
#define GWIN_NEED_RADIO TRUE
|
||||
#define GWIN_NEED_LIST TRUE
|
||||
#define GWIN_NEED_IMAGE_ANIMATION TRUE
|
||||
|
||||
|
||||
|
@ -69,13 +69,14 @@ static const GWidgetStyle YellowWidgetStyle = {
|
||||
/* The variables we need */
|
||||
static GListener gl;
|
||||
static GHandle ghConsole;
|
||||
static GHandle ghTabButtons, ghTabSliders, ghTabCheckboxes, ghTabLabels, ghTabRadios, ghTabImages;
|
||||
static GHandle ghTabButtons, ghTabSliders, ghTabCheckboxes, ghTabLabels, ghTabRadios, ghTabLists, ghTabImages;
|
||||
static GHandle ghButton1, ghButton2, ghButton3, ghButton4;
|
||||
static GHandle ghSlider1, ghSlider2, ghSlider3, ghSlider4;
|
||||
static GHandle ghCheckbox1, ghCheckbox2, ghCheckDisableAll;
|
||||
static GHandle ghLabel1;
|
||||
static GHandle ghRadio1, ghRadio2;
|
||||
static GHandle ghRadioBlack, ghRadioWhite, ghRadioYellow;
|
||||
static GHandle ghList1;
|
||||
static GHandle ghImage1;
|
||||
|
||||
/* Some useful macros */
|
||||
@ -86,6 +87,8 @@ static GHandle ghImage1;
|
||||
#define LABEL_HEIGHT 40
|
||||
#define BUTTON_WIDTH 50
|
||||
#define BUTTON_HEIGHT 30
|
||||
#define LIST_WIDTH 100
|
||||
#define LIST_HEIGHT 80
|
||||
#define SLIDER_WIDTH 20
|
||||
#define CHECKBOX_WIDTH 80
|
||||
#define CHECKBOX_HEIGHT 20
|
||||
@ -108,13 +111,14 @@ static void createWidgets(void) {
|
||||
|
||||
// Create the Tabs
|
||||
wi.g.show = TRUE; wi.customDraw = gwinRadioDraw_Tab;
|
||||
wi.g.width = ScrWidth/6; wi.g.height = TAB_HEIGHT; wi.g.y = 0;
|
||||
wi.g.width = ScrWidth/7; wi.g.height = TAB_HEIGHT; wi.g.y = 0;
|
||||
wi.g.x = 0*wi.g.width; wi.text = "Buttons"; ghTabButtons = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 1*wi.g.width; wi.text = "Sliders"; ghTabSliders = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 2*wi.g.width; wi.text = "Checkbox"; ghTabCheckboxes = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 3*wi.g.width; wi.text = "Radios"; ghTabRadios = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 4*wi.g.width; wi.text = "Labels"; ghTabLabels = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 5*wi.g.width; wi.text = "Images"; ghTabImages = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 4*wi.g.width; wi.text = "Lists"; ghTabLists = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 5*wi.g.width; wi.text = "Labels"; ghTabLabels = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
wi.g.x = 6*wi.g.width; wi.text = "Images"; ghTabImages = gwinRadioCreate(NULL, &wi, GROUP_TABS);
|
||||
|
||||
// Buttons
|
||||
wi.g.show = FALSE; wi.customDraw = 0;
|
||||
@ -156,6 +160,25 @@ static void createWidgets(void) {
|
||||
wi.g.x = 2*wi.g.width; wi.text = "Yellow"; ghRadioYellow = gwinRadioCreate(NULL, &wi, GROUP_COLORS);
|
||||
gwinRadioPress(ghRadioWhite);
|
||||
|
||||
// Lists
|
||||
wi.g.show = FALSE; wi.customDraw = 0;
|
||||
wi.g.width = LIST_WIDTH; wi.g.height = LIST_HEIGHT; wi.g.y = TAB_HEIGHT+5;
|
||||
wi.g.x = 0+0*(LIST_WIDTH+1); wi.text = "L1"; ghList1 = gwinListCreate(NULL, &wi);
|
||||
gwinListAddItem(ghList1, "Item 0", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 1", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 2", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 3", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 4", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 5", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 6", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 7", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 8", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 9", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 10", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 11", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 12", FALSE);
|
||||
gwinListAddItem(ghList1, "Item 13", FALSE);
|
||||
|
||||
// Image
|
||||
wi.g.x = ScrWidth-210; wi.g.y = TAB_HEIGHT + 10; wi.g.width = 200; wi.g.height = 200;
|
||||
ghImage1 = gwinImageCreate(NULL, &wi.g);
|
||||
@ -183,6 +206,7 @@ static void setTab(GHandle tab) {
|
||||
gwinSetVisible(ghLabel1, FALSE);
|
||||
gwinSetVisible(ghRadio1, FALSE); gwinSetVisible(ghRadio2, FALSE);
|
||||
gwinSetVisible(ghRadioWhite, FALSE);gwinSetVisible(ghRadioBlack, FALSE);gwinSetVisible(ghRadioYellow, FALSE);
|
||||
gwinSetVisible(ghList1, FALSE);
|
||||
gwinSetVisible(ghImage1, FALSE);
|
||||
|
||||
/* Turn on widgets depending on the tab selected */
|
||||
@ -199,6 +223,8 @@ static void setTab(GHandle tab) {
|
||||
} else if (tab == ghTabRadios) {
|
||||
gwinSetVisible(ghRadio1, TRUE); gwinSetVisible(ghRadio2, TRUE);
|
||||
gwinSetVisible(ghRadioWhite, TRUE); gwinSetVisible(ghRadioBlack, TRUE); gwinSetVisible(ghRadioYellow, TRUE);
|
||||
} else if (tab == ghTabLists) {
|
||||
gwinSetVisible(ghList1, TRUE);
|
||||
} else if (tab == ghTabImages) {
|
||||
gwinSetVisible(ghImage1, TRUE);
|
||||
}
|
||||
@ -282,6 +308,10 @@ int main(void) {
|
||||
}
|
||||
break;
|
||||
|
||||
case GEVENT_GWIN_LIST:
|
||||
gwinPrintf(ghConsole, "List %s Item %d\n", gwinGetText(((GEventGWinList *)pe)->list), ((GEventGWinList *)pe)->item);
|
||||
break;
|
||||
|
||||
case GEVENT_GWIN_RADIO:
|
||||
gwinPrintf(ghConsole, "Radio Group %u=%s\n", ((GEventGWinRadio *)pe)->group, gwinGetText(((GEventGWinRadio *)pe)->radio));
|
||||
|
||||
|
@ -775,18 +775,6 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
|
||||
const char *gdispGetFontName(font_t font);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Blend two colors together according to opacity/alpha.
|
||||
* @return The blended color.
|
||||
*
|
||||
* @param[in] fg Foreground color
|
||||
* @param[in] bg Background color
|
||||
* @param[in] alpha Opacity of the foreground color (0-255)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
|
||||
|
||||
/* Extra Arc Functions */
|
||||
|
||||
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
|
||||
@ -815,6 +803,19 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
|
||||
void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Blend 2 colors according to the alpha
|
||||
* @return The combined color
|
||||
*
|
||||
* @param[in] fg The foreground color
|
||||
* @param[in] bg The background color
|
||||
* @param[in] alpha The alpha value (0-255). 0 is all background, 255 is all foreground.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
|
||||
|
||||
/* Support routine for packed pixel formats */
|
||||
#if !defined(gdispPackPixels) || defined(__DOXYGEN__)
|
||||
/**
|
||||
|
@ -206,9 +206,9 @@ bool_t gfxQueueFSyncIsEmpty(gfxQueueFSync *pqueue);
|
||||
* @api
|
||||
* @{
|
||||
*/
|
||||
bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
|
||||
bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
|
||||
bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem);
|
||||
bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem);
|
||||
bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem);
|
||||
bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem);
|
||||
/* @} */
|
||||
|
||||
/**
|
||||
|
@ -37,21 +37,171 @@
|
||||
* @brief A list event
|
||||
*/
|
||||
typedef struct GEventGWinList {
|
||||
GEventType type; // The type of this event (GEVENT_GWIN_LIST)
|
||||
GHandle list; // THe list that has generated the event
|
||||
GEventType type; // The type of this event (GEVENT_GWIN_LIST)
|
||||
GHandle list; // The list
|
||||
int item; // The item that has been selected (or unselected in a multi-select listbox)
|
||||
} GEventGWinList;
|
||||
|
||||
// A list window
|
||||
typedef struct GListObject {
|
||||
GWidgetObject w;
|
||||
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
uint16_t t_up;
|
||||
uint16_t t_dn;
|
||||
#endif
|
||||
|
||||
int cnt; // Number of items currently in the list (quicker than counting each time)
|
||||
int top; // The element at the top of the visible list area
|
||||
gfxQueueASync list_head; // The list of items
|
||||
} GListObject;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Create a list widget
|
||||
*
|
||||
* @note The drawing color and the background color get set to the current defaults. If you haven't called
|
||||
* @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are Black and White.
|
||||
* @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then
|
||||
* there is no default font and text drawing operations will not display anything.
|
||||
* @note A list remembers its normal drawing state. If there is a window manager then it is automatically
|
||||
* redrawn if the window is moved or its visibility state is changed.
|
||||
* @note The list contains no elements after creation.
|
||||
* @note A slider supports mouse, toggle and dial input.
|
||||
* @note When assigning a toggle, only one toggle is supported per role. If you try to assign more than
|
||||
* one toggle to a role, it will forget the previous toggle. Two roles are supported:
|
||||
* Role 0 = toggle for down, role 1 = toggle for up
|
||||
* @note When assigning a dial, only one dial is supported. If you try to assign more than one dial, it
|
||||
* will forget the previous dial. Only dial role 0 is supported.
|
||||
*
|
||||
* @param[in] widget The GListObject structure to initialize. If this is NULL, the structure is dynamically allocated.
|
||||
* @param[in] pInit The initialization parameters to use
|
||||
*
|
||||
* @return NULL if there is no resulting drawing area, otherwise a window handle.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
GHandle gwinListCreate(GListObject *widget, GWidgetInit *pInit);
|
||||
|
||||
/**
|
||||
* @brief Add an item to the list
|
||||
*
|
||||
* @note The ID you get returned is not static. If items get removed from the list, the list items get
|
||||
* reordered.
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
* @param[in] item The string which shall be displayed in the list afterwards
|
||||
* @param[in] useAlloc If set to TRUE, the string will be dynamically allocated. A static buffer must be passed otherwise
|
||||
*
|
||||
* @return The current ID of the item. The ID might change if you remove items from the middle of the list
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
int gwinListAddItem(GHandle gh, const char* item, bool_t useAlloc);
|
||||
|
||||
/**
|
||||
* @brief Get the name behind an item with a given ID
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
* @param[in] item The item ID
|
||||
*
|
||||
* @return The string of the list item or NULL on error
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const char* gwinListItemGetText(GHandle gh, int item);
|
||||
|
||||
/**
|
||||
* @brief Get the ID of an item with a given name
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
* @param[in] text The item name
|
||||
*
|
||||
* @return The id of the list item or -1 on error
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
int gwinListFindText(GHandle gh, const char* text);
|
||||
|
||||
/**
|
||||
* @brief Set the custom parameter of an item with a given ID
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
* @param[in] item The item ID
|
||||
* @param[in] param The parameter to be set
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinListItemSetParam(GHandle gh, int item, uint16_t param);
|
||||
|
||||
/**
|
||||
* @brief Get the custom parameter of an item with a given ID
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
* @param[in] item The item ID
|
||||
*
|
||||
* @return The parameter
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
uint16_t gwinListItemGetParam(GHandle gh, int item);
|
||||
|
||||
/**
|
||||
* @brief Delete all the items of the list
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void ListDeleteAll(GHandle gh);
|
||||
|
||||
/**
|
||||
* @brief Delete an item from the list
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
* @param[in] item The item ID
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinListItemDelete(GHandle gh, int item);
|
||||
|
||||
/**
|
||||
* @brief Get the amount of items within the list
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
*
|
||||
* @return The amount of items in the list
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
int gwinListItemCount(GHandle gh);
|
||||
|
||||
/**
|
||||
* @brief Check if an item with a given ID is selected
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
* @param[in] item The item ID
|
||||
*
|
||||
* @return TRUE if the item is selected, FALSE otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool_t gwinListItemIsSelected(GHandle gh, int item);
|
||||
|
||||
/**
|
||||
* @brief Get the ID of the selected item
|
||||
*
|
||||
* @param[in] gh The widget handle (must be a list handle)
|
||||
*
|
||||
* @return The ID of the list item
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
int gwinListGetSelected(GHandle gh);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -75,7 +75,7 @@
|
||||
bool_t gfxQueueASyncIsEmpty(gfxQueueASync *pqueue) {
|
||||
return pqueue->head == NULL;
|
||||
}
|
||||
bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) {
|
||||
bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem) {
|
||||
gfxQueueASyncItem *pi;
|
||||
|
||||
gfxSystemLock();
|
||||
@ -156,7 +156,7 @@
|
||||
bool_t gfxQueueGSyncIsEmpty(gfxQueueGSync *pqueue) {
|
||||
return pqueue->head == NULL;
|
||||
}
|
||||
bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) {
|
||||
bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem) {
|
||||
gfxQueueGSyncItem *pi;
|
||||
|
||||
gfxSystemLock();
|
||||
@ -248,7 +248,7 @@
|
||||
bool_t gfxQueueFSyncIsEmpty(gfxQueueFSync *pqueue) {
|
||||
return pqueue->head == NULL;
|
||||
}
|
||||
bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) {
|
||||
bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem) {
|
||||
gfxQueueASyncItem *pi;
|
||||
|
||||
gfxSystemLock();
|
||||
|
443
src/gwin/list.c
443
src/gwin/list.c
@ -20,34 +20,255 @@
|
||||
#if GFX_USE_GWIN && GWIN_NEED_LIST
|
||||
|
||||
#include "gwin/class_gwin.h"
|
||||
#include <string.h>
|
||||
|
||||
// user for the default drawing routine
|
||||
#define SCROLLWIDTH 16 // the border from the scroll buttons to the frame
|
||||
#define ARROW 10 // arrow side length
|
||||
#define TEXTGAP 1 // extra vertical padding for text
|
||||
|
||||
#define gh2obj ((GListObject *)gh)
|
||||
#define gw2obj ((GListObject *)gw)
|
||||
#define qi2li ((ListItem *)qi)
|
||||
#define qix2li ((ListItem *)qix)
|
||||
#define ple ((GEventGWinList *)pe)
|
||||
|
||||
#define GLIST_FLG_MULTISELECT (GWIN_FIRST_CONTROL_FLAG << 0)
|
||||
#define GLIST_FLG_HASIMAGES (GWIN_FIRST_CONTROL_FLAG << 1)
|
||||
#define GLIST_FLG_SELECTED (GWIN_FIRST_CONTROL_FLAG << 2)
|
||||
|
||||
typedef struct ListItem {
|
||||
gfxQueueASyncItem q_item; // This must be the first member in the struct
|
||||
|
||||
uint16_t flags;
|
||||
uint16_t param; // A parameter the user can specify himself
|
||||
const char* text;
|
||||
#if GWIN_LIST_IMAGES
|
||||
gdispImage* pimg;
|
||||
#endif
|
||||
} ListItem;
|
||||
|
||||
static void sendListEvent(GWidgetObject *gw, int item) {
|
||||
GSourceListener* psl;
|
||||
GEvent* pe;
|
||||
|
||||
// Trigger a GWIN list event
|
||||
psl = 0;
|
||||
|
||||
while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
|
||||
if (!(pe = geventGetEventBuffer(psl)))
|
||||
continue;
|
||||
|
||||
ple->type = GEVENT_GWIN_LIST;
|
||||
ple->list = (GHandle)gw;
|
||||
ple->item = item;
|
||||
|
||||
geventSendEvent(psl);
|
||||
}
|
||||
}
|
||||
|
||||
static void gwinListDefaultDraw(GWidgetObject* gw, void* param) {
|
||||
(void)param;
|
||||
|
||||
#if GDISP_NEED_CONVEX_POLYGON
|
||||
static const point upArrow[] = { {0, ARROW}, {ARROW, ARROW}, {ARROW/2, 0} };
|
||||
static const point downArrow[] = { {0, 0}, {ARROW, 0}, {ARROW/2, ARROW} };
|
||||
#endif
|
||||
|
||||
const gfxQueueASyncItem* qi;
|
||||
int i;
|
||||
coord_t y, iheight, iwidth;
|
||||
const GColorSet * ps;
|
||||
|
||||
ps = (gw->g.flags & GWIN_FLG_ENABLED) ? &gw->pstyle->enabled : &gw->pstyle->disabled;
|
||||
iheight = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight) + TEXTGAP;
|
||||
|
||||
// the scroll area
|
||||
if (gw2obj->cnt > (gw->g.height-2) / iheight) {
|
||||
iwidth = gw->g.width - (SCROLLWIDTH+3);
|
||||
gdispFillArea(gw->g.x+iwidth+2, gw->g.y+1, SCROLLWIDTH, gw->g.height-2, gdispBlendColor(ps->fill, gw->pstyle->background, 128));
|
||||
gdispDrawLine(gw->g.x+iwidth+1, gw->g.y+1, gw->g.x+iwidth+1, gw->g.y+gw->g.height-2, ps->edge);
|
||||
#if GDISP_NEED_CONVEX_POLYGON
|
||||
gdispFillConvexPoly(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+(ARROW/2+1), upArrow, 3, ps->fill);
|
||||
gdispFillConvexPoly(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+gw->g.height-(ARROW+ARROW/2+1), downArrow, 3, ps->fill);
|
||||
#else
|
||||
#warning "GWIN: Lists display better when GDISP_NEED_CONVEX_POLGON is turned on"
|
||||
gdispFillArea(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+(ARROW/2+1), ARROW, ARROW, ps->fill);
|
||||
gdispFillArea(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+gw->g.height-(ARROW+ARROW/2+1), ARROW, ARROW, ps->fill);
|
||||
#endif
|
||||
} else
|
||||
iwidth = gw->g.width - 2;
|
||||
|
||||
|
||||
// Find the top item
|
||||
for (qi = gfxQueueASyncPeek(&gw2obj->list_head), i = 0; i < gw2obj->top && qi; qi = gfxQueueASyncNext(qi), i++);
|
||||
|
||||
// Draw until we run out of room or items
|
||||
for (y=1; y+iheight < gw->g.height-1 && qi; qi = gfxQueueASyncNext(qi), y += iheight) {
|
||||
if (qi2li->flags & GLIST_FLG_SELECTED) {
|
||||
//gdispFillStringBox(gw->g.x+1, gw->g.y+y, iwidth, iheight, qi2li->text, gwinGetDefaultFont(), gw->pstyle->background, ps->text, justifyLeft);
|
||||
gdispFillStringBox(gw->g.x+1, gw->g.y+y, iwidth, iheight, qi2li->text, gwinGetDefaultFont(), ps->text, ps->fill, justifyLeft);
|
||||
} else {
|
||||
gdispFillStringBox(gw->g.x+1, gw->g.y+y, iwidth, iheight, qi2li->text, gwinGetDefaultFont(), ps->text, gw->pstyle->background, justifyLeft);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill any remaining item space
|
||||
if (y < gw->g.height-1)
|
||||
gdispFillArea(gw->g.x+1, gw->g.y+y, iwidth, gw->g.height-1-y, gw->pstyle->background);
|
||||
|
||||
// the list frame
|
||||
gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, ps->edge);
|
||||
}
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
// a mouse down has occurred over the list area
|
||||
static void MouseDown(GWidgetObject* gw, coord_t x, coord_t y) {
|
||||
const gfxQueueASyncItem* qi;
|
||||
int item, i, pgsz;
|
||||
coord_t iheight;
|
||||
(void) x;
|
||||
|
||||
iheight = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight) + TEXTGAP;
|
||||
pgsz = (gw->g.height-2)/iheight;
|
||||
if (pgsz < 1) pgsz = 1;
|
||||
|
||||
// Handle click over the scroll bar
|
||||
if (gw2obj->cnt > pgsz && x >= gw->g.width-(SCROLLWIDTH+2)) {
|
||||
if (y < 2*ARROW) {
|
||||
if (gw2obj->top > 0) {
|
||||
gw2obj->top--;
|
||||
_gwidgetRedraw(&gw->g);
|
||||
}
|
||||
} else if (y >= gw->g.height - 2*ARROW) {
|
||||
if (gw2obj->top < gw2obj->cnt - pgsz) {
|
||||
gw2obj->top++;
|
||||
_gwidgetRedraw(&gw->g);
|
||||
}
|
||||
} else if (y < gw->g.height/2) {
|
||||
if (gw2obj->top > 0) {
|
||||
if (gw2obj->top > pgsz)
|
||||
gw2obj->top -= pgsz;
|
||||
else
|
||||
gw2obj->top = 0;
|
||||
_gwidgetRedraw(&gw->g);
|
||||
}
|
||||
} else {
|
||||
if (gw2obj->top < gw2obj->cnt - pgsz) {
|
||||
if (gw2obj->top < gw2obj->cnt - 2*pgsz)
|
||||
gw2obj->top += pgsz;
|
||||
else
|
||||
gw2obj->top = gw2obj->cnt - pgsz;
|
||||
_gwidgetRedraw(&gw->g);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle click over the list area
|
||||
item = gw2obj->top + y / iheight;
|
||||
|
||||
if (item < 0 || item >= gw2obj->cnt)
|
||||
return;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gw2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if (item == i)
|
||||
qi2li->flags |= GLIST_FLG_SELECTED;
|
||||
else
|
||||
qi2li->flags &=~ GLIST_FLG_SELECTED;
|
||||
}
|
||||
|
||||
_gwidgetRedraw(&gw->g);
|
||||
sendListEvent(gw, item);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
// a toggle-on has occurred
|
||||
static void ToggleOn(GWidgetObject *gw, uint16_t role) {
|
||||
const gfxQueueASyncItem * qi;
|
||||
const gfxQueueASyncItem * qix;
|
||||
int i;
|
||||
|
||||
switch (role) {
|
||||
// select down
|
||||
case 0:
|
||||
for (i = 0, qi = gfxQueueASyncPeek(&gw2obj->list_head); qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if ((qi2li->flags & GLIST_FLG_SELECTED)) {
|
||||
qix = gfxQueueASyncNext(qi);
|
||||
if (qix) {
|
||||
qi2li->flags &=~ GLIST_FLG_SELECTED;
|
||||
qix2li->flags |= GLIST_FLG_SELECTED;
|
||||
_gwidgetRedraw(&gw->g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// select up
|
||||
case 1:
|
||||
qi = gfxQueueASyncPeek(&gw2obj->list_head);
|
||||
qix = 0;
|
||||
|
||||
for (i = 0; qi; qix = qi, qi = gfxQueueASyncNext(qi), i++) {
|
||||
if ((qi2li->flags & GLIST_FLG_SELECTED))
|
||||
if (qix) {
|
||||
qi2li->flags &=~ GLIST_FLG_SELECTED;
|
||||
qix2li->flags |= GLIST_FLG_SELECTED;
|
||||
_gwidgetRedraw(&gw->g);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) {
|
||||
if (role)
|
||||
gw2obj->t_up = instance;
|
||||
else
|
||||
gw2obj->t_dn = instance;
|
||||
}
|
||||
|
||||
static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) {
|
||||
return role ? gw2obj->t_up : gw2obj->t_dn;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _destroy(GHandle gh) {
|
||||
const gfxQueueASyncItem* qi;
|
||||
|
||||
while((qi = gfxQueueASyncGet(&gh2obj->list_head)))
|
||||
gfxFree((void *)qi);
|
||||
|
||||
_gwidgetDestroy(gh);
|
||||
}
|
||||
|
||||
static const gwidgetVMT listVMT = {
|
||||
{
|
||||
"List", // The class name
|
||||
sizeof(GListObject), // The object size
|
||||
_gwidgetDestroy, // The destroy routine
|
||||
_destroy, // The destroy routine
|
||||
_gwidgetRedraw, // The redraw routine
|
||||
0, // The after-clear routine
|
||||
},
|
||||
gwinListDefaultDraw, // default drawing routine
|
||||
#if GWINPUT_NEED_MOUSE
|
||||
#if GINPUT_NEED_MOUSE
|
||||
{
|
||||
0,
|
||||
MouseDown,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
{
|
||||
2, // two toggle roles
|
||||
ToggleAssign, // Assign toggles
|
||||
ToggleGet, // get toggles
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
ToggleOn, // process toggle on event
|
||||
},
|
||||
#endif
|
||||
#if GINPUT_NEED_DIAL
|
||||
@ -60,13 +281,213 @@ static const gwidgetVMT listVMT = {
|
||||
#endif
|
||||
};
|
||||
|
||||
GHandle gwinListCreate(GListObject* widget, GWidgetInit* pInit) {
|
||||
if (!(widget = (GListObject *)_gwidgetCreate(&widget->w, pInit, &listVMT)))
|
||||
GHandle gwinListCreate(GListObject* gobj, GWidgetInit* pInit) {
|
||||
if (!(gobj = (GListObject *)_gwidgetCreate(&gobj->w, pInit, &listVMT)))
|
||||
return 0;
|
||||
|
||||
gwinSetVisible(&widget->w.g, pInit->g.show);
|
||||
// initialize the item queue
|
||||
gfxQueueASyncInit(&gobj->list_head);
|
||||
gobj->cnt = 0;
|
||||
gobj->top = 0;
|
||||
|
||||
return (GHandle)widget;
|
||||
gwinSetVisible(&gobj->w.g, pInit->g.show);
|
||||
|
||||
return (GHandle)gobj;
|
||||
}
|
||||
|
||||
int gwinListAddItem(GHandle gh, const char* item_name, bool_t useAlloc) {
|
||||
ListItem *newItem;
|
||||
|
||||
if (useAlloc) {
|
||||
if (!(newItem = (ListItem *)gfxAlloc(sizeof(ListItem)+strlen(item_name)+1)))
|
||||
return -1;
|
||||
|
||||
strcpy((char *)(newItem+1), item_name);
|
||||
item_name = (const char *)(newItem+1);
|
||||
} else {
|
||||
if (!(newItem = (ListItem *)gfxAlloc(sizeof(ListItem))))
|
||||
return -1;
|
||||
}
|
||||
|
||||
// the item is not selected when added
|
||||
newItem->flags = 0;
|
||||
newItem->param = 0;
|
||||
newItem->text = item_name;
|
||||
|
||||
// select the item if it's the first in the list
|
||||
if (gh2obj->cnt == 0)
|
||||
newItem->flags |= GLIST_FLG_SELECTED;
|
||||
|
||||
// add the new item to the list
|
||||
gfxQueueASyncPut(&gh2obj->list_head, &newItem->q_item);
|
||||
|
||||
// increment the total amount of entries in the list widget
|
||||
gh2obj->cnt++;
|
||||
|
||||
_gwidgetRedraw(gh);
|
||||
|
||||
// return the position in the list (-1 because we start with index 0)
|
||||
return gh2obj->cnt-1;
|
||||
}
|
||||
|
||||
const char* gwinListItemGetText(GHandle gh, int item) {
|
||||
const gfxQueueASyncItem* qi;
|
||||
int i;
|
||||
|
||||
// is it a valid handle?
|
||||
if (gh->vmt != (gwinVMT *)&listVMT)
|
||||
return 0;
|
||||
|
||||
// watch out for an invalid item
|
||||
if (item < 0 || item >= gh2obj->cnt)
|
||||
return 0;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if (i == item)
|
||||
return qi2li->text;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gwinListFindText(GHandle gh, const char* text) {
|
||||
const gfxQueueASyncItem* qi;
|
||||
int i;
|
||||
|
||||
// is it a valid handle?
|
||||
if (gh->vmt != (gwinVMT *)&listVMT)
|
||||
return -1;
|
||||
|
||||
// watch out for NULL pointers
|
||||
if (!text)
|
||||
return -1;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gh2obj->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;
|
||||
int i;
|
||||
|
||||
// is it a valid handle?
|
||||
if (gh->vmt != (gwinVMT *)&listVMT)
|
||||
return -1;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if (qi2li->flags & GLIST_FLG_SELECTED)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gwinListItemSetParam(GHandle gh, int item, uint16_t param) {
|
||||
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) - 1)
|
||||
return;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if (i == item) {
|
||||
qi2li->param = param;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gwinListDeleteAll(GHandle gh) {
|
||||
gfxQueueASyncItem* qi;
|
||||
|
||||
// is it a valid handle?
|
||||
if (gh->vmt != (gwinVMT *)&listVMT)
|
||||
return;
|
||||
|
||||
while((qi = gfxQueueASyncGet(&gh2obj->list_head)))
|
||||
gfxFree(qi);
|
||||
|
||||
gh2obj->cnt = 0;
|
||||
gh2obj->top = 0;
|
||||
_gwidgetRedraw(gh);
|
||||
}
|
||||
|
||||
void gwinListItemDelete(GHandle gh, int item) {
|
||||
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;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if (i == item) {
|
||||
gfxQueueASyncRemove(&gh2obj->list_head, (gfxQueueASyncItem*)qi);
|
||||
gfxFree((void *)qi);
|
||||
if (gh2obj->top >= item && gh2obj->top)
|
||||
gh2obj->top--;
|
||||
_gwidgetRedraw(gh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t gwinListItemGetParam(GHandle gh, int item) {
|
||||
const gfxQueueASyncItem * qi;
|
||||
int i;
|
||||
|
||||
// is it a valid handle?
|
||||
if (gh->vmt != (gwinVMT *)&listVMT)
|
||||
return 0;
|
||||
|
||||
// watch out for an invalid item
|
||||
if (item < 0 || item > (gh2obj->cnt) - 1)
|
||||
return 0;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if (i == item)
|
||||
return qi2li->param;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool_t gwinListItemIsSelected(GHandle gh, int item) {
|
||||
const gfxQueueASyncItem * qi;
|
||||
int i;
|
||||
|
||||
// is it a valid handle?
|
||||
if (gh->vmt != (gwinVMT *)&listVMT)
|
||||
return FALSE;
|
||||
|
||||
// watch out for an invalid item
|
||||
if (item < 0 || item > (gh2obj->cnt) - 1)
|
||||
return FALSE;
|
||||
|
||||
for(qi = gfxQueueASyncPeek(&gh2obj->list_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
|
||||
if (i == item)
|
||||
return (qi2li->flags & GLIST_FLG_SELECTED) ? TRUE : FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int gwinListItemCount(GHandle gh) {
|
||||
// is it a valid handle?
|
||||
if (gh->vmt != (gwinVMT *)&listVMT)
|
||||
return 0;
|
||||
|
||||
return gh2obj->cnt;
|
||||
}
|
||||
|
||||
#endif // GFX_USE_GWIN && GWIN_NEED_LIST
|
||||
|
Loading…
Reference in New Issue
Block a user