Clean up GWIN Event assignment. Optimise event efficiency.

ugfx_release_2.6
inmarket 2013-06-10 17:18:01 +10:00
parent 777ec6af7c
commit 2cb35d6815
25 changed files with 561 additions and 242 deletions

View File

@ -47,7 +47,7 @@
GHandle gwinCreateScope(GScopeObject *gs, coord_t x, coord_t y, coord_t cx, coord_t cy, uint32_t physdev, uint32_t frequency) { GHandle gwinCreateScope(GScopeObject *gs, coord_t x, coord_t y, coord_t cx, coord_t cy, uint32_t physdev, uint32_t frequency) {
/* Initialise the base class GWIN */ /* Initialise the base class GWIN */
if (!(gs = (GScopeObject *)_gwindowInit((GWindowObject *)gs, x, y, cx, cy, sizeof(GScopeObject)))) if (!(gs = (GScopeObject *)_gwindowCreate((GWindowObject *)gs, x, y, cx, cy, sizeof(GScopeObject))))
return 0; return 0;
/* Initialise the scope object members and allocate memory for buffers */ /* Initialise the scope object members and allocate memory for buffers */

View File

@ -54,7 +54,7 @@
GHandle gwinCreateScope(GScopeObject *gs, coord_t x, coord_t y, coord_t cx, coord_t cy, uint16_t channel, uint32_t frequency) { GHandle gwinCreateScope(GScopeObject *gs, coord_t x, coord_t y, coord_t cx, coord_t cy, uint16_t channel, uint32_t frequency) {
/* Initialise the base class GWIN */ /* Initialise the base class GWIN */
if (!(gs = (GScopeObject *)_gwindowInit((GWindowObject *)gs, x, y, cx, cy, sizeof(GScopeObject)))) if (!(gs = (GScopeObject *)_gwindowCreate((GWindowObject *)gs, x, y, cx, cy, sizeof(GScopeObject))))
return 0; return 0;
/* Initialise the scope object members and allocate memory for buffers */ /* Initialise the scope object members and allocate memory for buffers */

View File

@ -51,15 +51,17 @@
#define GDISP_NEED_IMAGE_PNG FALSE #define GDISP_NEED_IMAGE_PNG FALSE
/* Features for the GWIN sub-system. */ /* Features for the GWIN sub-system. */
#define GWIN_NEED_WINDOWMANAGER TRUE
#define GWIN_NEED_CONSOLE TRUE #define GWIN_NEED_CONSOLE TRUE
#define GWIN_NEED_GRAPH FALSE #define GWIN_NEED_GRAPH FALSE
#define GWIN_NEED_WIDGET TRUE
#define GWIN_NEED_BUTTON TRUE #define GWIN_NEED_BUTTON TRUE
#define GWIN_NEED_SLIDER TRUE #define GWIN_NEED_SLIDER TRUE
#define GWIN_NEED_CHECKBOX TRUE #define GWIN_NEED_CHECKBOX TRUE
/* Features for the GINPUT sub-system. */ /* Features for the GINPUT sub-system. */
#define GINPUT_NEED_MOUSE TRUE #define GINPUT_NEED_MOUSE TRUE
#define GINPUT_NEED_TOGGLE FALSE #define GINPUT_NEED_TOGGLE TRUE
#define GINPUT_NEED_DIAL FALSE #define GINPUT_NEED_DIAL FALSE
#endif /* _GFXCONF_H */ #endif /* _GFXCONF_H */

View File

@ -49,11 +49,20 @@ int main(void) {
gfxInit(); gfxInit();
gdispClear(White); gdispClear(White);
// Set the font and defalt colors // Set the widget defaults
gwinSetDefaultFont(gdispOpenFont("UI2")); gwinSetDefaultFont(gdispOpenFont("UI2"));
gwinSetDefaultColor(Black); gwinSetDefaultColor(Black);
gwinSetDefaultBgColor(White); gwinSetDefaultBgColor(White);
// We want to listen for widget events
geventListenerInit(&gl);
gwinAttachListener(&gl);
// Connect the mouse
#if GINPUT_NEED_MOUSE
gwinAttachMouse(0);
#endif
// Create out gwin windows/widgets // Create out gwin windows/widgets
ghConsole = gwinCreateConsole(NULL, ScrWidth/2+1, ScrHeight/2+1, ScrWidth/2-1, ScrHeight/2-1); ghConsole = gwinCreateConsole(NULL, ScrWidth/2+1, ScrHeight/2+1, ScrWidth/2-1, ScrHeight/2-1);
ghButton1 = gwinCreateButton(NULL, 0+0*(BUTTON_WIDTH+1), 0, BUTTON_WIDTH, BUTTON_HEIGHT); ghButton1 = gwinCreateButton(NULL, 0+0*(BUTTON_WIDTH+1), 0, BUTTON_WIDTH, BUTTON_HEIGHT);
@ -84,49 +93,28 @@ int main(void) {
gwinSetText(ghCheckbox1, "C1", FALSE); gwinSetText(ghCheckbox1, "C1", FALSE);
gwinSetText(ghCheckbox2, "C2", FALSE); gwinSetText(ghCheckbox2, "C2", FALSE);
// Assign the mouse and dials to the buttons & sliders etc. // Assign toggles and dials to the buttons & sliders etc.
#if GINPUT_NEED_MOUSE #if GINPUT_NEED_TOGGLE
gwinAttachMouse(ghButton1, 0); gwinAttachToggle(ghButton1, 0, 0);
gwinAttachMouse(ghButton2, 0); gwinAttachToggle(ghButton2, 0, 1);
gwinAttachMouse(ghButton3, 0); #endif
gwinAttachMouse(ghButton4, 0); #if GINPUT_NEED_DIAL
gwinAttachMouse(ghSlider1, 0); gwinAttachDial(ghSlider1, 0, 0);
gwinAttachMouse(ghSlider2, 0); gwinAttachDial(ghSlider3, 0, 1);
gwinAttachMouse(ghSlider3, 0); #endif
gwinAttachMouse(ghSlider4, 0);
gwinAttachMouse(ghCheckbox1, 0);
gwinAttachMouse(ghCheckbox2, 0);
#endif
#if GINPUT_NEED_DIAL
gwinAttachSliderDial(ghSlider1, 0);
gwinAttachSliderDial(ghSlider3, 1);
#endif
// We want to listen for widget events
geventListenerInit(&gl);
gwinAttachListener(ghButton1, &gl, 0);
gwinAttachListener(ghButton2, &gl, 0);
gwinAttachListener(ghButton3, &gl, 0);
gwinAttachListener(ghButton4, &gl, 0);
gwinAttachListener(ghSlider1, &gl, 0);
gwinAttachListener(ghSlider2, &gl, 0);
gwinAttachListener(ghSlider3, &gl, 0);
gwinAttachListener(ghSlider4, &gl, 0);
gwinAttachListener(ghCheckbox1, &gl, 0);
gwinAttachListener(ghCheckbox2, &gl, 0);
// Draw everything on the screen // Draw everything on the screen
gwinClear(ghConsole); gwinClear(ghConsole);
gwinDraw(ghButton1); gwinSetVisible(ghButton1, TRUE);
gwinDraw(ghButton2); gwinSetVisible(ghButton2, TRUE);
gwinDraw(ghButton3); gwinSetVisible(ghButton3, TRUE);
gwinDraw(ghButton4); gwinSetVisible(ghButton4, TRUE);
gwinDraw(ghSlider1); gwinSetVisible(ghSlider1, TRUE);
gwinDraw(ghSlider2); gwinSetVisible(ghSlider2, TRUE);
gwinDraw(ghSlider3); gwinSetVisible(ghSlider3, TRUE);
gwinDraw(ghSlider4); gwinSetVisible(ghSlider4, TRUE);
gwinDraw(ghCheckbox1); gwinSetVisible(ghCheckbox1, TRUE);
gwinDraw(ghCheckbox2); gwinSetVisible(ghCheckbox2, TRUE);
while(1) { while(1) {
// Get an Event // Get an Event

View File

@ -119,8 +119,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
break; break;
case WM_LBUTTONUP: case WM_LBUTTONUP:
#if GINPUT_NEED_TOGGLE #if GINPUT_NEED_TOGGLE
if ((toggles & 0xF0)) { if ((toggles & 0x0F)) {
toggles &= 0x0F; toggles &= ~0x0F;
rect.left = 0; rect.left = 0;
rect.right = wWidth; rect.right = wWidth;
rect.top = wHeight; rect.top = wHeight;

View File

@ -1,9 +1,9 @@
/* /*
* This file is subject to the terms of the GFX License, v1.0. If a copy of * This file is subject to the terms of the GFX License, v1.0. If a copy of
* the license was not distributed with this file, you can obtain one at: * the license was not distributed with this file, you can obtain one at:
* *
* http://chibios-gfx.com/license.html * http://chibios-gfx.com/license.html
*/ */
/** /**
* @file drivers/multiple/Win32/ginput_lld_toggle_config.h * @file drivers/multiple/Win32/ginput_lld_toggle_config.h
@ -20,19 +20,19 @@
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
#define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE // We are interrupt driven (or polled - ether works here) #define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE // We are interrupt driven (or polled - either works here)
#define GINPUT_TOGGLE_NUM_PORTS 8 // The total number of toggle inputs #define GINPUT_TOGGLE_NUM_PORTS 8 // The total number of toggle inputs
#define GINPUT_TOGGLE_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries #define GINPUT_TOGGLE_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries
#define GINPUT_TOGGLE_SW1 0 // Switch 1 - Toggle #define GINPUT_TOGGLE_MOMENTARY1 0 // Switch 5 - Momentary
#define GINPUT_TOGGLE_SW2 1 // Switch 2 - Toggle #define GINPUT_TOGGLE_MOMENTARY2 1 // Switch 6 - Momentary
#define GINPUT_TOGGLE_SW3 2 // Switch 3 - Toggle #define GINPUT_TOGGLE_MOMENTARY3 2 // Switch 7 - Momentary
#define GINPUT_TOGGLE_SW4 3 // Switch 4 - Toggle #define GINPUT_TOGGLE_MOMENTARY4 3 // Switch 8 - Momentary
#define GINPUT_TOGGLE_MOMENTARY1 4 // Switch 5 - Momentary #define GINPUT_TOGGLE_SW1 4 // Switch 1 - Toggle
#define GINPUT_TOGGLE_MOMENTARY2 5 // Switch 6 - Momentary #define GINPUT_TOGGLE_SW2 5 // Switch 2 - Toggle
#define GINPUT_TOGGLE_MOMENTARY3 6 // Switch 7 - Momentary #define GINPUT_TOGGLE_SW3 6 // Switch 3 - Toggle
#define GINPUT_TOGGLE_MOMENTARY4 7 // Switch 8 - Momentary #define GINPUT_TOGGLE_SW4 7 // Switch 4 - Toggle
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */ #endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */

View File

@ -46,24 +46,6 @@
#warning "GWIN: Drawing can occur outside the defined windows as GDISP_NEED_CLIP is FALSE" #warning "GWIN: Drawing can occur outside the defined windows as GDISP_NEED_CLIP is FALSE"
#endif #endif
#endif #endif
#if GWIN_NEED_WINDOWMANAGER
#if !GFX_USE_GQUEUE || !GQUEUE_NEED_ASYNC
#if GFX_DISPLAY_RULE_WARNINGS
#warning "GWIN: GFX_USE_GQUEUE and GQUEUE_NEED_ASYNC is required if GWIN_NEED_WINDOWMANAGER is TRUE. It has been turned on for you."
#endif
#undef GFX_USE_GQUEUE
#undef GQUEUE_NEED_ASYNC
#define GFX_USE_GQUEUE TRUE
#define GQUEUE_NEED_ASYNC TRUE
#endif
#endif
#if GWIN_NEED_CONSOLE
#if !GDISP_NEED_TEXT
#error "GWIN: GDISP_NEED_TEXT is required if GWIN_NEED_CONSOLE is TRUE."
#endif
#endif
#if GWIN_NEED_GRAPH
#endif
#if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX #if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX
#if !GWIN_NEED_WIDGET #if !GWIN_NEED_WIDGET
#if GFX_DISPLAY_RULE_WARNINGS #if GFX_DISPLAY_RULE_WARNINGS
@ -81,6 +63,13 @@
// This test also ensures that GFX_USE_GEVENT is set // This test also ensures that GFX_USE_GEVENT is set
#error "GWIN: GFX_USE_GINPUT (and one or more input sources) is required if GWIN_NEED_WIDGET is TRUE" #error "GWIN: GFX_USE_GINPUT (and one or more input sources) is required if GWIN_NEED_WIDGET is TRUE"
#endif #endif
#if !GWIN_NEED_WINDOWMANAGER
#if GFX_DISPLAY_RULE_WARNINGS
#warning "GWIN: GWIN_NEED_WINDOWMANAGER is required if GWIN_NEED_WIDGET is TRUE. It has been turned on for you."
#endif
#undef GWIN_NEED_WINDOWMANAGER
#define GWIN_NEED_WINDOWMANAGER TRUE
#endif
#if !GDISP_NEED_MULTITHREAD && !GDISP_NEED_ASYNC #if !GDISP_NEED_MULTITHREAD && !GDISP_NEED_ASYNC
#if GFX_DISPLAY_RULE_WARNINGS #if GFX_DISPLAY_RULE_WARNINGS
#warning "GWIN: Either GDISP_NEED_MULTITHREAD or GDISP_NEED_ASYNC is required if GWIN_NEED_WIDGET is TRUE." #warning "GWIN: Either GDISP_NEED_MULTITHREAD or GDISP_NEED_ASYNC is required if GWIN_NEED_WIDGET is TRUE."
@ -90,6 +79,24 @@
#define GDISP_NEED_MULTITHREAD TRUE #define GDISP_NEED_MULTITHREAD TRUE
#endif #endif
#endif #endif
#if GWIN_NEED_WINDOWMANAGER
#if !GFX_USE_GQUEUE || !GQUEUE_NEED_ASYNC
#if GFX_DISPLAY_RULE_WARNINGS
#warning "GWIN: GFX_USE_GQUEUE and GQUEUE_NEED_ASYNC is required if GWIN_NEED_WINDOWMANAGER is TRUE. It has been turned on for you."
#endif
#undef GFX_USE_GQUEUE
#undef GQUEUE_NEED_ASYNC
#define GFX_USE_GQUEUE TRUE
#define GQUEUE_NEED_ASYNC TRUE
#endif
#endif
#if GWIN_NEED_CONSOLE
#if !GDISP_NEED_TEXT
#error "GWIN: GDISP_NEED_TEXT is required if GWIN_NEED_CONSOLE is TRUE."
#endif
#endif
#if GWIN_NEED_GRAPH
#endif
#endif #endif
#if GFX_USE_GINPUT #if GFX_USE_GINPUT

View File

@ -36,6 +36,7 @@ typedef struct GEventDial_t {
GEventType type; // The type of this event (GEVENT_DIAL) GEventType type; // The type of this event (GEVENT_DIAL)
uint16_t instance; // The dial instance uint16_t instance; // The dial instance
uint16_t value; // The dial value uint16_t value; // The dial value
uint16_t maxvalue; // The maximum dial value
} GEventDial; } GEventDial;
/*===========================================================================*/ /*===========================================================================*/

View File

@ -103,7 +103,7 @@ void gfxQueueFSyncInit(gfxQueueFSync *pqueue);
/* @} */ /* @} */
/** /**
* @brief Get an item from the head of the queue. * @brief Get an item from the head of the queue (and remove it from the queue).
* @return NULL if the timeout expires before an item is available * @return NULL if the timeout expires before an item is available
* *
* @param[in] pqueue A pointer to the queue * @param[in] pqueue A pointer to the queue
@ -139,7 +139,7 @@ bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delayti
/* @} */ /* @} */
/** /**
* @brief Pop an item from the head of the queue. * @brief Pop an item from the head of the queue (and remove it from the queue).
* @detail This is exactly the same as the Get operation above. * @detail This is exactly the same as the Get operation above.
* *
* @api * @api
@ -220,6 +220,46 @@ bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem); bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem);
/* @} */ /* @} */
/**
* @brief Get the first item from the head of the queue but do not remove it from the queue.
* @return NULL if no item is available.
*
* @param[in] pqueue A pointer to the queue
*
* @note This call does not block.
* @note This can be used as the first call to iterate all the elements in the queue.
* @note As that item is still on the queue, it should be treated as read-only. It could
* also be removed from the queue at any time by another thread (thereby altering the
* queue item).
*
* @api
* @{
*/
#define gfxQueueASyncPeek(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head))
#define gfxQueueGSyncPeek(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head))
#define gfxQueueFSyncPeek(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head))
/* @} */
/**
* @brief Get the next item in the queue (but do not remove it from the queue).
* @return NULL if no item is available.
*
* @param[in] pitem The previous item in the queue
*
* @note This call does not block.
* @note This can be used as subsequent calls to iterate all the elements in the queue.
* @note As that item is still on the queue, it should be treated as read-only. It could
* also be removed from the queue at any time by another thread (thereby altering the
* queue item).
*
* @api
* @{
*/
#define gfxQueueASyncNext(pitem) ((const gfxQueueASyncItem *)((pitem)->next))
#define gfxQueueGSyncNext(pitem) ((const gfxQueueGSyncItem *)((pitem)->next))
#define gfxQueueFSyncNext(pitem) ((const gfxQueueFSyncItem *)((pitem)->next))
/* @} */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -55,6 +55,7 @@ typedef struct GButtonColors {
*/ */
typedef struct GButtonObject_t { typedef struct GButtonObject_t {
GWidgetObject w; GWidgetObject w;
uint16_t toggle;
GButtonColors c_up; GButtonColors c_up;
GButtonColors c_dn; GButtonColors c_dn;
GButtonColors c_dis; GButtonColors c_dis;
@ -78,10 +79,13 @@ extern "C" {
* @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there * @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 no nothing. * is no default font and text drawing operations will no nothing.
* @note The dimensions and position may be changed to fit on the real screen. * @note The dimensions and position may be changed to fit on the real screen.
* @note A button remembers its normal button state. If there is a window manager then it is automatically * @note A button 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. * redrawn if the window is moved or its visibility state is changed.
* @note The button is initially marked as invisible so that more properties can be set before display. * @note The button is initially marked as invisible so that more properties can be set before display.
* Call @p gwinSetVisible() to display it when ready. * Call @p gwinSetVisible() to display it when ready.
* @note A button supports mouse and a toggle input.
* @note When assigning a toggle, only one toggle is supported. If you try to assign more than one toggle it will
* forget the previous toggle. When assigning a toggle the role parameter must be 0.
* *
* @api * @api
*/ */

View File

@ -50,6 +50,7 @@ typedef struct GCheckboxColors {
/* A Checkbox window */ /* A Checkbox window */
typedef struct GCheckboxObject_t { typedef struct GCheckboxObject_t {
GWidgetObject w; GWidgetObject w;
uint16_t toggle;
GCheckboxColors c; GCheckboxColors c;
} GCheckboxObject; } GCheckboxObject;
@ -62,10 +63,18 @@ typedef struct GCheckboxObject_t {
* @param[in] width The width of the window * @param[in] width The width of the window
* @param[in] height The height of the window * @param[in] height The height of the window
* *
* @note The drawing color gets set to White and the background drawing color to Black. * @note The drawing color and the background color get set to the current defaults. If you haven't called
* @note Don't forget to set the font using @p gwinSetFont() or @p gwinSetDefaultFont() * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
* @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 no nothing.
* @note The dimensions and position may be changed to fit on the real screen. * @note The dimensions and position may be changed to fit on the real screen.
* @note The checkbox is not automatically drawn. Call gwinDraw() to draw it. * @note A checkbox 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 checkbox is initially marked as invisible so that more properties can be set before display.
* Call @p gwinSetVisible() to display it when ready.
* @note A checkbox supports mouse and a toggle input.
* @note When assigning a toggle, only one toggle is supported. If you try to assign more than one toggle it will
* forget the previous toggle. When assigning a toggle the role parameter must be 0.
* *
* @api * @api
*/ */

View File

@ -52,37 +52,58 @@ typedef struct gwinVMT {
/* @} */ /* @} */
#if GWIN_NEED_WIDGET || defined(__DOXYGEN__) #if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
/**
* @brief An toggle/dial instance is not being used
*/
#define GWIDGET_NO_INSTANCE ((uint16_t)-1)
/**
* @brief The source handle that widgets use when sending events
*/
#define GWIDGET_SOURCE ((GSourceHandle)(void *)_gwidgetCreate)
/** /**
* @brief The Virtual Method Table for a widget * @brief The Virtual Method Table for a widget
* @note A widget must have a destroy function. Either use @p _gwidgetDestroy() or use your own function * @note A widget must have a destroy function. Either use @p _gwidgetDestroy() or use your own function
* which internally calls @p _gwidgetDestroy(). * which internally calls @p _gwidgetDestroy().
* @note A widget must have a redraw function. Use @p _gwidgetRedraw(). * @note A widget must have a redraw function. Use @p _gwidgetRedraw().
* @note If no MouseDown(), MouseUp() or MouseMove() function is provided, the widget will not accept being attached to a mouse input source. * @note If toggleroles != 0, ToggleAssign(), ToggleGet() and one or both of ToggleOff() and ToggleOn() must be specified.
* @note If no ToggleOn() or ToggleOff() function is provided, the widget will not accept being attached to a toggle input source. * @note If dialroles != 0, DialAssign(), DialGet() and DialMove() must be specified.
* @note If no DialMove() function is provided, the widget will not accept being attached to a dial input source.
* @note AssignToggle() and AssignDial() enable a widget to handle more than one toggle/dial device attached to the widget.
* For example, a slider might accept two toggles, one for slider-down and one for slider-up.
* The function enables the widget to record that a particular device instance performs each particular role.
* (eg toggle0 = slider-down, toggle1 = slider-up).
* @{ * @{
*/ */
typedef struct gwidgetVMT { typedef struct gwidgetVMT {
struct gwinVMT g; // @< This is still a GWIN struct gwinVMT g; // @< This is still a GWIN
void (*DefaultDraw) (GWidgetObject *gw, void *param); // @< The default drawing routine (mandatory) void (*DefaultDraw) (GWidgetObject *gw, void *param); // @< The default drawing routine (mandatory)
void (*MouseDown) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse down events (optional) struct {
void (*MouseUp) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse up events (optional) void (*MouseDown) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse down events (optional)
void (*MouseMove) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse move events (optional) void (*MouseUp) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse up events (optional)
void (*ToggleOff) (GWidgetObject *gw, uint16_t instance); // @< Process toggle off events (optional) void (*MouseMove) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse move events (optional)
void (*ToggleOn) (GWidgetObject *gw, uint16_t instance); // @< Process toggle on events (optional) };
void (*DialMove) (GWidgetObject *gw, uint16_t instance, uint16_t value); // @< Process dial move events (optional) struct {
void (*AllEvents) (GWidgetObject *gw, GEvent *pe); // @< Process all events (optional) uint16_t toggleroles; // @< The roles supported for toggles (0->toggleroles-1)
bool_t (*AssignToggle) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Test the role and save the toggle instance handle (optional) void (*ToggleAssign) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Assign a toggle to a role (optional)
bool_t (*AssignDial) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Test the role and save the dial instance handle (optional) uint16_t (*ToggleGet) (GWidgetObject *gw, uint16_t role); // @< Return the instance for a particular role (optional)
void (*ToggleOff) (GWidgetObject *gw, uint16_t role); // @< Process toggle off events (optional)
void (*ToggleOn) (GWidgetObject *gw, uint16_t role); // @< Process toggle on events (optional)
};
struct {
uint16_t dialroles; // @< The roles supported for dials (0->dialroles-1)
void (*DialAssign) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Test the role and save the dial instance handle (optional)
uint16_t (*DialGet) (GWidgetObject *gw, uint16_t role); // @< Return the instance for a particular role (optional)
void (*DialMove) (GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max); // @< Process dial move events (optional)
};
} gwidgetVMT; } gwidgetVMT;
/* @} */ /* @} */
#endif #endif
#if GWIN_NEED_WINDOWMANAGER || defined(__DOXYGEN__) #if GWIN_NEED_WINDOWMANAGER || defined(__DOXYGEN__)
#if 1 // When we know that wmq is the first element of the GWindowObject structure
#define QItem2GWindow(qi) ((GHandle)qi)
#else
#define QItem2GWindow(qi) ((GHandle)(((char *)(qi)) - (size_t)(&(((GWindowObject *)0)->wmq))))
#endif
// @note There is only ever one instance of each GWindowManager type // @note There is only ever one instance of each GWindowManager type
typedef struct GWindowManager { typedef struct GWindowManager {
const struct gwmVMT *vmt; const struct gwmVMT *vmt;
@ -126,7 +147,7 @@ extern "C" {
* *
* @notapi * @notapi
*/ */
GHandle _gwindowInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t w, coord_t h, size_t size, const gwinVMT *vmt, uint16_t flags); GHandle _gwindowCreate(GWindowObject *pgw, coord_t x, coord_t y, coord_t w, coord_t h, size_t size, const gwinVMT *vmt, uint16_t flags);
#if GWIN_NEED_WIDGET || defined(__DOXYGEN__) #if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
/** /**
@ -140,7 +161,7 @@ GHandle _gwindowInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t w, coord_
* *
* @notapi * @notapi
*/ */
GHandle _gwidgetInit(GWidgetObject *pgw, coord_t x, coord_t y, coord_t w, coord_t h, size_t size, const gwidgetVMT *vmt); GHandle _gwidgetCreate(GWidgetObject *pgw, coord_t x, coord_t y, coord_t w, coord_t h, size_t size, const gwidgetVMT *vmt);
/** /**
* @brief Destroy the Widget object * @brief Destroy the Widget object

View File

@ -46,7 +46,6 @@ typedef void (*CustomWidgetDrawFunction)(struct GWidgetObject *gw, void *param);
*/ */
typedef struct GWidgetObject { typedef struct GWidgetObject {
GWindowObject g; // @< This is still a GWIN GWindowObject g; // @< This is still a GWIN
GListener listener; // @< The widget listener
const char * txt; // @< The widget text const char * txt; // @< The widget text
CustomWidgetDrawFunction fnDraw; // @< The current draw function CustomWidgetDrawFunction fnDraw; // @< The current draw function
void * fnParam; // @< A parameter for the current draw function void * fnParam; // @< A parameter for the current draw function
@ -120,28 +119,27 @@ const char *gwinGetText(GHandle gh);
void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param); void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param);
/** /**
* @brief Attach a Listener to this widget * @brief Attach a Listener to listen for widget events
* @return TRUE on success * @return TRUE on success
* *
* @param[in] gh The widget handle
* @param[in] pl The listener * @param[in] pl The listener
* @param[in] flags Flags to use for listening. For most widgets this should be 0.
* *
* @api * @api
*/ */
bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags); bool_t gwinAttachListener(GListener *pl);
#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
/** /**
* @brief Attach a mouse to a widget * @brief Set the mouse to be used to control the widgets
* @return TRUE on success * @return TRUE on success
* *
* @param[in] gh The widget handle
* @param[in] instance The mouse instance * @param[in] instance The mouse instance
* *
* @note Every widget uses the same mouse.
*
* @api * @api
*/ */
bool_t gwinAttachMouse(GHandle gh, uint16_t instance); bool_t gwinAttachMouse(uint16_t instance);
#endif #endif
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE

View File

@ -35,6 +35,7 @@
*/ */
typedef struct GWindowObject { typedef struct GWindowObject {
#if GWIN_NEED_WINDOWMANAGER #if GWIN_NEED_WINDOWMANAGER
// This MUST be the first member of the struct
gfxQueueASyncItem wmq; // @< The next window (for the window manager) gfxQueueASyncItem wmq; // @< The next window (for the window manager)
#endif #endif
const struct gwinVMT *vmt; // @< The VMT for this GWIN const struct gwinVMT *vmt; // @< The VMT for this GWIN

View File

@ -21,11 +21,11 @@
* @{ * @{
*/ */
/** /**
* @brief Should a window manager be used. * @brief Should window manager support be included
* @details Defaults to FALSE * @details Defaults to FALSE
*/ */
#ifndef GWIN_NEED_WINDOWMANAGER #ifndef GWIN_NEED_WINDOWMANAGER
#define GWIN_NEED_WINDOWMANAGER FALSE #define GWIN_NEED_WIDGET FALSE
#endif #endif
/** /**
* @brief Should widget functions be included. Needed for any widget (eg Buttons, Sliders etc) * @brief Should widget functions be included. Needed for any widget (eg Buttons, Sliders etc)

View File

@ -45,11 +45,14 @@ typedef struct GSliderColors {
// A slider window // A slider window
typedef struct GSliderObject_t { typedef struct GSliderObject_t {
GWidgetObject w; GWidgetObject w;
GSliderColors c; uint16_t t_dn;
uint16_t t_up;
uint16_t dial;
coord_t dpos; coord_t dpos;
int min; int min;
int max; int max;
int pos; int pos;
GSliderColors c;
} GSliderObject; } GSliderObject;
#ifdef __cplusplus #ifdef __cplusplus
@ -65,11 +68,22 @@ extern "C" {
* @param[in] width The width of the window * @param[in] width The width of the window
* @param[in] height The height of the window * @param[in] height The height of the window
* *
* @note The drawing color gets set to White and the background drawing color to Black. * @note The drawing color and the background color get set to the current defaults. If you haven't called
* @note Don't forget to set the font using @p gwinSetFont() or @p gwinSetDefaultFont() * @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
* @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 no nothing.
* @note The dimensions and position may be changed to fit on the real screen. * @note The dimensions and position may be changed to fit on the real screen.
* @note The slider is not automatically drawn. Call gwinDraw() to draw it. * @note A slider remembers its normal drawing state. If there is a window manager then it is automatically
* @note Sets the slider range from 0 to 100 with an initial position of 0 * redrawn if the window is moved or its visibility state is changed.
* @note The slider is initially marked as invisible so that more properties can be set before display.
* Call @p gwinSetVisible() to display it when ready.
* @note The initial slider range is from 0 to 100 with an initial position of 0.
* @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.
* *
* @api * @api
*/ */

View File

@ -57,6 +57,7 @@ static void DialCallback(uint16_t instance, uint16_t rawvalue) {
pe->type = GEVENT_DIAL; pe->type = GEVENT_DIAL;
pe->instance = instance; pe->instance = instance;
pe->value = pds->lastvalue; pe->value = pds->lastvalue;
pe->maxvalue = pds->max;
geventSendEvent(psl); geventSendEvent(psl);
} }
} }
@ -144,6 +145,7 @@ bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial) {
pdial->type = GEVENT_DIAL; pdial->type = GEVENT_DIAL;
pdial->instance = instance; pdial->instance = instance;
pdial->value = DialStatus[instance].lastvalue; pdial->value = DialStatus[instance].lastvalue;
pdial->maxvalue = DialStatus[instance].max;
return TRUE; return TRUE;
} }

View File

@ -37,6 +37,7 @@
gfxSystemLock(); gfxSystemLock();
if ((pi = pqueue->head)) if ((pi = pqueue->head))
pqueue->head = pi->next; pqueue->head = pi->next;
pi->next = 0;
gfxSystemUnlock(); gfxSystemUnlock();
return pi; return pi;
} }
@ -68,12 +69,14 @@
if (pqueue->head) { if (pqueue->head) {
if (pqueue->head == pitem) { if (pqueue->head == pitem) {
pqueue->head = pitem->next; pqueue->head = pitem->next;
pitem->next = 0;
} else { } else {
for(pi = pqueue->head; pi->next; pi = pi->next) { for(pi = pqueue->head; pi->next; pi = pi->next) {
if (pi->next == pitem) { if (pi->next == pitem) {
pi->next = pitem->next; pi->next = pitem->next;
if (pqueue->tail == pitem) if (pqueue->tail == pitem)
pqueue->tail = pi; pqueue->tail = pi;
pitem->next = 0;
break; break;
} }
} }
@ -111,6 +114,7 @@
gfxSystemLock(); gfxSystemLock();
pi = pqueue->head; pi = pqueue->head;
pqueue->head = pi->next; pqueue->head = pi->next;
pi->next = 0;
gfxSytemUnlock(); gfxSytemUnlock();
return pi; return pi;
} }
@ -146,12 +150,14 @@
if (pqueue->head) { if (pqueue->head) {
if (pqueue->head == pitem) { if (pqueue->head == pitem) {
pqueue->head = pitem->next; pqueue->head = pitem->next;
pitem->next = 0;
} else { } else {
for(pi = pqueue->head; pi->next; pi = pi->next) { for(pi = pqueue->head; pi->next; pi = pi->next) {
if (pi->next == pitem) { if (pi->next == pitem) {
pi->next = pitem->next; pi->next = pitem->next;
if (pqueue->tail == pitem) if (pqueue->tail == pitem)
pqueue->tail = pi; pqueue->tail = pi;
pitem->next = 0;
break; break;
} }
} }
@ -189,6 +195,7 @@
gfxSystemLock(); gfxSystemLock();
pi = pqueue->head; pi = pqueue->head;
pqueue->head = pi->next; pqueue->head = pi->next;
pi->next = 0;
gfxSytemUnlock(); gfxSytemUnlock();
gfxSemSignalI(&pi->sem); gfxSemSignalI(&pi->sem);
@ -233,6 +240,7 @@
if (pqueue->head == pitem) { if (pqueue->head == pitem) {
pqueue->head = pitem->next; pqueue->head = pitem->next;
found: found:
pitem->next = 0;
gfxSystemUnlock(); gfxSystemUnlock();
gfxSemSignal(&pitem->sem); gfxSemSignal(&pitem->sem);
gfxSemDestroy(&pitem->sem); gfxSemDestroy(&pitem->sem);

View File

@ -32,8 +32,10 @@
// Prototypes for button VMT functions // Prototypes for button VMT functions
static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y); static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y);
static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y);
static void ToggleOff(GWidgetObject *gw, uint16_t instance); static void ToggleOff(GWidgetObject *gw, uint16_t role);
static void ToggleOn(GWidgetObject *gw, uint16_t instance); static void ToggleOn(GWidgetObject *gw, uint16_t role);
static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance);
static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role);
// The button VMT table // The button VMT table
static const gwidgetVMT buttonVMT = { static const gwidgetVMT buttonVMT = {
@ -43,16 +45,25 @@ static const gwidgetVMT buttonVMT = {
_gwidgetRedraw, // The redraw routine _gwidgetRedraw, // The redraw routine
0, // The after-clear routine 0, // The after-clear routine
}, },
gwinButtonDraw_3D, // The default drawing routine gwinButtonDraw_3D, // The default drawing routine
MouseDown, // Process mouse down events {
MouseUp, // Process mouse up events MouseDown, // Process mouse down events
0, // Process mouse move events (NOT USED) MouseUp, // Process mouse up events
ToggleOff, // Process toggle off events 0, // Process mouse move events (NOT USED)
ToggleOn, // Process toggle on events },
0, // Process dial move events (NOT USED) {
0, // Process all events (NOT USED) 1, // 1 toggle role
0, // AssignToggle (NOT USED) ToggleAssign, // Assign Toggles
0, // AssignDial (NOT USED) ToggleGet, // Get Toggles
ToggleOff, // Process toggle off events
ToggleOn, // Process toggle on events
},
{
0, // No dial roles
0, // Assign Dials (NOT USED)
0, // Get Dials (NOT USED)
0, // Process dial move events (NOT USED)
}
}; };
// Default color scheme // Default color scheme
@ -80,7 +91,7 @@ static void SendButtonEvent(GWidgetObject *gw) {
// Trigger a GWIN Button Event // Trigger a GWIN Button Event
psl = 0; psl = 0;
while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
if (!(pe = geventGetEventBuffer(psl))) if (!(pe = geventGetEventBuffer(psl)))
continue; continue;
pbe->type = GEVENT_GWIN_BUTTON; pbe->type = GEVENT_GWIN_BUTTON;
@ -114,25 +125,36 @@ static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) {
} }
// A toggle off has occurred // A toggle off has occurred
static void ToggleOff(GWidgetObject *gw, uint16_t instance) { static void ToggleOff(GWidgetObject *gw, uint16_t role) {
(void) instance; (void) role;
gw->g.flags &= ~GBUTTON_FLG_PRESSED; gw->g.flags &= ~GBUTTON_FLG_PRESSED;
_gwidgetRedraw((GHandle)gw); _gwidgetRedraw((GHandle)gw);
} }
// A toggle on has occurred // A toggle on has occurred
static void ToggleOn(GWidgetObject *gw, uint16_t instance) { static void ToggleOn(GWidgetObject *gw, uint16_t role) {
(void) instance; (void) role;
gw->g.flags |= GBUTTON_FLG_PRESSED; gw->g.flags |= GBUTTON_FLG_PRESSED;
_gwidgetRedraw((GHandle)gw); _gwidgetRedraw((GHandle)gw);
// Trigger the event on button down (different than for mouse/touch) // Trigger the event on button down (different than for mouse/touch)
SendButtonEvent(gw); SendButtonEvent(gw);
} }
static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) {
(void) role;
((GButtonObject *)gw)->toggle = instance;
}
static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) {
(void) role;
return ((GButtonObject *)gw)->toggle;
}
GHandle gwinCreateButton(GButtonObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateButton(GButtonObject *gw, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gw = (GButtonObject *)_gwidgetInit((GWidgetObject *)gw, x, y, width, height, sizeof(GButtonObject), &buttonVMT))) if (!(gw = (GButtonObject *)_gwidgetCreate((GWidgetObject *)gw, x, y, width, height, sizeof(GButtonObject), &buttonVMT)))
return 0; return 0;
gw->toggle = GWIDGET_NO_INSTANCE;
gw->c_up = GButtonDefaultColorsUp; gw->c_up = GButtonDefaultColorsUp;
gw->c_dn = GButtonDefaultColorsDown; gw->c_dn = GButtonDefaultColorsDown;
gw->c_dis = GButtonDefaultColorsDisabled; gw->c_dis = GButtonDefaultColorsDisabled;

View File

@ -26,7 +26,9 @@
// Prototypes for button VMT functions // Prototypes for button VMT functions
static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y); static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y);
static void ToggleOn(GWidgetObject *gw, uint16_t instance); static void ToggleOn(GWidgetObject *gw, uint16_t role);
static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance);
static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role);
// The button VMT table // The button VMT table
static const gwidgetVMT checkboxVMT = { static const gwidgetVMT checkboxVMT = {
@ -37,15 +39,24 @@ static const gwidgetVMT checkboxVMT = {
0, // The after-clear routine 0, // The after-clear routine
}, },
gwinCheckboxDraw_CheckOnLeft, // The default drawing routine gwinCheckboxDraw_CheckOnLeft, // The default drawing routine
MouseDown, // Process mouse down events {
0, // Process mouse up events (NOT USED) MouseDown, // Process mouse down events
0, // Process mouse move events (NOT USED) 0, // Process mouse up events (NOT USED)
0, // Process toggle off events (NOT USED) 0, // Process mouse move events (NOT USED)
ToggleOn, // Process toggle on events },
0, // Process dial move events (NOT USED) {
0, // Process all events (NOT USED) 1, // 1 toggle role
0, // AssignToggle (NOT USED) ToggleAssign, // Assign Toggles
0, // AssignDial (NOT USED) ToggleGet, // Get Toggles
0, // Process toggle off events (NOT USED)
ToggleOn, // Process toggle on events
},
{
0, // No dial roles
0, // Assign Dials (NOT USED)
0, // Get Dials (NOT USED)
0, // Process dial move events (NOT USED)
}
}; };
static const GCheckboxColors defaultColors = { static const GCheckboxColors defaultColors = {
@ -63,7 +74,7 @@ static void SendCheckboxEvent(GWidgetObject *gw) {
// Trigger a GWIN Checkbox Event // Trigger a GWIN Checkbox Event
psl = 0; psl = 0;
while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
if (!(pe = geventGetEventBuffer(psl))) if (!(pe = geventGetEventBuffer(psl)))
continue; continue;
pce->type = GEVENT_GWIN_CHECKBOX; pce->type = GEVENT_GWIN_CHECKBOX;
@ -84,17 +95,28 @@ static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
} }
// A toggle on has occurred // A toggle on has occurred
static void ToggleOn(GWidgetObject *gw, uint16_t instance) { static void ToggleOn(GWidgetObject *gw, uint16_t role) {
(void) instance; (void) role;
gw->g.flags ^= GCHECKBOX_FLG_CHECKED; gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
_gwidgetRedraw((GHandle)gw); _gwidgetRedraw((GHandle)gw);
SendCheckboxEvent(gw); SendCheckboxEvent(gw);
} }
static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) {
(void) role;
((GCheckboxObject *)gw)->toggle = instance;
}
static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) {
(void) role;
return ((GCheckboxObject *)gw)->toggle;
}
GHandle gwinCreateCheckbox(GCheckboxObject *gb, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateCheckbox(GCheckboxObject *gb, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gb = (GCheckboxObject *)_gwidgetInit((GWidgetObject *)gb, x, y, width, height, sizeof(GCheckboxObject), &checkboxVMT))) if (!(gb = (GCheckboxObject *)_gwidgetCreate((GWidgetObject *)gb, x, y, width, height, sizeof(GCheckboxObject), &checkboxVMT)))
return 0; return 0;
gb->toggle = (uint16_t) -1;
gb->c = defaultColors; // assign the default colors gb->c = defaultColors; // assign the default colors
return (GHandle)gb; return (GHandle)gb;
} }

View File

@ -66,7 +66,7 @@ static const gwinVMT consoleVMT = {
}; };
GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateConsole(GConsoleObject *gc, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gc = (GConsoleObject *)_gwindowInit((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT, GWIN_FLG_VISIBLE))) if (!(gc = (GConsoleObject *)_gwindowCreate((GWindowObject *)gc, x, y, width, height, sizeof(GConsoleObject), &consoleVMT, GWIN_FLG_VISIBLE)))
return 0; return 0;
#if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM #if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
gc->stream.vmt = &GWindowConsoleVMT; gc->stream.vmt = &GWindowConsoleVMT;

View File

@ -165,7 +165,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t
} }
GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateGraph(GGraphObject *gg, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gg = (GGraphObject *)_gwindowInit((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT, GWIN_FLG_VISIBLE))) if (!(gg = (GGraphObject *)_gwindowCreate((GWindowObject *)gg, x, y, width, height, sizeof(GGraphObject), &graphVMT, GWIN_FLG_VISIBLE)))
return 0; return 0;
gg->xorigin = gg->yorigin = 0; gg->xorigin = gg->yorigin = 0;
gg->lastx = gg->lasty = 0; gg->lastx = gg->lasty = 0;

View File

@ -13,23 +13,25 @@
#include "gwin/class_gwin.h" #include "gwin/class_gwin.h"
/* Our listener for events for widgets */
static GListener gl;
/* We use these everywhere in this file */ /* We use these everywhere in this file */
#define gw ((GWidgetObject *)gh) #define gw ((GWidgetObject *)gh)
#define wvmt ((gwidgetVMT *)gh->vmt) #define wvmt ((gwidgetVMT *)gh->vmt)
static void gwidgetCallback(void *param, GEvent *pe) { /* Process an event */
#define gh ((GWindowObject *)param) static void gwidgetEvent(void *param, GEvent *pe) {
#define gh QItem2GWindow(qi)
#define pme ((GEventMouse *)pe) #define pme ((GEventMouse *)pe)
#define pte ((GEventToggle *)pe) #define pte ((GEventToggle *)pe)
#define pde ((GEventDial *)pe) #define pde ((GEventDial *)pe)
// check if widget is disabled const gfxQueueASyncItem * qi;
if ((gw->g.flags & (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) #if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL)
return; uint16_t role;
#endif
// Process via AllEvents() if it is defined (void) param;
if (wvmt->AllEvents)
wvmt->AllEvents(gw, pe);
// Process various events // Process various events
switch (pe->type) { switch (pe->type) {
@ -37,76 +39,179 @@ static void gwidgetCallback(void *param, GEvent *pe) {
#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
case GEVENT_MOUSE: case GEVENT_MOUSE:
case GEVENT_TOUCH: case GEVENT_TOUCH:
// Are we captured? // Cycle through all windows
if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) { for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
if ((pme->last_buttons & ~pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) {
gw->g.flags &= ~GWIN_FLG_MOUSECAPTURE;
if (wvmt->MouseUp)
wvmt->MouseUp(gw, pme->x - gw->g.x, pme->y - gw->g.y);
return;
} else if (wvmt->MouseMove)
wvmt->MouseMove(gw, pme->x - gw->g.x, pme->y - gw->g.y);
// We are not captured - look for mouse downs over the widget // check if it a widget that is enabled and visible
} else if ((~pme->last_buttons & pme->current_buttons & GINPUT_MOUSE_BTN_LEFT) if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE))
&& pme->x >= gw->g.x && pme->x < gw->g.x + gw->g.width continue;
&& pme->y >= gw->g.y && pme->y < gw->g.y + gw->g.height) {
gw->g.flags |= GWIN_FLG_MOUSECAPTURE; // Are we captured?
if (wvmt->MouseDown) if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) {
wvmt->MouseDown(gw, pme->x - gw->g.x, pme->y - gw->g.y); if ((pme->last_buttons & ~pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) {
gw->g.flags &= ~GWIN_FLG_MOUSECAPTURE;
if (wvmt->MouseUp)
wvmt->MouseUp(gw, pme->x - gw->g.x, pme->y - gw->g.y);
} else if (wvmt->MouseMove)
wvmt->MouseMove(gw, pme->x - gw->g.x, pme->y - gw->g.y);
// We are not captured - look for mouse downs over the widget
} else if ((~pme->last_buttons & pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)
&& pme->x >= gw->g.x && pme->x < gw->g.x + gw->g.width
&& pme->y >= gw->g.y && pme->y < gw->g.y + gw->g.height) {
gw->g.flags |= GWIN_FLG_MOUSECAPTURE;
if (wvmt->MouseDown)
wvmt->MouseDown(gw, pme->x - gw->g.x, pme->y - gw->g.y);
}
} }
break; break;
#endif #endif
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
case GEVENT_TOGGLE: case GEVENT_TOGGLE:
if (pte->on) { // Cycle through all windows
if (wvmt->ToggleOn) for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
wvmt->ToggleOn(gw, pte->instance);
} else { // check if it a widget that is enabled and visible
if (wvmt->ToggleOff) if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE))
wvmt->ToggleOff(gw, pte->instance); continue;
for(role = 0; role < wvmt->toggleroles; role++) {
if (wvmt->ToggleGet(gw, role) == pte->instance) {
if (pte->on) {
if (wvmt->ToggleOn)
wvmt->ToggleOn(gw, role);
} else {
if (wvmt->ToggleOff)
wvmt->ToggleOff(gw, role);
}
}
}
} }
break; break;
#endif #endif
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL #if GFX_USE_GINPUT && GINPUT_NEED_DIAL
case GEVENT_DIAL: case GEVENT_DIAL:
if (wvmt->DialMove) // Cycle through all windows
wvmt->DialMove(gw, pde->instance, pde->value); for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
// check if it a widget that is enabled and visible
if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE))
continue;
for(role = 0; role < wvmt->dialroles; role++) {
if (wvmt->DialGet(gw, role) == pte->instance) {
if (wvmt->DialMove)
wvmt->DialMove(gw, role, pde->value, pde->maxvalue);
}
}
}
break; break;
#endif #endif
default: default:
break; break;
} }
#undef gh #undef gh
#undef pme #undef pme
#undef pte #undef pte
#undef pde #undef pde
} }
GHandle _gwidgetInit(GWidgetObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwidgetVMT *vmt) { #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
if (!(pgw = (GWidgetObject *)_gwindowInit((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED))) static GHandle FindToggleUser(uint16_t instance) {
#define gh QItem2GWindow(qi)
const gfxQueueASyncItem * qi;
uint16_t role;
for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
if (!(gh->flags & GWIN_FLG_WIDGET)) // check if it a widget
continue;
for(role = 0; role < wvmt->toggleroles; role++) {
if (wvmt->ToggleGet(gw, role) == instance)
return gh;
}
}
return 0;
#undef gh
}
#endif
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
static GHandle FindDialUser(uint16_t instance) {
#define gh QItem2GWindow(qi)
const gfxQueueASyncItem * qi;
uint16_t role;
for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
if (!(gh->flags & GWIN_FLG_WIDGET)) // check if it a widget
continue;
for(role = 0; role < wvmt->dialroles; role++) {
if (wvmt->DialGet(gw, role) == instance)
return gh;
}
}
return 0;
#undef gh
}
#endif
void _gwidgetInit(void) {
geventListenerInit(&gl);
geventRegisterCallback(&gl, gwidgetEvent, 0);
}
GHandle _gwidgetCreate(GWidgetObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwidgetVMT *vmt) {
if (!(pgw = (GWidgetObject *)_gwindowCreate((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED)))
return 0; return 0;
pgw->txt = ""; pgw->txt = "";
pgw->fnDraw = vmt->DefaultDraw; pgw->fnDraw = vmt->DefaultDraw;
pgw->fnParam = 0; pgw->fnParam = 0;
geventListenerInit(&pgw->listener);
geventRegisterCallback(&pgw->listener, gwidgetCallback, pgw);
return (GHandle)pgw; return (GHandle)pgw;
} }
void _gwidgetDestroy(GHandle gh) { void _gwidgetDestroy(GHandle gh) {
#if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL)
uint16_t role, instance;
#endif
// Deallocate the text (if necessary) // Deallocate the text (if necessary)
if ((gh->flags & GWIN_FLG_ALLOCTXT)) { if ((gh->flags & GWIN_FLG_ALLOCTXT)) {
gh->flags &= ~GWIN_FLG_ALLOCTXT; gh->flags &= ~GWIN_FLG_ALLOCTXT;
gfxFree((void *)gw->txt); gfxFree((void *)gw->txt);
} }
// Untangle the listeners (both on us and to us).
geventDetachSource(&gw->listener, 0); #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
// Detach any toggles from this object
for(role = 0; role < wvmt->toggleroles; role++) {
instance = wvmt->ToggleGet(gw, role);
if (instance != GWIDGET_NO_INSTANCE) {
wvmt->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE);
if (!FindToggleUser(instance))
geventDetachSource(&gl, ginputGetToggle(instance));
}
}
#endif
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
// Detach any dials from this object
for(role = 0; role < wvmt->dialroles; role++) {
instance = wvmt->DialGet(gw, role);
if (instance != GWIDGET_NO_INSTANCE) {
wvmt->DialAssign(gw, role, GWIDGET_NO_INSTANCE);
if (!FindDialUser(instance))
geventDetachSource(&gl, ginputGetDial(instance));
}
}
#endif
// Remove any listeners on this object.
geventDetachSourceListeners((GSourceHandle)gh); geventDetachSourceListeners((GSourceHandle)gh);
} }
@ -183,76 +288,89 @@ void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) {
_gwidgetRedraw(gh); _gwidgetRedraw(gh);
} }
bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags) { bool_t gwinAttachListener(GListener *pl) {
if (!(gh->flags & GWIN_FLG_WIDGET)) return geventAttachSource(pl, GWIDGET_SOURCE, 0);
return FALSE;
return geventAttachSource(pl, (GSourceHandle)gh, flags);
} }
#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
bool_t gwinAttachMouse(GHandle gh, uint16_t instance) { bool_t gwinAttachMouse(uint16_t instance) {
GSourceHandle gsh; GSourceHandle gsh;
unsigned flags;
if (!(gh->flags & GWIN_FLG_WIDGET))
return FALSE;
if (!wvmt->MouseDown && !wvmt->MouseMove && !wvmt->MouseUp)
return FALSE;
if (!(gsh = ginputGetMouse(instance))) if (!(gsh = ginputGetMouse(instance)))
return FALSE; return FALSE;
flags = wvmt->MouseMove ? (GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES) : GLISTEN_MOUSEMETA; return geventAttachSource(&gl, gsh, GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES);
return geventAttachSource(&gw->listener, gsh, flags);
} }
#endif #endif
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance) { bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance) {
GSourceHandle gsh; GSourceHandle gsh;
unsigned flags; uint16_t oi;
// Is this a widget
if (!(gh->flags & GWIN_FLG_WIDGET)) if (!(gh->flags & GWIN_FLG_WIDGET))
return FALSE; return FALSE;
flags = 0; // Is the role valid
if (wvmt->ToggleOff) flags |= GLISTEN_TOGGLE_OFF; if (role >= wvmt->toggleroles)
if (wvmt->ToggleOn) flags |= GLISTEN_TOGGLE_ON;
if (!flags)
return FALSE; return FALSE;
// Is this a valid device
if (!(gsh = ginputGetToggle(instance))) if (!(gsh = ginputGetToggle(instance)))
return FALSE; return FALSE;
if (wvmt->AssignToggle && !wvmt->AssignToggle(gw, role, instance)) // Is this already done?
return FALSE; oi = wvmt->ToggleGet(gw, role);
if (instance == oi)
return TRUE;
return geventAttachSource(&gw->listener, gsh, flags); // Remove the old instance
if (oi != GWIDGET_NO_INSTANCE) {
wvmt->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE);
if (!FindToggleUser(oi))
geventDetachSource(&gl, ginputGetToggle(oi));
}
// Assign the new
wvmt->ToggleAssign(gw, role, instance);
return geventAttachSource(&gl, gsh, GLISTEN_TOGGLE_ON|GLISTEN_TOGGLE_OFF);
} }
#endif #endif
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL #if GFX_USE_GINPUT && GINPUT_NEED_DIAL
bool_t gwinAttachDial(GHandle gh, uint16_t role, uint16_t instance) { bool_t gwinAttachDial(GHandle gh, uint16_t role, uint16_t instance) {
GSourceHandle gsh; GSourceHandle gsh;
uint16_t oi;
if (!(gh->flags & GWIN_FLG_WIDGET)) if (!(gh->flags & GWIN_FLG_WIDGET))
return FALSE; return FALSE;
if (!wvmt->DialMove) // Is the role valid
if (role >= wvmt->dialroles)
return FALSE; return FALSE;
// Is this a valid device
if (!(gsh = ginputGetDial(instance))) if (!(gsh = ginputGetDial(instance)))
return FALSE; return FALSE;
if (wvmt->AssignDial && !wvmt->AssignDial(gw, role, instance)) // Is this already done?
return FALSE; oi = wvmt->DialGet(gw, role);
if (instance == oi)
return TRUE;
return geventAttachSource(&gw->listener, gsh, 0); // Remove the old instance
if (oi != GWIDGET_NO_INSTANCE) {
wvmt->DialAssign(gw, role, GWIDGET_NO_INSTANCE);
if (!FindDialUser(oi))
geventDetachSource(&gl, ginputGetDial(oi));
}
// Assign the new
wvmt->DialAssign(gw, role, instance);
return geventAttachSource(&gl, gsh, 0);
} }
#endif #endif
#endif /* GFX_USE_GWIN && GWIN_NEED_WIDGET */ #endif /* GFX_USE_GWIN && GWIN_NEED_WIDGET */
/** @} */ /** @} */

View File

@ -70,6 +70,11 @@ static color_t defaultBgColor = Black;
*-----------------------------------------------*/ *-----------------------------------------------*/
void _gwinInit(void) { void _gwinInit(void) {
#if GWIN_NEED_WIDGET
extern void _gwidgetInit(void);
_gwidgetInit();
#endif
#if GWIN_NEED_WINDOWMANAGER #if GWIN_NEED_WINDOWMANAGER
gfxQueueASyncInit(&_GWINList); gfxQueueASyncInit(&_GWINList);
cwm = &GNullWindowManager; cwm = &GNullWindowManager;
@ -79,7 +84,7 @@ void _gwinInit(void) {
// Internal routine for use by GWIN components only // Internal routine for use by GWIN components only
// Initialise a window creating it dynamically if required. // Initialise a window creating it dynamically if required.
GHandle _gwindowInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt, uint16_t flags) { GHandle _gwindowCreate(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height, size_t size, const gwinVMT *vmt, uint16_t flags) {
// Allocate the structure if necessary // Allocate the structure if necessary
if (!pgw) { if (!pgw) {
if (!(pgw = (GWindowObject *)gfxAlloc(size))) if (!(pgw = (GWindowObject *)gfxAlloc(size)))
@ -146,7 +151,7 @@ void gwinSetDefaultBgColor(color_t bgclr) {
*-----------------------------------------------*/ *-----------------------------------------------*/
GHandle gwinCreateWindow(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateWindow(GWindowObject *pgw, coord_t x, coord_t y, coord_t width, coord_t height) {
return _gwindowInit(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT, GWIN_FLG_VISIBLE); return _gwindowCreate(pgw, x, y, width, height, sizeof(GWindowObject), &basegwinVMT, GWIN_FLG_VISIBLE);
} }
void gwinDestroy(GHandle gh) { void gwinDestroy(GHandle gh) {

View File

@ -25,10 +25,19 @@
#define GWIN_SLIDER_DEAD_BAND 5 #define GWIN_SLIDER_DEAD_BAND 5
#endif #endif
#ifndef GWIN_SLIDER_TOGGLE_INC
#define GWIN_SLIDER_TOGGLE_INC 20 // How many toggles to go from minimum to maximum
#endif
// Prototypes for slider VMT functions // Prototypes for slider VMT functions
static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y); static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y);
static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y); static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y);
static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value); static void ToggleOn(GWidgetObject *gw, uint16_t role);
static void DialMove(GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max);
static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance);
static void DialAssign(GWidgetObject *gw, uint16_t role, uint16_t instance);
static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role);
static uint16_t DialGet(GWidgetObject *gw, uint16_t role);
// The button VMT table // The button VMT table
static const gwidgetVMT sliderVMT = { static const gwidgetVMT sliderVMT = {
@ -38,16 +47,25 @@ static const gwidgetVMT sliderVMT = {
_gwidgetRedraw, // The redraw routine _gwidgetRedraw, // The redraw routine
0, // The after-clear routine 0, // The after-clear routine
}, },
gwinSliderDraw_Std, // The default drawing routine gwinSliderDraw_Std, // The default drawing routine
MouseMove, // Process mouse down events (AS MOUSEMOVE) {
MouseUp, // Process mouse up events 0, // Process mouse down events (NOT USED)
MouseMove, // Process mouse move events MouseUp, // Process mouse up events
0, // Process toggle off events (NOT USED) MouseMove, // Process mouse move events
0, // Process toggle on events (NOT USED) },
DialMove, // Process dial move events {
0, // Process all events (NOT USED) 2, // 1 toggle role
0, // AssignToggle (NOT USED) ToggleAssign, // Assign Toggles
0, // AssignDial (NOT USED) ToggleGet, // Get Toggles
0, // Process toggle off events (NOT USED)
ToggleOn, // Process toggle on events
},
{
1, // 1 dial roles
DialAssign, // Assign Dials
DialGet, // Get Dials
DialMove, // Process dial move events
}
}; };
static const GSliderColors GSliderDefaultColors = { static const GSliderColors GSliderDefaultColors = {
@ -66,7 +84,7 @@ static void SendSliderEvent(GWidgetObject *gw) {
// Trigger a GWIN Button Event // Trigger a GWIN Button Event
psl = 0; psl = 0;
while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) { while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
if (!(pe = geventGetEventBuffer(psl))) if (!(pe = geventGetEventBuffer(psl)))
continue; continue;
pse->type = GEVENT_GWIN_SLIDER; pse->type = GEVENT_GWIN_SLIDER;
@ -75,7 +93,7 @@ static void SendSliderEvent(GWidgetObject *gw) {
geventSendEvent(psl); geventSendEvent(psl);
} }
#undef pbe #undef pse
} }
// Reset the display position back to the value predicted by the saved slider position // Reset the display position back to the value predicted by the saved slider position
@ -159,13 +177,28 @@ static void MouseMove(GWidgetObject *gw, coord_t x, coord_t y) {
#undef gsw #undef gsw
} }
// A dial move event // A toggle on has occurred
static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value) { static void ToggleOn(GWidgetObject *gw, uint16_t role) {
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
#define gsw ((GSliderObject *)gw) #define gsw ((GSliderObject *)gw)
if (role) {
gwinSetSliderPosition((GHandle)gw, gsw->pos+(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC);
SendSliderEvent(gw);
} else {
gwinSetSliderPosition((GHandle)gw, gsw->pos-(gsw->max-gsw->min)/GWIN_SLIDER_TOGGLE_INC);
SendSliderEvent(gw);
}
#undef gsw
}
// A dial move event
static void DialMove(GWidgetObject *gw, uint16_t role, uint16_t value, uint16_t max) {
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
#define gsw ((GSliderObject *)gw)
(void) role;
// Set the new position // Set the new position
gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/ginputGetDialRange(instance) + gsw->min); gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/max + gsw->min);
ResetDisplayPos(gsw); ResetDisplayPos(gsw);
gwinDraw(&gw->g); gwinDraw(&gw->g);
@ -174,13 +207,37 @@ static void DialMove(GWidgetObject *gw, uint16_t instance, uint16_t value) {
SendSliderEvent(gw); SendSliderEvent(gw);
#undef gsw #undef gsw
#else #else
(void)gw; (void)instance; (void)value; (void)gw; (void)role; (void)value; (void)max;
#endif #endif
} }
static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) {
if (role)
((GSliderObject *)gw)->t_up = instance;
else
((GSliderObject *)gw)->t_dn = instance;
}
static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) {
return role ? ((GSliderObject *)gw)->t_up : ((GSliderObject *)gw)->t_dn;
}
static void DialAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) {
(void) role;
((GSliderObject *)gw)->dial = instance;
}
static uint16_t DialGet(GWidgetObject *gw, uint16_t role) {
(void) role;
return ((GSliderObject *)gw)->dial;
}
GHandle gwinCreateSlider(GSliderObject *gs, coord_t x, coord_t y, coord_t width, coord_t height) { GHandle gwinCreateSlider(GSliderObject *gs, coord_t x, coord_t y, coord_t width, coord_t height) {
if (!(gs = (GSliderObject *)_gwidgetInit((GWidgetObject *)gs, x, y, width, height, sizeof(GSliderObject), &sliderVMT))) if (!(gs = (GSliderObject *)_gwidgetCreate((GWidgetObject *)gs, x, y, width, height, sizeof(GSliderObject), &sliderVMT)))
return 0; return 0;
gs->t_dn = (uint16_t) -1;
gs->t_up = (uint16_t) -1;
gs->dial = (uint16_t) -1;
gs->c = GSliderDefaultColors; gs->c = GSliderDefaultColors;
gs->min = 0; gs->min = 0;
gs->max = 100; gs->max = 100;