diff options
Diffstat (limited to 'src/gwin')
| -rw-r--r-- | src/gwin/button.c | 3 | ||||
| -rw-r--r-- | src/gwin/button.h | 3 | ||||
| -rw-r--r-- | src/gwin/checkbox.c | 3 | ||||
| -rw-r--r-- | src/gwin/checkbox.h | 3 | ||||
| -rw-r--r-- | src/gwin/class_gwin.h | 4 | ||||
| -rw-r--r-- | src/gwin/frame.c | 6 | ||||
| -rw-r--r-- | src/gwin/gcontainer.c | 13 | ||||
| -rw-r--r-- | src/gwin/gcontainer.h | 1 | ||||
| -rw-r--r-- | src/gwin/gwidget.c | 57 | ||||
| -rw-r--r-- | src/gwin/gwidget.h | 45 | ||||
| -rw-r--r-- | src/gwin/list.c | 3 | ||||
| -rw-r--r-- | src/gwin/list.h | 3 | ||||
| -rw-r--r-- | src/gwin/radio.c | 3 | ||||
| -rw-r--r-- | src/gwin/radio.h | 3 | ||||
| -rw-r--r-- | src/gwin/slider.c | 3 | ||||
| -rw-r--r-- | src/gwin/slider.h | 3 | ||||
| -rw-r--r-- | src/gwin/sys_options.h | 9 |
17 files changed, 137 insertions, 28 deletions
diff --git a/src/gwin/button.c b/src/gwin/button.c index d489ecb0..fc1cb976 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -39,6 +39,9 @@ static void SendButtonEvent(GWidgetObject *gw) { continue; pbe->type = GEVENT_GWIN_BUTTON; pbe->button = (GHandle)gw; + #if GWIN_WIDGET_TAGS + pbe->tag = gw->tag; + #endif geventSendEvent(psl); } diff --git a/src/gwin/button.h b/src/gwin/button.h index 73d5f9f1..077b50f4 100644 --- a/src/gwin/button.h +++ b/src/gwin/button.h @@ -38,6 +38,9 @@ typedef struct GEventGWinButton { GEventType type; // The type of this event (GEVENT_GWIN_BUTTON) GHandle button; // The button that has been depressed (actually triggered on release) + #if GWIN_WIDGET_TAGS + WidgetTag tag; // The button tag + #endif } GEventGWinButton; /** diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c index f162d8fc..7914ee82 100644 --- a/src/gwin/checkbox.c +++ b/src/gwin/checkbox.c @@ -33,6 +33,9 @@ static void SendCheckboxEvent(GWidgetObject *gw) { pce->type = GEVENT_GWIN_CHECKBOX; pce->checkbox = &gw->g; pce->isChecked = (gw->g.flags & GCHECKBOX_FLG_CHECKED) ? TRUE : FALSE; + #if GWIN_WIDGET_TAGS + pce->tag = gw->tag; + #endif geventSendEvent(psl); } diff --git a/src/gwin/checkbox.h b/src/gwin/checkbox.h index 2b1fb801..ebd35a0b 100644 --- a/src/gwin/checkbox.h +++ b/src/gwin/checkbox.h @@ -38,6 +38,9 @@ typedef struct GEventGWinCheckbox { GEventType type; // The type of this event (GEVENT_GWIN_CHECKBOX) GHandle checkbox; // The checkbox that has been depressed (actually triggered on release) bool_t isChecked; // Is the checkbox currently checked or unchecked? + #if GWIN_WIDGET_TAGS + WidgetTag tag; // The checkbox tag + #endif } GEventGWinCheckbox; /* A Checkbox window */ diff --git a/src/gwin/class_gwin.h b/src/gwin/class_gwin.h index 995121b7..b32e4da2 100644 --- a/src/gwin/class_gwin.h +++ b/src/gwin/class_gwin.h @@ -23,6 +23,10 @@ #if GFX_USE_GWIN || defined(__DOXYGEN__) +#if defined(__KEIL__) || defined(__C51__) + #pragma anon_unions +#endif + /** * @brief The predefined flags for a Window * @{ diff --git a/src/gwin/frame.c b/src/gwin/frame.c index c10aaea3..3f41c69f 100644 --- a/src/gwin/frame.c +++ b/src/gwin/frame.c @@ -38,8 +38,10 @@ static coord_t BorderSizeT(GHandle gh) { return (gh->flags & GWIN_FRAME_BORDER) static void _frameDestroy(GHandle gh) { /* Deregister the button callback */ - geventRegisterCallback(&gh2obj->gl, NULL, NULL); - geventDetachSource(&gh2obj->gl, NULL); + if ((gh->flags & (GWIN_FRAME_CLOSE_BTN|GWIN_FRAME_MINMAX_BTN))) { + geventRegisterCallback(&gh2obj->gl, NULL, NULL); + geventDetachSource(&gh2obj->gl, NULL); + } /* call the gcontainer standard destroy routine */ _gcontainerDestroy(gh); diff --git a/src/gwin/gcontainer.c b/src/gwin/gcontainer.c index 46e89032..2d711ffd 100644 --- a/src/gwin/gcontainer.c +++ b/src/gwin/gcontainer.c @@ -93,11 +93,14 @@ coord_t gwinGetInnerHeight(GHandle gh) { static coord_t BorderSize(GHandle gh) { return (gh->flags & GWIN_CONTAINER_BORDER) ? 2 : 0; } static void DrawSimpleContainer(GWidgetObject *gw, void *param) { - (void) param; - gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background); - if ((gw->g.flags & GWIN_CONTAINER_BORDER)) - gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, (gw->g.flags & GWIN_FLG_SYSENABLED) ? gw->pstyle->enabled.edge : gw->pstyle->disabled.edge); -} + (void)param; + + if (!(gw->g.flags & GWIN_CONTAINER_TRANSPARENT)) + gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background); + + if ((gw->g.flags & GWIN_CONTAINER_BORDER)) + gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, (gw->g.flags & GWIN_FLG_SYSENABLED) ? gw->pstyle->enabled.edge : gw->pstyle->disabled.edge); +} // The container VMT table static const gcontainerVMT containerVMT = { diff --git a/src/gwin/gcontainer.h b/src/gwin/gcontainer.h index efba83f9..942cf8c0 100644 --- a/src/gwin/gcontainer.h +++ b/src/gwin/gcontainer.h @@ -105,6 +105,7 @@ extern "C" { * @{ */ #define GWIN_CONTAINER_BORDER 0x00000001 + #define GWIN_CONTAINER_TRANSPARENT 0x00000002 /** @} */ /** diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c index 8ccb47fc..c9fff50e 100644 --- a/src/gwin/gwidget.c +++ b/src/gwin/gwidget.c @@ -86,6 +86,7 @@ static void gwidgetEvent(void *param, GEvent *pe) { #define pte ((GEventToggle *)pe) #define pde ((GEventDial *)pe) + GHandle h; GHandle gh; #if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL) uint16_t role; @@ -99,32 +100,38 @@ static void gwidgetEvent(void *param, GEvent *pe) { case GEVENT_MOUSE: case GEVENT_TOUCH: // Cycle through all windows - for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) { - - // check if the widget matches this display - if (gh->display != pme->display) - continue; + for(gh = 0, h = gwinGetNextWindow(0); h; h = gwinGetNextWindow(h)) { - // check if it is a widget that is enabled and visible - if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE)) + // The window must be on this display and visible to be relevant + if (h->display != pme->display || !(h->flags & GWIN_FLG_SYSVISIBLE)) continue; - // Are we captured? - if ((gw->g.flags & GWIN_FLG_MOUSECAPTURE)) { + // Is the mouse currently captured by this widget? + if ((h->flags & (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) == (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) { + gh = h; if ((pme->last_buttons & ~pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) { - gw->g.flags &= ~GWIN_FLG_MOUSECAPTURE; + gh->flags &= ~GWIN_FLG_MOUSECAPTURE; if (wvmt->MouseUp) - wvmt->MouseUp(gw, pme->x - gw->g.x, pme->y - gw->g.y); + wvmt->MouseUp(gw, pme->x - gh->x, pme->y - gh->y); } else if (wvmt->MouseMove) - wvmt->MouseMove(gw, pme->x - gw->g.x, pme->y - gw->g.y); + wvmt->MouseMove(gw, pme->x - gh->x, pme->y - gh->y); + + // There is only ever one captured mouse. Prevent normal mouse processing if there is a captured mouse + gh = 0; + break; + } + + // Save the highest z-order window that the mouse is over + if (pme->x >= h->x && pme->x < h->x + h->width && pme->y >= h->y && pme->y < h->y + h->height) + gh = h; + } - // 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; + // Process any mouse down over the highest order window if it is an enabled widget + if (gh && (gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) == (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) { + if ((~pme->last_buttons & pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) { + gh->flags |= GWIN_FLG_MOUSECAPTURE; if (wvmt->MouseDown) - wvmt->MouseDown(gw, pme->x - gw->g.x, pme->y - gw->g.y); + wvmt->MouseDown(gw, pme->x - gh->x, pme->y - gh->y); } } break; @@ -242,6 +249,9 @@ GHandle _gwidgetCreate(GDisplay *g, GWidgetObject *pgw, const GWidgetInit *pInit pgw->fnDraw = pInit->customDraw ? pInit->customDraw : vmt->DefaultDraw; pgw->fnParam = pInit->customParam; pgw->pstyle = pInit->customStyle ? pInit->customStyle : defaultStyle; + #if GWIN_WIDGET_TAGS + pgw->tag = pInit->tag; + #endif return &pgw->g; } @@ -473,5 +483,16 @@ bool_t gwinAttachListener(GListener *pl) { } #endif +#if GWIN_WIDGET_TAGS + void gwinSetTag(GHandle gh, WidgetTag tag) { + if ((gh->flags & GWIN_FLG_WIDGET)) + gw->tag = tag; + } + + WidgetTag gwinGetTag(GHandle gh) { + return ((gh->flags & GWIN_FLG_WIDGET)) ? gw->tag : 0; + } +#endif + #endif /* GFX_USE_GWIN && GWIN_NEED_WIDGET */ /** @} */ diff --git a/src/gwin/gwidget.h b/src/gwin/gwidget.h index 0a7bc72f..bd1ea4c8 100644 --- a/src/gwin/gwidget.h +++ b/src/gwin/gwidget.h @@ -73,6 +73,11 @@ extern const GWidgetStyle WhiteWidgetStyle; typedef void (*CustomWidgetDrawFunction)(struct GWidgetObject *gw, void *param); /** + * @brief Defines a the type of a tag on a widget + */ +typedef uint16_t WidgetTag; + +/** * @brief The structure to initialise a widget. * * @note Some widgets may have extra parameters. @@ -92,6 +97,9 @@ typedef struct GWidgetInit { CustomWidgetDrawFunction customDraw; // @< A custom draw function - use NULL for the standard void * customParam; // @< A parameter for the custom draw function (default = NULL) const GWidgetStyle * customStyle; // @< A custom style to use - use NULL for the default style + #if GWIN_WIDGET_TAGS || defined(__DOXYGEN__) + WidgetTag tag; // @< The tag to associate with the widget + #endif } GWidgetInit; /** @} */ @@ -110,6 +118,9 @@ typedef struct GWidgetObject { CustomWidgetDrawFunction fnDraw; // @< The current draw function void * fnParam; // @< A parameter for the current draw function const GWidgetStyle * pstyle; // @< The current widget style colors + #if GWIN_WIDGET_TAGS || defined(__DOXYGEN__) + WidgetTag tag; // @< The widget tag + #endif } GWidgetObject; /** @} */ @@ -187,6 +198,34 @@ void gwinSetText(GHandle gh, const char *text, bool_t useAlloc); */ const char *gwinGetText(GHandle gh); +#if GWIN_WIDGET_TAGS || defined(__DOXYGEN__) + /** + * @brief Set the tag of a widget. + * + * @param[in] gh The widget handle + * @param[in] tag The tag to set. + * + * @note Non-widgets will ignore this call. + * + * @pre Requires GWIN_WIDGET_TAGS to be TRUE + * + * @api + */ + void gwinSetTag(GHandle gh, WidgetTag tag); + + /** + * @brief Get the tag of a widget. + * @return The widget tag value (or 0 if it is not a widget) + * + * @param[in] gh The widget handle + * + * @pre Requires GWIN_WIDGET_TAGS to be TRUE + * + * @api + */ + WidgetTag gwinGetTag(GHandle gh); +#endif + /** * @brief Set the style of a widget. * @@ -235,7 +274,7 @@ void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param); */ bool_t gwinAttachListener(GListener *pl); -#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE +#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) || defined(__DOXYGEN__) /** * @brief Set the mouse to be used to control the widgets * @return TRUE on success @@ -249,7 +288,7 @@ bool_t gwinAttachListener(GListener *pl); bool_t gwinAttachMouse(uint16_t instance); #endif -#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE +#if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) || defined(__DOXYGEN__) /** * @brief Attach a toggle to a widget * @return TRUE on success @@ -267,7 +306,7 @@ bool_t gwinAttachListener(GListener *pl); bool_t gwinAttachToggle(GHandle gh, uint16_t role, uint16_t instance); #endif -#if GFX_USE_GINPUT && GINPUT_NEED_DIAL +#if (GFX_USE_GINPUT && GINPUT_NEED_DIAL) || defined(__DOXYGEN__) /** * @brief Attach a toggle to a widget * @return TRUE on success diff --git a/src/gwin/list.c b/src/gwin/list.c index c2a857e3..98ec2ed5 100644 --- a/src/gwin/list.c +++ b/src/gwin/list.c @@ -66,6 +66,9 @@ static void sendListEvent(GWidgetObject *gw, int item) { ple->type = GEVENT_GWIN_LIST; ple->list = (GHandle)gw; ple->item = item; + #if GWIN_WIDGET_TAGS + ple->tag = gw->tag; + #endif geventSendEvent(psl); } diff --git a/src/gwin/list.h b/src/gwin/list.h index 9e31bf2a..1eae3c19 100644 --- a/src/gwin/list.h +++ b/src/gwin/list.h @@ -40,6 +40,9 @@ typedef struct GEventGWinList { GEventType type; // The type of this event (GEVENT_GWIN_LIST) GHandle list; // The list int item; // The item that has been selected (or unselected in a multi-select listbox) + #if GWIN_WIDGET_TAGS + WidgetTag tag; // The list tag + #endif } GEventGWinList; // A list window diff --git a/src/gwin/radio.c b/src/gwin/radio.c index af7b877d..557061e4 100644 --- a/src/gwin/radio.c +++ b/src/gwin/radio.c @@ -38,6 +38,9 @@ static void SendRadioEvent(GWidgetObject *gw) { pbe->type = GEVENT_GWIN_RADIO; pbe->radio = (GHandle)gw; pbe->group = ((GRadioObject *)gw)->group; + #if GWIN_WIDGET_TAGS + pbe->tag = gw->tag; + #endif geventSendEvent(psl); } diff --git a/src/gwin/radio.h b/src/gwin/radio.h index 196f8e27..eb7ee719 100644 --- a/src/gwin/radio.h +++ b/src/gwin/radio.h @@ -37,6 +37,9 @@ typedef struct GEventGWinRadio { GEventType type; // The type of this event (GEVENT_GWIN_RADIO) GHandle radio; // The radio button that has been depressed uint16_t group; // The group for this radio button + #if GWIN_WIDGET_TAGS + WidgetTag tag; // The radio tag + #endif } GEventGWinRadio; /** diff --git a/src/gwin/slider.c b/src/gwin/slider.c index b488f823..7ce7b83f 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -38,6 +38,9 @@ static void SendSliderEvent(GWidgetObject *gw) { pse->type = GEVENT_GWIN_SLIDER; pse->slider = (GHandle)gw; pse->position = ((GSliderObject *)gw)->pos; + #if GWIN_WIDGET_TAGS + pse->tag = gw->tag; + #endif geventSendEvent(psl); } diff --git a/src/gwin/slider.h b/src/gwin/slider.h index 41244186..32161d62 100644 --- a/src/gwin/slider.h +++ b/src/gwin/slider.h @@ -30,6 +30,9 @@ typedef struct GEventGWinSlider { GEventType type; // The type of this event (GEVENT_GWIN_BUTTON) GHandle slider; // The slider that is returning results int position; + #if GWIN_WIDGET_TAGS + WidgetTag tag; // The slider tag + #endif } GEventGWinSlider; // There are currently no GEventGWinSlider listening flags - use 0 diff --git a/src/gwin/sys_options.h b/src/gwin/sys_options.h index b1b58a68..d5240556 100644 --- a/src/gwin/sys_options.h +++ b/src/gwin/sys_options.h @@ -128,6 +128,15 @@ * @{ */ /** + * @brief Add a tag to each widget + * @details Defaults to FALSE + * @note Adds a tag member to each widget. Any events created include this tag. + * The enables switch based application logic to detect the event source. + */ + #ifndef GWIN_WIDGET_TAGS + #define GWIN_WIDGET_TAGS FALSE + #endif + /** * @brief Use flat styling for controls rather than a 3D look * @details Defaults to FALSE * @note This may appear better on color-restricted displays |
