From e0f22d9cb8990c6535d0bac0de8143eb1b3b1b2f Mon Sep 17 00:00:00 2001
From: Steffen Schroeter <steffen@vexar.de>
Date: Fri, 19 Jan 2018 14:21:58 +0100
Subject: Add keyboard input to radio widget

---
 src/gwin/gwin_class.h  | 15 +++++++++++++++
 src/gwin/gwin_radio.c  | 30 +++++++++++++++++++++++++++++-
 src/gwin/gwin_widget.c | 11 +++++++++++
 3 files changed, 55 insertions(+), 1 deletion(-)

(limited to 'src/gwin')

diff --git a/src/gwin/gwin_class.h b/src/gwin/gwin_class.h
index ea5c260c..454c13ff 100644
--- a/src/gwin/gwin_class.h
+++ b/src/gwin/gwin_class.h
@@ -359,9 +359,24 @@ bool_t _gwinWMAdd(GHandle gh, const GWindowInit *pInit);
 		 */
 		void _gwidgetDrawFocusRect(GWidgetObject *gw, coord_t x, coord_t y, coord_t cx, coord_t cy);
 
+		/**
+		 * @brief	Draw a simple focus circle in the default style.
+		 *
+		 * @param[in]	gw		The widget
+		 * @param[in]	radius	The radius of the circle
+		 *
+		 * @note		Assumes the widget is in a state where it can draw.
+		 * @note		Nothing is drawn if the window doesn't have focus.
+		 * @note		The focus circle may be more than one pixel thick.
+		 *
+		 * @notapi
+		 */
+		void _gwidgetDrawFocusCircle(GWidgetObject *gx, coord_t radius);
+
 	#else
 		#define _gwinFixFocus(gh)
 		#define _gwidgetDrawFocusRect(gh,x,y,cx,cy)
+		#define _gwidgetDrawFocusCircle(gh,radius)
 	#endif
 
 	#if GWIN_NEED_FLASHING || defined(__DOXYGEN__)
diff --git a/src/gwin/gwin_radio.c b/src/gwin/gwin_radio.c
index 6d9bd60e..faa20ab9 100644
--- a/src/gwin/gwin_radio.c
+++ b/src/gwin/gwin_radio.c
@@ -53,6 +53,20 @@ static void SendRadioEvent(GWidgetObject *gw) {
 	}
 #endif
 
+#if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
+	static void RadioKeyboard(GWidgetObject* gw, GEventKeyboard* pke)
+	{
+		// Only react on KEYDOWN events. Ignore KEYUP events.
+		if ((pke->keystate & GKEYSTATE_KEYUP))
+			return;
+
+		// ENTER and SPACE keys to check/uncheck the checkbox
+		if (pke->c[0] == GKEY_ENTER || pke->c[0] == GKEY_SPACE) {
+			gwinRadioPress((GHandle)gw);
+		}
+	}
+#endif
+
 #if GINPUT_NEED_TOGGLE
 	// A toggle on has occurred
 	static void RadioToggleOn(GWidgetObject *gw, uint16_t role) {
@@ -91,7 +105,7 @@ static const gwidgetVMT radioVMT = {
 	#endif
 	#if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
 		{
-			0						// Process keyboard events
+			RadioKeyboard			// Process keyboard events
 		},
 	#endif
 	#if GINPUT_NEED_TOGGLE
@@ -194,6 +208,8 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
 			gdispGFillArea(gw->g.display, gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
 	#endif
 
+	_gwidgetDrawFocusCircle(gw, df);
+
 	gdispGFillStringBox(gw->g.display, gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
 	#undef gcw
 }
@@ -214,6 +230,9 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
 		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);
+
+		// Render highlighted border if focused
+		_gwidgetDrawFocusRect(gw, 1, 1, gw->g.width-2, gw->g.height-2);
 	}
 	void gwinRadioDraw_Tab(GWidgetObject *gw, void *param) {
 		const GColorSet *	pcol;
@@ -235,6 +254,9 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
 			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);
 		}
+
+		// Render highlighted border if focused
+		_gwidgetDrawFocusRect(gw, 0, 0, gw->g.width-1, gw->g.height-1);
 	}
 #else
 	void gwinRadioDraw_Button(GWidgetObject *gw, void *param) {
@@ -258,6 +280,9 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
 		gdispGDrawStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, 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);
+
+		// Render highlighted border if focused
+		_gwidgetDrawFocusRect(gw, 0, 0, gw->g.width-1, gw->g.height-1);
 	}
 	void gwinRadioDraw_Tab(GWidgetObject *gw, void *param) {
 		const GColorSet *	pcol;
@@ -286,6 +311,9 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
 			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);
 			gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
 		}
+
+		// Render highlighted border if focused
+		_gwidgetDrawFocusRect(gw, 0, 0, gw->g.width-1, gw->g.height-1);
 	}
 #endif
 
diff --git a/src/gwin/gwin_widget.c b/src/gwin/gwin_widget.c
index 34b047eb..52ad90ad 100644
--- a/src/gwin/gwin_widget.c
+++ b/src/gwin/gwin_widget.c
@@ -330,6 +330,17 @@ static void gwidgetEvent(void *param, GEvent *pe) {
 		}
 	}
 
+	void _gwidgetDrawFocusCircle(GWidgetObject *gx, coord_t radius) {
+		coord_t i;
+
+		// Don't do anything if we don't have the focus
+		if (&gx->g != _widgetInFocus)
+			return;
+    
+		for (i = 0; i < GWIN_FOCUS_HIGHLIGHT_WIDTH; i++) {
+			gdispGDrawCircle(gx->g.display, gx->g.x + radius, gx->g.y + radius, radius + i, gx->pstyle->focus);
+		}
+	}
 #endif
 
 #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
-- 
cgit v1.2.3


From c119ca4a5dd8df57d39a57a530cc5b01adf699e8 Mon Sep 17 00:00:00 2001
From: Steffen Schroeter <steffen@vexar.de>
Date: Tue, 23 Jan 2018 14:05:11 +0100
Subject: Added missing check for GDISP_NEED_CIRCLE

---
 src/gwin/gwin_class.h  |  4 +++-
 src/gwin/gwin_widget.c | 20 +++++++++++---------
 2 files changed, 14 insertions(+), 10 deletions(-)

(limited to 'src/gwin')

diff --git a/src/gwin/gwin_class.h b/src/gwin/gwin_class.h
index 454c13ff..4b173e3c 100644
--- a/src/gwin/gwin_class.h
+++ b/src/gwin/gwin_class.h
@@ -371,7 +371,9 @@ bool_t _gwinWMAdd(GHandle gh, const GWindowInit *pInit);
 		 *
 		 * @notapi
 		 */
-		void _gwidgetDrawFocusCircle(GWidgetObject *gx, coord_t radius);
+		#if GDISP_NEED_CIRCLE
+			void _gwidgetDrawFocusCircle(GWidgetObject *gx, coord_t radius);
+		#endif
 
 	#else
 		#define _gwinFixFocus(gh)
diff --git a/src/gwin/gwin_widget.c b/src/gwin/gwin_widget.c
index 52ad90ad..38b4e236 100644
--- a/src/gwin/gwin_widget.c
+++ b/src/gwin/gwin_widget.c
@@ -330,17 +330,19 @@ static void gwidgetEvent(void *param, GEvent *pe) {
 		}
 	}
 
-	void _gwidgetDrawFocusCircle(GWidgetObject *gx, coord_t radius) {
-		coord_t i;
+	#if GDISP_NEED_CIRCLE
+		void _gwidgetDrawFocusCircle(GWidgetObject *gx, coord_t radius) {
+			coord_t i;
 
-		// Don't do anything if we don't have the focus
-		if (&gx->g != _widgetInFocus)
-			return;
-    
-		for (i = 0; i < GWIN_FOCUS_HIGHLIGHT_WIDTH; i++) {
-			gdispGDrawCircle(gx->g.display, gx->g.x + radius, gx->g.y + radius, radius + i, gx->pstyle->focus);
+			// Don't do anything if we don't have the focus
+			if (&gx->g != _widgetInFocus)
+				return;
+
+			for (i = 0; i < GWIN_FOCUS_HIGHLIGHT_WIDTH; i++) {
+				gdispGDrawCircle(gx->g.display, gx->g.x + radius, gx->g.y + radius, radius + i, gx->pstyle->focus);
+			}
 		}
-	}
+	#endif
 #endif
 
 #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
-- 
cgit v1.2.3