aboutsummaryrefslogtreecommitdiffstats
path: root/src/gwin
diff options
context:
space:
mode:
Diffstat (limited to 'src/gwin')
-rw-r--r--src/gwin/button.c3
-rw-r--r--src/gwin/button.h3
-rw-r--r--src/gwin/checkbox.c3
-rw-r--r--src/gwin/checkbox.h3
-rw-r--r--src/gwin/class_gwin.h4
-rw-r--r--src/gwin/frame.c6
-rw-r--r--src/gwin/gcontainer.c13
-rw-r--r--src/gwin/gcontainer.h1
-rw-r--r--src/gwin/gwidget.c57
-rw-r--r--src/gwin/gwidget.h45
-rw-r--r--src/gwin/list.c3
-rw-r--r--src/gwin/list.h3
-rw-r--r--src/gwin/radio.c3
-rw-r--r--src/gwin/radio.h3
-rw-r--r--src/gwin/slider.c3
-rw-r--r--src/gwin/slider.h3
-rw-r--r--src/gwin/sys_options.h9
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