Clean up GWIN Event assignment. Optimise event efficiency.
This commit is contained in:
parent
777ec6af7c
commit
2cb35d6815
@ -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) {
|
||||
/* 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;
|
||||
|
||||
/* Initialise the scope object members and allocate memory for buffers */
|
||||
|
@ -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) {
|
||||
/* 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;
|
||||
|
||||
/* Initialise the scope object members and allocate memory for buffers */
|
||||
|
@ -51,15 +51,17 @@
|
||||
#define GDISP_NEED_IMAGE_PNG FALSE
|
||||
|
||||
/* Features for the GWIN sub-system. */
|
||||
#define GWIN_NEED_WINDOWMANAGER TRUE
|
||||
#define GWIN_NEED_CONSOLE TRUE
|
||||
#define GWIN_NEED_GRAPH FALSE
|
||||
#define GWIN_NEED_WIDGET TRUE
|
||||
#define GWIN_NEED_BUTTON TRUE
|
||||
#define GWIN_NEED_SLIDER TRUE
|
||||
#define GWIN_NEED_CHECKBOX TRUE
|
||||
|
||||
/* Features for the GINPUT sub-system. */
|
||||
#define GINPUT_NEED_MOUSE TRUE
|
||||
#define GINPUT_NEED_TOGGLE FALSE
|
||||
#define GINPUT_NEED_TOGGLE TRUE
|
||||
#define GINPUT_NEED_DIAL FALSE
|
||||
|
||||
#endif /* _GFXCONF_H */
|
||||
|
@ -49,11 +49,20 @@ int main(void) {
|
||||
gfxInit();
|
||||
gdispClear(White);
|
||||
|
||||
// Set the font and defalt colors
|
||||
// Set the widget defaults
|
||||
gwinSetDefaultFont(gdispOpenFont("UI2"));
|
||||
gwinSetDefaultColor(Black);
|
||||
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
|
||||
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);
|
||||
@ -84,49 +93,28 @@ int main(void) {
|
||||
gwinSetText(ghCheckbox1, "C1", FALSE);
|
||||
gwinSetText(ghCheckbox2, "C2", FALSE);
|
||||
|
||||
// Assign the mouse and dials to the buttons & sliders etc.
|
||||
#if GINPUT_NEED_MOUSE
|
||||
gwinAttachMouse(ghButton1, 0);
|
||||
gwinAttachMouse(ghButton2, 0);
|
||||
gwinAttachMouse(ghButton3, 0);
|
||||
gwinAttachMouse(ghButton4, 0);
|
||||
gwinAttachMouse(ghSlider1, 0);
|
||||
gwinAttachMouse(ghSlider2, 0);
|
||||
gwinAttachMouse(ghSlider3, 0);
|
||||
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);
|
||||
// Assign toggles and dials to the buttons & sliders etc.
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
gwinAttachToggle(ghButton1, 0, 0);
|
||||
gwinAttachToggle(ghButton2, 0, 1);
|
||||
#endif
|
||||
#if GINPUT_NEED_DIAL
|
||||
gwinAttachDial(ghSlider1, 0, 0);
|
||||
gwinAttachDial(ghSlider3, 0, 1);
|
||||
#endif
|
||||
|
||||
// Draw everything on the screen
|
||||
gwinClear(ghConsole);
|
||||
gwinDraw(ghButton1);
|
||||
gwinDraw(ghButton2);
|
||||
gwinDraw(ghButton3);
|
||||
gwinDraw(ghButton4);
|
||||
gwinDraw(ghSlider1);
|
||||
gwinDraw(ghSlider2);
|
||||
gwinDraw(ghSlider3);
|
||||
gwinDraw(ghSlider4);
|
||||
gwinDraw(ghCheckbox1);
|
||||
gwinDraw(ghCheckbox2);
|
||||
gwinSetVisible(ghButton1, TRUE);
|
||||
gwinSetVisible(ghButton2, TRUE);
|
||||
gwinSetVisible(ghButton3, TRUE);
|
||||
gwinSetVisible(ghButton4, TRUE);
|
||||
gwinSetVisible(ghSlider1, TRUE);
|
||||
gwinSetVisible(ghSlider2, TRUE);
|
||||
gwinSetVisible(ghSlider3, TRUE);
|
||||
gwinSetVisible(ghSlider4, TRUE);
|
||||
gwinSetVisible(ghCheckbox1, TRUE);
|
||||
gwinSetVisible(ghCheckbox2, TRUE);
|
||||
|
||||
while(1) {
|
||||
// Get an Event
|
||||
|
@ -119,8 +119,8 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
if ((toggles & 0xF0)) {
|
||||
toggles &= 0x0F;
|
||||
if ((toggles & 0x0F)) {
|
||||
toggles &= ~0x0F;
|
||||
rect.left = 0;
|
||||
rect.right = wWidth;
|
||||
rect.top = wHeight;
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* http://chibios-gfx.com/license.html
|
||||
*/
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* http://chibios-gfx.com/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/multiple/Win32/ginput_lld_toggle_config.h
|
||||
@ -20,19 +20,19 @@
|
||||
|
||||
#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_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries
|
||||
|
||||
#define GINPUT_TOGGLE_SW1 0 // Switch 1 - Toggle
|
||||
#define GINPUT_TOGGLE_SW2 1 // Switch 2 - Toggle
|
||||
#define GINPUT_TOGGLE_SW3 2 // Switch 3 - Toggle
|
||||
#define GINPUT_TOGGLE_SW4 3 // Switch 4 - Toggle
|
||||
#define GINPUT_TOGGLE_MOMENTARY1 0 // Switch 5 - Momentary
|
||||
#define GINPUT_TOGGLE_MOMENTARY2 1 // Switch 6 - Momentary
|
||||
#define GINPUT_TOGGLE_MOMENTARY3 2 // Switch 7 - Momentary
|
||||
#define GINPUT_TOGGLE_MOMENTARY4 3 // Switch 8 - Momentary
|
||||
|
||||
#define GINPUT_TOGGLE_MOMENTARY1 4 // Switch 5 - Momentary
|
||||
#define GINPUT_TOGGLE_MOMENTARY2 5 // Switch 6 - Momentary
|
||||
#define GINPUT_TOGGLE_MOMENTARY3 6 // Switch 7 - Momentary
|
||||
#define GINPUT_TOGGLE_MOMENTARY4 7 // Switch 8 - Momentary
|
||||
#define GINPUT_TOGGLE_SW1 4 // Switch 1 - Toggle
|
||||
#define GINPUT_TOGGLE_SW2 5 // Switch 2 - Toggle
|
||||
#define GINPUT_TOGGLE_SW3 6 // Switch 3 - Toggle
|
||||
#define GINPUT_TOGGLE_SW4 7 // Switch 4 - Toggle
|
||||
|
||||
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */
|
||||
|
||||
|
@ -46,24 +46,6 @@
|
||||
#warning "GWIN: Drawing can occur outside the defined windows as GDISP_NEED_CLIP is FALSE"
|
||||
#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_WIDGET
|
||||
#if GFX_DISPLAY_RULE_WARNINGS
|
||||
@ -81,6 +63,13 @@
|
||||
// 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"
|
||||
#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 GFX_DISPLAY_RULE_WARNINGS
|
||||
#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
|
||||
#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
|
||||
|
||||
#if GFX_USE_GINPUT
|
||||
|
@ -36,6 +36,7 @@ typedef struct GEventDial_t {
|
||||
GEventType type; // The type of this event (GEVENT_DIAL)
|
||||
uint16_t instance; // The dial instance
|
||||
uint16_t value; // The dial value
|
||||
uint16_t maxvalue; // The maximum dial value
|
||||
} GEventDial;
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -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
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @api
|
||||
@ -220,6 +220,46 @@ bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, gfxQueueGSyncItem *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
|
||||
}
|
||||
#endif
|
||||
|
@ -55,6 +55,7 @@ typedef struct GButtonColors {
|
||||
*/
|
||||
typedef struct GButtonObject_t {
|
||||
GWidgetObject w;
|
||||
uint16_t toggle;
|
||||
GButtonColors c_up;
|
||||
GButtonColors c_dn;
|
||||
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
|
||||
* 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 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.
|
||||
* @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.
|
||||
* @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
|
||||
*/
|
||||
|
@ -50,6 +50,7 @@ typedef struct GCheckboxColors {
|
||||
/* A Checkbox window */
|
||||
typedef struct GCheckboxObject_t {
|
||||
GWidgetObject w;
|
||||
uint16_t toggle;
|
||||
GCheckboxColors c;
|
||||
} GCheckboxObject;
|
||||
|
||||
@ -62,10 +63,18 @@ typedef struct GCheckboxObject_t {
|
||||
* @param[in] width The width 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 Don't forget to set the font using @p gwinSetFont() or @p gwinSetDefaultFont()
|
||||
* @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 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 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
|
||||
*/
|
||||
|
@ -52,37 +52,58 @@ typedef struct gwinVMT {
|
||||
/* @} */
|
||||
|
||||
#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
|
||||
* @note A widget must have a destroy function. Either use @p _gwidgetDestroy() or use your own function
|
||||
* which internally calls @p _gwidgetDestroy().
|
||||
* @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 no ToggleOn() or ToggleOff() function is provided, the widget will not accept being attached to a toggle input source.
|
||||
* @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).
|
||||
* @note If toggleroles != 0, ToggleAssign(), ToggleGet() and one or both of ToggleOff() and ToggleOn() must be specified.
|
||||
* @note If dialroles != 0, DialAssign(), DialGet() and DialMove() must be specified.
|
||||
* @{
|
||||
*/
|
||||
typedef struct gwidgetVMT {
|
||||
struct gwinVMT g; // @< This is still a GWIN
|
||||
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)
|
||||
void (*MouseUp) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse up events (optional)
|
||||
void (*MouseMove) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse move events (optional)
|
||||
void (*ToggleOff) (GWidgetObject *gw, uint16_t instance); // @< Process toggle off 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)
|
||||
void (*AllEvents) (GWidgetObject *gw, GEvent *pe); // @< Process all events (optional)
|
||||
bool_t (*AssignToggle) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Test the role and save the toggle instance handle (optional)
|
||||
bool_t (*AssignDial) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Test the role and save the dial instance handle (optional)
|
||||
struct gwinVMT g; // @< This is still a GWIN
|
||||
void (*DefaultDraw) (GWidgetObject *gw, void *param); // @< The default drawing routine (mandatory)
|
||||
struct {
|
||||
void (*MouseDown) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse down events (optional)
|
||||
void (*MouseUp) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse up events (optional)
|
||||
void (*MouseMove) (GWidgetObject *gw, coord_t x, coord_t y); // @< Process mouse move events (optional)
|
||||
};
|
||||
struct {
|
||||
uint16_t toggleroles; // @< The roles supported for toggles (0->toggleroles-1)
|
||||
void (*ToggleAssign) (GWidgetObject *gw, uint16_t role, uint16_t instance); // @< Assign a toggle to a role (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;
|
||||
/* @} */
|
||||
#endif
|
||||
|
||||
#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
|
||||
typedef struct GWindowManager {
|
||||
const struct gwmVMT *vmt;
|
||||
@ -126,7 +147,7 @@ extern "C" {
|
||||
*
|
||||
* @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__)
|
||||
/**
|
||||
@ -140,7 +161,7 @@ GHandle _gwindowInit(GWindowObject *pgw, coord_t x, coord_t y, coord_t w, coord_
|
||||
*
|
||||
* @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
|
||||
|
@ -46,7 +46,6 @@ typedef void (*CustomWidgetDrawFunction)(struct GWidgetObject *gw, void *param);
|
||||
*/
|
||||
typedef struct GWidgetObject {
|
||||
GWindowObject g; // @< This is still a GWIN
|
||||
GListener listener; // @< The widget listener
|
||||
const char * txt; // @< The widget text
|
||||
CustomWidgetDrawFunction fnDraw; // @< 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);
|
||||
|
||||
/**
|
||||
* @brief Attach a Listener to this widget
|
||||
* @brief Attach a Listener to listen for widget events
|
||||
* @return TRUE on success
|
||||
*
|
||||
* @param[in] gh The widget handle
|
||||
* @param[in] pl The listener
|
||||
* @param[in] flags Flags to use for listening. For most widgets this should be 0.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags);
|
||||
bool_t gwinAttachListener(GListener *pl);
|
||||
|
||||
#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
|
||||
*
|
||||
* @param[in] gh The widget handle
|
||||
* @param[in] instance The mouse instance
|
||||
*
|
||||
* @note Every widget uses the same mouse.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool_t gwinAttachMouse(GHandle gh, uint16_t instance);
|
||||
bool_t gwinAttachMouse(uint16_t instance);
|
||||
#endif
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
|
||||
|
@ -35,6 +35,7 @@
|
||||
*/
|
||||
typedef struct GWindowObject {
|
||||
#if GWIN_NEED_WINDOWMANAGER
|
||||
// This MUST be the first member of the struct
|
||||
gfxQueueASyncItem wmq; // @< The next window (for the window manager)
|
||||
#endif
|
||||
const struct gwinVMT *vmt; // @< The VMT for this GWIN
|
||||
|
@ -21,11 +21,11 @@
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Should a window manager be used.
|
||||
* @brief Should window manager support be included
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GWIN_NEED_WINDOWMANAGER
|
||||
#define GWIN_NEED_WINDOWMANAGER FALSE
|
||||
#define GWIN_NEED_WIDGET FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should widget functions be included. Needed for any widget (eg Buttons, Sliders etc)
|
||||
|
@ -45,11 +45,14 @@ typedef struct GSliderColors {
|
||||
// A slider window
|
||||
typedef struct GSliderObject_t {
|
||||
GWidgetObject w;
|
||||
GSliderColors c;
|
||||
uint16_t t_dn;
|
||||
uint16_t t_up;
|
||||
uint16_t dial;
|
||||
coord_t dpos;
|
||||
int min;
|
||||
int max;
|
||||
int pos;
|
||||
GSliderColors c;
|
||||
} GSliderObject;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -65,11 +68,22 @@ extern "C" {
|
||||
* @param[in] width The width 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 Don't forget to set the font using @p gwinSetFont() or @p gwinSetDefaultFont()
|
||||
* @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 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 slider is not automatically drawn. Call gwinDraw() to draw it.
|
||||
* @note Sets the slider range from 0 to 100 with an initial position of 0
|
||||
* @note A slider 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 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
|
||||
*/
|
||||
|
@ -57,6 +57,7 @@ static void DialCallback(uint16_t instance, uint16_t rawvalue) {
|
||||
pe->type = GEVENT_DIAL;
|
||||
pe->instance = instance;
|
||||
pe->value = pds->lastvalue;
|
||||
pe->maxvalue = pds->max;
|
||||
geventSendEvent(psl);
|
||||
}
|
||||
}
|
||||
@ -144,6 +145,7 @@ bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial) {
|
||||
pdial->type = GEVENT_DIAL;
|
||||
pdial->instance = instance;
|
||||
pdial->value = DialStatus[instance].lastvalue;
|
||||
pdial->maxvalue = DialStatus[instance].max;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
gfxSystemLock();
|
||||
if ((pi = pqueue->head))
|
||||
pqueue->head = pi->next;
|
||||
pi->next = 0;
|
||||
gfxSystemUnlock();
|
||||
return pi;
|
||||
}
|
||||
@ -68,12 +69,14 @@
|
||||
if (pqueue->head) {
|
||||
if (pqueue->head == pitem) {
|
||||
pqueue->head = pitem->next;
|
||||
pitem->next = 0;
|
||||
} else {
|
||||
for(pi = pqueue->head; pi->next; pi = pi->next) {
|
||||
if (pi->next == pitem) {
|
||||
pi->next = pitem->next;
|
||||
if (pqueue->tail == pitem)
|
||||
pqueue->tail = pi;
|
||||
pitem->next = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -111,6 +114,7 @@
|
||||
gfxSystemLock();
|
||||
pi = pqueue->head;
|
||||
pqueue->head = pi->next;
|
||||
pi->next = 0;
|
||||
gfxSytemUnlock();
|
||||
return pi;
|
||||
}
|
||||
@ -146,12 +150,14 @@
|
||||
if (pqueue->head) {
|
||||
if (pqueue->head == pitem) {
|
||||
pqueue->head = pitem->next;
|
||||
pitem->next = 0;
|
||||
} else {
|
||||
for(pi = pqueue->head; pi->next; pi = pi->next) {
|
||||
if (pi->next == pitem) {
|
||||
pi->next = pitem->next;
|
||||
if (pqueue->tail == pitem)
|
||||
pqueue->tail = pi;
|
||||
pitem->next = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -189,6 +195,7 @@
|
||||
gfxSystemLock();
|
||||
pi = pqueue->head;
|
||||
pqueue->head = pi->next;
|
||||
pi->next = 0;
|
||||
gfxSytemUnlock();
|
||||
|
||||
gfxSemSignalI(&pi->sem);
|
||||
@ -233,6 +240,7 @@
|
||||
if (pqueue->head == pitem) {
|
||||
pqueue->head = pitem->next;
|
||||
found:
|
||||
pitem->next = 0;
|
||||
gfxSystemUnlock();
|
||||
gfxSemSignal(&pitem->sem);
|
||||
gfxSemDestroy(&pitem->sem);
|
||||
|
@ -32,8 +32,10 @@
|
||||
// Prototypes for button VMT functions
|
||||
static void MouseDown(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 ToggleOn(GWidgetObject *gw, uint16_t instance);
|
||||
static void ToggleOff(GWidgetObject *gw, uint16_t role);
|
||||
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
|
||||
static const gwidgetVMT buttonVMT = {
|
||||
@ -43,16 +45,25 @@ static const gwidgetVMT buttonVMT = {
|
||||
_gwidgetRedraw, // The redraw routine
|
||||
0, // The after-clear routine
|
||||
},
|
||||
gwinButtonDraw_3D, // The default drawing routine
|
||||
MouseDown, // Process mouse down events
|
||||
MouseUp, // Process mouse up events
|
||||
0, // Process mouse move events (NOT USED)
|
||||
ToggleOff, // Process toggle off events
|
||||
ToggleOn, // Process toggle on events
|
||||
0, // Process dial move events (NOT USED)
|
||||
0, // Process all events (NOT USED)
|
||||
0, // AssignToggle (NOT USED)
|
||||
0, // AssignDial (NOT USED)
|
||||
gwinButtonDraw_3D, // The default drawing routine
|
||||
{
|
||||
MouseDown, // Process mouse down events
|
||||
MouseUp, // Process mouse up events
|
||||
0, // Process mouse move events (NOT USED)
|
||||
},
|
||||
{
|
||||
1, // 1 toggle role
|
||||
ToggleAssign, // Assign Toggles
|
||||
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
|
||||
@ -80,7 +91,7 @@ static void SendButtonEvent(GWidgetObject *gw) {
|
||||
|
||||
// Trigger a GWIN Button Event
|
||||
psl = 0;
|
||||
while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) {
|
||||
while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
|
||||
if (!(pe = geventGetEventBuffer(psl)))
|
||||
continue;
|
||||
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
|
||||
static void ToggleOff(GWidgetObject *gw, uint16_t instance) {
|
||||
(void) instance;
|
||||
static void ToggleOff(GWidgetObject *gw, uint16_t role) {
|
||||
(void) role;
|
||||
gw->g.flags &= ~GBUTTON_FLG_PRESSED;
|
||||
_gwidgetRedraw((GHandle)gw);
|
||||
}
|
||||
|
||||
// A toggle on has occurred
|
||||
static void ToggleOn(GWidgetObject *gw, uint16_t instance) {
|
||||
(void) instance;
|
||||
static void ToggleOn(GWidgetObject *gw, uint16_t role) {
|
||||
(void) role;
|
||||
gw->g.flags |= GBUTTON_FLG_PRESSED;
|
||||
_gwidgetRedraw((GHandle)gw);
|
||||
// Trigger the event on button down (different than for mouse/touch)
|
||||
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) {
|
||||
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;
|
||||
|
||||
gw->toggle = GWIDGET_NO_INSTANCE;
|
||||
gw->c_up = GButtonDefaultColorsUp;
|
||||
gw->c_dn = GButtonDefaultColorsDown;
|
||||
gw->c_dis = GButtonDefaultColorsDisabled;
|
||||
|
@ -26,7 +26,9 @@
|
||||
|
||||
// Prototypes for button VMT functions
|
||||
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
|
||||
static const gwidgetVMT checkboxVMT = {
|
||||
@ -37,15 +39,24 @@ static const gwidgetVMT checkboxVMT = {
|
||||
0, // The after-clear routine
|
||||
},
|
||||
gwinCheckboxDraw_CheckOnLeft, // The default drawing routine
|
||||
MouseDown, // Process mouse down events
|
||||
0, // Process mouse up events (NOT USED)
|
||||
0, // Process mouse move events (NOT USED)
|
||||
0, // Process toggle off events (NOT USED)
|
||||
ToggleOn, // Process toggle on events
|
||||
0, // Process dial move events (NOT USED)
|
||||
0, // Process all events (NOT USED)
|
||||
0, // AssignToggle (NOT USED)
|
||||
0, // AssignDial (NOT USED)
|
||||
{
|
||||
MouseDown, // Process mouse down events
|
||||
0, // Process mouse up events (NOT USED)
|
||||
0, // Process mouse move events (NOT USED)
|
||||
},
|
||||
{
|
||||
1, // 1 toggle role
|
||||
ToggleAssign, // Assign Toggles
|
||||
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 = {
|
||||
@ -63,7 +74,7 @@ static void SendCheckboxEvent(GWidgetObject *gw) {
|
||||
|
||||
// Trigger a GWIN Checkbox Event
|
||||
psl = 0;
|
||||
while ((psl = geventGetSourceListener((GSourceHandle)gw, psl))) {
|
||||
while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
|
||||
if (!(pe = geventGetEventBuffer(psl)))
|
||||
continue;
|
||||
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
|
||||
static void ToggleOn(GWidgetObject *gw, uint16_t instance) {
|
||||
(void) instance;
|
||||
static void ToggleOn(GWidgetObject *gw, uint16_t role) {
|
||||
(void) role;
|
||||
gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
|
||||
_gwidgetRedraw((GHandle)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) {
|
||||
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;
|
||||
|
||||
gb->toggle = (uint16_t) -1;
|
||||
gb->c = defaultColors; // assign the default colors
|
||||
return (GHandle)gb;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ static const gwinVMT consoleVMT = {
|
||||
};
|
||||
|
||||
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;
|
||||
#if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
|
||||
gc->stream.vmt = &GWindowConsoleVMT;
|
||||
|
@ -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) {
|
||||
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;
|
||||
gg->xorigin = gg->yorigin = 0;
|
||||
gg->lastx = gg->lasty = 0;
|
||||
|
@ -13,23 +13,25 @@
|
||||
|
||||
#include "gwin/class_gwin.h"
|
||||
|
||||
/* Our listener for events for widgets */
|
||||
static GListener gl;
|
||||
|
||||
/* We use these everywhere in this file */
|
||||
#define gw ((GWidgetObject *)gh)
|
||||
#define wvmt ((gwidgetVMT *)gh->vmt)
|
||||
|
||||
static void gwidgetCallback(void *param, GEvent *pe) {
|
||||
#define gh ((GWindowObject *)param)
|
||||
/* Process an event */
|
||||
static void gwidgetEvent(void *param, GEvent *pe) {
|
||||
#define gh QItem2GWindow(qi)
|
||||
#define pme ((GEventMouse *)pe)
|
||||
#define pte ((GEventToggle *)pe)
|
||||
#define pde ((GEventDial *)pe)
|
||||
|
||||
// check if widget is disabled
|
||||
if ((gw->g.flags & (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE))
|
||||
return;
|
||||
|
||||
// Process via AllEvents() if it is defined
|
||||
if (wvmt->AllEvents)
|
||||
wvmt->AllEvents(gw, pe);
|
||||
const gfxQueueASyncItem * qi;
|
||||
#if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL)
|
||||
uint16_t role;
|
||||
#endif
|
||||
(void) param;
|
||||
|
||||
// Process various events
|
||||
switch (pe->type) {
|
||||
@ -37,76 +39,179 @@ static void gwidgetCallback(void *param, GEvent *pe) {
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
|
||||
case GEVENT_MOUSE:
|
||||
case GEVENT_TOUCH:
|
||||
// Are we captured?
|
||||
if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) {
|
||||
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);
|
||||
// Cycle through all windows
|
||||
for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
|
||||
|
||||
// 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);
|
||||
// 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;
|
||||
|
||||
// Are we captured?
|
||||
if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) {
|
||||
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;
|
||||
#endif
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
|
||||
case GEVENT_TOGGLE:
|
||||
if (pte->on) {
|
||||
if (wvmt->ToggleOn)
|
||||
wvmt->ToggleOn(gw, pte->instance);
|
||||
} else {
|
||||
if (wvmt->ToggleOff)
|
||||
wvmt->ToggleOff(gw, pte->instance);
|
||||
// Cycle through all windows
|
||||
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->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;
|
||||
#endif
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
|
||||
case GEVENT_DIAL:
|
||||
if (wvmt->DialMove)
|
||||
wvmt->DialMove(gw, pde->instance, pde->value);
|
||||
// Cycle through all windows
|
||||
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;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#undef gh
|
||||
#undef pme
|
||||
#undef pte
|
||||
#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 (!(pgw = (GWidgetObject *)_gwindowInit((GWindowObject *)pgw, x, y, width, height, size, (const gwinVMT *)vmt, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED)))
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
|
||||
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;
|
||||
|
||||
pgw->txt = "";
|
||||
pgw->fnDraw = vmt->DefaultDraw;
|
||||
pgw->fnParam = 0;
|
||||
geventListenerInit(&pgw->listener);
|
||||
geventRegisterCallback(&pgw->listener, gwidgetCallback, pgw);
|
||||
|
||||
return (GHandle)pgw;
|
||||
}
|
||||
|
||||
void _gwidgetDestroy(GHandle gh) {
|
||||
#if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL)
|
||||
uint16_t role, instance;
|
||||
#endif
|
||||
|
||||
// Deallocate the text (if necessary)
|
||||
if ((gh->flags & GWIN_FLG_ALLOCTXT)) {
|
||||
gh->flags &= ~GWIN_FLG_ALLOCTXT;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -183,76 +288,89 @@ void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) {
|
||||
_gwidgetRedraw(gh);
|
||||
}
|
||||
|
||||
bool_t gwinAttachListener(GHandle gh, GListener *pl, unsigned flags) {
|
||||
if (!(gh->flags & GWIN_FLG_WIDGET))
|
||||
return FALSE;
|
||||
|
||||
return geventAttachSource(pl, (GSourceHandle)gh, flags);
|
||||
bool_t gwinAttachListener(GListener *pl) {
|
||||
return geventAttachSource(pl, GWIDGET_SOURCE, 0);
|
||||
}
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
|
||||
bool_t gwinAttachMouse(GHandle gh, uint16_t instance) {
|
||||
bool_t gwinAttachMouse(uint16_t instance) {
|
||||
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)))
|
||||
return FALSE;
|
||||
|
||||
flags = wvmt->MouseMove ? (GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES) : GLISTEN_MOUSEMETA;
|
||||
return geventAttachSource(&gw->listener, gsh, flags);
|
||||
return geventAttachSource(&gl, gsh, GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
|
||||
bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance) {
|
||||
GSourceHandle gsh;
|
||||
unsigned flags;
|
||||
uint16_t oi;
|
||||
|
||||
// Is this a widget
|
||||
if (!(gh->flags & GWIN_FLG_WIDGET))
|
||||
return FALSE;
|
||||
|
||||
flags = 0;
|
||||
if (wvmt->ToggleOff) flags |= GLISTEN_TOGGLE_OFF;
|
||||
if (wvmt->ToggleOn) flags |= GLISTEN_TOGGLE_ON;
|
||||
if (!flags)
|
||||
// Is the role valid
|
||||
if (role >= wvmt->toggleroles)
|
||||
return FALSE;
|
||||
|
||||
// Is this a valid device
|
||||
if (!(gsh = ginputGetToggle(instance)))
|
||||
return FALSE;
|
||||
|
||||
if (wvmt->AssignToggle && !wvmt->AssignToggle(gw, role, instance))
|
||||
return FALSE;
|
||||
// Is this already done?
|
||||
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
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
|
||||
bool_t gwinAttachDial(GHandle gh, uint16_t role, uint16_t instance) {
|
||||
GSourceHandle gsh;
|
||||
uint16_t oi;
|
||||
|
||||
if (!(gh->flags & GWIN_FLG_WIDGET))
|
||||
return FALSE;
|
||||
|
||||
if (!wvmt->DialMove)
|
||||
// Is the role valid
|
||||
if (role >= wvmt->dialroles)
|
||||
return FALSE;
|
||||
|
||||
// Is this a valid device
|
||||
if (!(gsh = ginputGetDial(instance)))
|
||||
return FALSE;
|
||||
|
||||
if (wvmt->AssignDial && !wvmt->AssignDial(gw, role |