aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/modules/gwin/widgets/gfxconf.h1
-rw-r--r--demos/modules/gwin/widgets/main.c14
-rw-r--r--gfxconf.example.h2
-rw-r--r--src/gwin/gwin.h34
-rw-r--r--src/gwin/gwin_checkbox.c10
-rw-r--r--src/gwin/gwin_class.h19
-rw-r--r--src/gwin/gwin_options.h15
-rw-r--r--src/gwin/gwin_radio.c12
-rw-r--r--src/gwin/gwin_wm.c75
9 files changed, 180 insertions, 2 deletions
diff --git a/demos/modules/gwin/widgets/gfxconf.h b/demos/modules/gwin/widgets/gfxconf.h
index e7e2714e..4ba2c21d 100644
--- a/demos/modules/gwin/widgets/gfxconf.h
+++ b/demos/modules/gwin/widgets/gfxconf.h
@@ -51,6 +51,7 @@
#define GFX_USE_GWIN TRUE
#define GWIN_NEED_WINDOWMANAGER TRUE
+ #define GWIN_NEED_FLASHING TRUE
#define GWIN_NEED_CONSOLE TRUE
#define GWIN_CONSOLE_USE_HISTORY TRUE
diff --git a/demos/modules/gwin/widgets/main.c b/demos/modules/gwin/widgets/main.c
index 80cd6c02..d5bfb6d2 100644
--- a/demos/modules/gwin/widgets/main.c
+++ b/demos/modules/gwin/widgets/main.c
@@ -79,6 +79,8 @@ static const GWidgetStyle YellowWidgetStyle = {
static font_t font;
static GListener gl;
static GHandle ghConsole;
+static GTimer FlashTimer;
+
#if GWIN_NEED_TABSET
static GHandle ghTabset;
#else
@@ -485,6 +487,12 @@ static void setEnabled(bool_t ena) {
//gwinSetEnabled(ghCheckDisableAll, TRUE);
}
+static void FlashOffFn(void *param) {
+ (void) param;
+
+ gwinNoFlash(ghCheckbox3);
+}
+
int main(void) {
GEvent * pe;
@@ -517,6 +525,7 @@ int main(void) {
// We want to listen for widget events
geventListenerInit(&gl);
gwinAttachListener(&gl);
+ gtimerInit(&FlashTimer);
#if !GWIN_NEED_TABSET
// Press the Tab we want visible
@@ -543,6 +552,11 @@ int main(void) {
if (((GEventGWinCheckbox *)pe)->gwin == ghCheckDisableAll) {
gwinPrintf(ghConsole, "%s All\n", ((GEventGWinCheckbox *)pe)->isChecked ? "Disable" : "Enable");
setEnabled(!((GEventGWinCheckbox *)pe)->isChecked);
+
+ // If it is the toggle button checkbox start the flash.
+ } else if (((GEventGWinCheckbox *)pe)->gwin == ghCheckbox3) {
+ gwinFlash(ghCheckbox3);
+ gtimerStart(&FlashTimer, FlashOffFn, 0, FALSE, 3000);
}
break;
diff --git a/gfxconf.example.h b/gfxconf.example.h
index 3a91d21a..4c94bb18 100644
--- a/gfxconf.example.h
+++ b/gfxconf.example.h
@@ -148,6 +148,8 @@
//#define GWIN_NEED_WINDOWMANAGER FALSE
// #define GWIN_REDRAW_IMMEDIATE FALSE
// #define GWIN_REDRAW_SINGLEOP FALSE
+// #define GWIN_NEED_FLASHING FALSE
+// #define GWIN_FLASHING_PERIOD 250
//#define GWIN_NEED_CONSOLE FALSE
// #define GWIN_CONSOLE_USE_HISTORY FALSE
diff --git a/src/gwin/gwin.h b/src/gwin/gwin.h
index 81bf38e5..9b2d18b7 100644
--- a/src/gwin/gwin.h
+++ b/src/gwin/gwin.h
@@ -547,6 +547,40 @@ extern "C" {
*/
GHandle gwinGetNextWindow(GHandle gh);
+ /**
+ * @brief Set a window or widget to flash
+ *
+ * @param[in] gh The window handle
+ * @param[in] flash Enable or disable the flashing of the window
+ *
+ * @note The window is automatically redrawn if it supports self-redrawing.
+ * @note When a window is set to flash, its appearance changes in some
+ * way every flash period (GWIN_FLASHING_PERIOD). How its appearance
+ * changes depends on the draw for each window/widget.
+ *
+ * @pre Requires GWIN_NEED_FLASHING to be TRUE
+ *
+ * @api
+ */
+ void gwinSetFlashing(GHandle gh, bool_t flash);
+
+ /**
+ * @brief Enables flashing of a window or widget
+ *
+ * @param[in] gh The window handle
+ *
+ * @api
+ */
+ #define gwinFlash(gh) gwinSetFlashing(gh, TRUE)
+
+ /**
+ * @brief Disables a widget
+ *
+ * @param[in] gh The window handle
+ *
+ * @api
+ */
+ #define gwinNoFlash(gh) gwinSetFlashing(gh, FALSE)
#endif
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
diff --git a/src/gwin/gwin_checkbox.c b/src/gwin/gwin_checkbox.c
index ff0507d9..3f1d46bf 100644
--- a/src/gwin/gwin_checkbox.c
+++ b/src/gwin/gwin_checkbox.c
@@ -216,6 +216,11 @@ void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
pcol = getDrawColors(gw);
+ #if GWIN_NEED_FLASHING
+ // Flash the on and off state.
+ pcol = _gwinGetFlashedColor(gw, pcol, TRUE);
+ #endif
+
gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
gdispGDrawLine(gw->g.display, gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
@@ -232,6 +237,11 @@ void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
pcol = getDrawColors(gw);
+ #if GWIN_NEED_FLASHING
+ // Flash the on and off state.
+ pcol = _gwinGetFlashedColor(gw, pcol, TRUE);
+ #endif
+
/* Fill the box blended from variants of the fill color */
tcol = gdispBlendColor(White, pcol->fill, TOP_FADE);
bcol = gdispBlendColor(Black, pcol->fill, BOTTOM_FADE);
diff --git a/src/gwin/gwin_class.h b/src/gwin/gwin_class.h
index 8cb17ac8..01b6e596 100644
--- a/src/gwin/gwin_class.h
+++ b/src/gwin/gwin_class.h
@@ -47,6 +47,7 @@
#define GWIN_FLG_MINIMIZED 0x00100000 // @< The window is minimized
#define GWIN_FLG_MAXIMIZED 0x00200000 // @< The window is maximized
#define GWIN_FLG_MOUSECAPTURE 0x00400000 // @< The window has captured the mouse
+#define GWIN_FLG_FLASHING 0x00800000 // @< The window is flashing - see the _gwinFlashState boolean
#define GWIN_FIRST_WM_FLAG 0x01000000 // @< 8 bits free for the window manager to use
#define GWIN_LAST_WM_FLAG 0x80000000 // @< 8 bits free for the window manager to use
/** @} */
@@ -165,7 +166,9 @@ typedef struct gwinVMT {
/**
* @brief The current window manager
*/
- extern GWindowManager * _GWINwm;
+ extern GWindowManager * _GWINwm;
+ extern bool_t _gwinFlashState;
+
#endif
#ifdef __cplusplus
@@ -313,6 +316,20 @@ bool_t _gwinWMAdd(GHandle gh, const GWindowInit *pInit);
* @notapi
*/
void _gwinSendEvent(GHandle gh, GEventType type);
+
+
+ #if GWIN_NEED_FLASHING || defined(__DOXYGEN__)
+ /**
+ * @brief Convert a chosen style color set pressed/enabled etc if flashing
+ * @return The colorset - after flashing is taken into account
+ *
+ * @param[in] gw The widget
+ * @param[in] pcol The style color set that has been chosen to reflect the state of the widget
+ * @param[in] flashOffState Whether the off-state should be flashed as well. If false, only the
+ * pressed color set is flashed.
+ */
+ const GColorSet *_gwinGetFlashedColor(GWidgetObject *gw, const GColorSet *pcol, bool_t flashOffState);
+ #endif
#endif
#if GWIN_NEED_CONTAINERS || defined(__DOXYGEN__)
diff --git a/src/gwin/gwin_options.h b/src/gwin/gwin_options.h
index 9252e67a..106c5e06 100644
--- a/src/gwin/gwin_options.h
+++ b/src/gwin/gwin_options.h
@@ -328,6 +328,21 @@
#ifndef GWIN_TABSET_TABHEIGHT
#define GWIN_TABSET_TABHEIGHT 18
#endif
+ /**
+ * @brief Should flashing of widgets be supported
+ * @details Defaults to FALSE
+ * @pre Requires GWIN_NEED_WINDOWMANAGER to be TRUE
+ */
+ #ifndef GWIN_NEED_FLASHING
+ #define GWIN_NEED_FLASHING FALSE
+ #endif
+ /**
+ * @brief What is the period for the flashing timer
+ * @details Defaults to 250 milliseconds
+ */
+ #ifndef GWIN_FLASHING_PERIOD
+ #define GWIN_FLASHING_PERIOD 250
+ #endif
/** @} */
#endif /* _GWIN_OPTIONS_H */
diff --git a/src/gwin/gwin_radio.c b/src/gwin/gwin_radio.c
index 0bafa7cc..b9076109 100644
--- a/src/gwin/gwin_radio.c
+++ b/src/gwin/gwin_radio.c
@@ -203,7 +203,12 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&radioVMT) return;
pcol = getDrawColors(gw);
-
+
+ #if GWIN_NEED_FLASHING
+ // Flash only the on state.
+ pcol = _gwinGetFlashedColor(gw, pcol, FALSE);
+ #endif
+
gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
gdispGDrawLine(gw->g.display, gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
@@ -215,6 +220,11 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&radioVMT) return;
pcol = getDrawColors(gw);
+ #if GWIN_NEED_FLASHING
+ // Flash only the on state.
+ pcol = _gwinGetFlashedColor(gw, pcol, FALSE);
+ #endif
+
if ((gw->g.flags & GRADIO_FLG_PRESSED)) {
gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);
gdispGFillStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
diff --git a/src/gwin/gwin_wm.c b/src/gwin/gwin_wm.c
index 6d860f23..00365c36 100644
--- a/src/gwin/gwin_wm.c
+++ b/src/gwin/gwin_wm.c
@@ -161,9 +161,13 @@
// The default window manager
extern const GWindowManager GNullWindowManager;
GWindowManager * _GWINwm;
+bool_t _gwinFlashState;
static gfxSem gwinsem;
static gfxQueueASync _GWINList;
+#if GWIN_NEED_FLASHING
+ static GTimer FlashTimer;
+#endif
#if !GWIN_REDRAW_IMMEDIATE
static GTimer RedrawTimer;
static void RedrawTimerFn(void *param);
@@ -171,6 +175,7 @@ static gfxQueueASync _GWINList;
static volatile uint8_t RedrawPending;
#define DOREDRAW_INVISIBLES 0x01
#define DOREDRAW_VISIBLES 0x02
+ #define DOREDRAW_FLASHRUNNING 0x04
/*-----------------------------------------------
@@ -181,6 +186,9 @@ void _gwmInit(void)
{
gfxSemInit(&gwinsem, 1, 1);
gfxQueueASyncInit(&_GWINList);
+ #if GWIN_NEED_FLASHING
+ gtimerInit(&FlashTimer);
+ #endif
#if !GWIN_REDRAW_IMMEDIATE
gtimerInit(&RedrawTimer);
gtimerStart(&RedrawTimer, RedrawTimerFn, 0, TRUE, TIME_INFINITE);
@@ -563,6 +571,73 @@ GHandle gwinGetNextWindow(GHandle gh) {
return gh ? (GHandle)gfxQueueASyncNext(&gh->wmq) : (GHandle)gfxQueueASyncPeek(&_GWINList);
}
+#if GWIN_NEED_FLASHING
+ static void FlashTimerFn(void *param) {
+ GHandle gh;
+ (void) param;
+
+ // Assume we will be stopping
+ RedrawPending &= ~DOREDRAW_FLASHRUNNING;
+
+ // Swap the flash state
+ _gwinFlashState = !_gwinFlashState;
+
+ // Redraw all flashing windows
+ for(gh = (GHandle)gfxQueueASyncPeek(&_GWINList); gh; gh = (GHandle)gfxQueueASyncNext(&gh->wmq)) {
+ if ((gh->flags & GWIN_FLG_FLASHING)) {
+ RedrawPending |= DOREDRAW_FLASHRUNNING;
+ _gwinUpdate(gh);
+ }
+ }
+
+ // Do we have no flashers left?
+ if (!(RedrawPending & DOREDRAW_FLASHRUNNING))
+ gtimerStop(&FlashTimer);
+ }
+
+ void gwinSetFlashing(GHandle gh, bool_t flash) {
+
+ // Start flashing?
+ if (flash) {
+ gh->flags |= GWIN_FLG_FLASHING; // A redraw will occur on the next flash period.
+
+ // Start the flash timer if needed
+ if (!(RedrawPending & DOREDRAW_FLASHRUNNING)) {
+ RedrawPending |= DOREDRAW_FLASHRUNNING;
+
+ // Ensure we start the timer with flash bit on
+ _gwinFlashState = FALSE;
+ FlashTimerFn(0); // First flash
+ gtimerStart(&FlashTimer, FlashTimerFn, 0, TRUE, GWIN_FLASHING_PERIOD); // Subsequent flashes
+ }
+
+ // Stop flashing?
+ } else if ((gh->flags & GWIN_FLG_FLASHING)) {
+ gh->flags &= ~GWIN_FLG_FLASHING;
+ // We need to manually redraw as the timer is now turned off for this window
+ _gwinUpdate(gh);
+ }
+ }
+
+ #if GWIN_NEED_WIDGET
+ const GColorSet *_gwinGetFlashedColor(GWidgetObject *gw, const GColorSet *pcol, bool_t flashOffState) {
+ // Does the flashing state affect the current colors?
+ if ((gw->g.flags & GWIN_FLG_FLASHING) && _gwinFlashState) {
+
+ // For a pressed state show an unpressed state
+ if (pcol == &gw->pstyle->pressed)
+ pcol = &gw->pstyle->enabled;
+
+ // For a non-pressed state (if allowed) show a pressed state
+ else if (flashOffState && pcol == &gw->pstyle->enabled)
+ pcol = &gw->pstyle->pressed;
+ }
+ return pcol;
+ }
+ #endif
+#endif
+
+
/*-----------------------------------------------
* "Null" Window Manager Routines
*-----------------------------------------------*/