aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2013-07-06 01:46:34 +1000
committerinmarket <andrewh@inmarket.com.au>2013-07-06 01:46:34 +1000
commit5191c278e7195de62b619be58c19ea338c31d54c (patch)
treee7083e1d084b141f390d740c6d1c139c95421c7d /src
parentab44f32859ac61072a561869787089e13adaf509 (diff)
downloaduGFX-5191c278e7195de62b619be58c19ea338c31d54c.tar.gz
uGFX-5191c278e7195de62b619be58c19ea338c31d54c.tar.bz2
uGFX-5191c278e7195de62b619be58c19ea338c31d54c.zip
Add Radio buttons (can also be used as a Tab group)
Diffstat (limited to 'src')
-rw-r--r--src/gwin/gwin.mk1
-rw-r--r--src/gwin/radio.c260
2 files changed, 261 insertions, 0 deletions
diff --git a/src/gwin/gwin.mk b/src/gwin/gwin.mk
index b9e6a9ee..92b10b7b 100644
--- a/src/gwin/gwin.mk
+++ b/src/gwin/gwin.mk
@@ -8,4 +8,5 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \
$(GFXLIB)/src/gwin/checkbox.c \
$(GFXLIB)/src/gwin/gimage.c \
$(GFXLIB)/src/gwin/label.c \
+ $(GFXLIB)/src/gwin/radio.c \
diff --git a/src/gwin/radio.c b/src/gwin/radio.c
new file mode 100644
index 00000000..d1c65dbc
--- /dev/null
+++ b/src/gwin/radio.c
@@ -0,0 +1,260 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://chibios-gfx.com/license.html
+ */
+
+/**
+ * @file src/gwin/radio.c
+ * @brief GWIN sub-system radio button code.
+ *
+ * @defgroup RadioButton RadioButton
+ * @ingroup GWIN
+ *
+ * @{
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GWIN && GWIN_NEED_RADIO
+
+#include "gwin/class_gwin.h"
+
+// Our pressed state
+#define GRADIO_FLG_PRESSED (GWIN_FIRST_CONTROL_FLAG<<0)
+
+// Default color scheme
+static const GRadioColors GRadioDefaultColorsUp = {
+ HTML2COLOR(0x404040), // color_up_edge;
+ HTML2COLOR(0xE0E0E0), // color_up_fill;
+ HTML2COLOR(0x000000), // color_up_txt;
+};
+static const GRadioColors GRadioDefaultColorsDown = {
+ HTML2COLOR(0x404040), // color_dn_edge;
+ HTML2COLOR(0x808080), // color_dn_fill;
+ HTML2COLOR(0x404040), // color_dn_txt;
+};
+static const GRadioColors GRadioDefaultColorsDisabled = {
+ HTML2COLOR(0x808080), // color_dis_edge;
+ HTML2COLOR(0xE0E0E0), // color_dis_fill;
+ HTML2COLOR(0xC0C0C0), // color_dis_txt;
+};
+
+// Send the button event
+static void SendButtonEvent(GWidgetObject *gw) {
+ GSourceListener * psl;
+ GEvent * pe;
+ #define pbe ((GEventGWinRadio *)pe)
+
+ // Trigger a GWIN Button Event
+ psl = 0;
+ while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
+ if (!(pe = geventGetEventBuffer(psl)))
+ continue;
+ pbe->type = GEVENT_GWIN_RADIO;
+ pbe->radio = (GHandle)gw;
+ pbe->group = ((GRadioObject *)gw)->group;
+ geventSendEvent(psl);
+ }
+
+ #undef pbe
+}
+
+#if GINPUT_NEED_MOUSE
+ // A mouse down has occurred over the button
+ static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
+ (void) x; (void) y;
+
+ gwinPressRadio((GHandle)gw);
+ }
+#endif
+
+#if GINPUT_NEED_TOGGLE
+ // A toggle on has occurred
+ static void ToggleOn(GWidgetObject *gw, uint16_t role) {
+ (void) role;
+
+ gwinPressRadio((GHandle)gw);
+ }
+
+ static void ToggleAssign(GWidgetObject *gw, uint16_t role, uint16_t instance) {
+ (void) role;
+ ((GRadioObject *)gw)->toggle = instance;
+ }
+
+ static uint16_t ToggleGet(GWidgetObject *gw, uint16_t role) {
+ (void) role;
+ return ((GRadioObject *)gw)->toggle;
+ }
+#endif
+
+// The radio button VMT table
+static const gwidgetVMT radioVMT = {
+ {
+ "Radio", // The classname
+ sizeof(GRadioObject), // The object size
+ _gwidgetDestroy, // The destroy routine
+ _gwidgetRedraw, // The redraw routine
+ 0, // The after-clear routine
+ },
+ gwinRadioDraw_Radio, // The default drawing routine
+ #if GINPUT_NEED_MOUSE
+ {
+ MouseDown, // Process mouse down events
+ 0, // Process mouse up events (NOT USED)
+ 0, // Process mouse move events (NOT USED)
+ },
+ #endif
+ #if GINPUT_NEED_TOGGLE
+ {
+ 1, // 1 toggle role
+ ToggleAssign, // Assign Toggles
+ ToggleGet, // Get Toggles
+ 0, // Process toggle off events (NOT USED)
+ ToggleOn, // Process toggle on events
+ },
+ #endif
+ #if GINPUT_NEED_DIAL
+ {
+ 0, // No dial roles
+ 0, // Assign Dials (NOT USED)
+ 0, // Get Dials (NOT USED)
+ 0, // Process dial move events (NOT USED)
+ },
+ #endif
+};
+
+GHandle gwinCreateRadio(GRadioObject *gw, const GWidgetInit *pInit, uint16_t group) {
+ if (!(gw = (GRadioObject *)_gwidgetCreate(&gw->w, pInit, &radioVMT)))
+ return 0;
+
+ #if GINPUT_NEED_TOGGLE
+ gw->toggle = GWIDGET_NO_INSTANCE;
+ #endif
+ gw->group = group;
+ gw->c_up = GRadioDefaultColorsUp;
+ gw->c_dn = GRadioDefaultColorsDown;
+ gw->c_dis = GRadioDefaultColorsDisabled;
+ gwinSetVisible((GHandle)gw, pInit->g.show);
+ return (GHandle)gw;
+}
+
+void gwinSetRadioColors(GHandle gh, const GRadioColors *pUp, const GRadioColors *pDown, const GRadioColors *pDisabled) {
+ if (gh->vmt != (gwinVMT *)&radioVMT)
+ return;
+
+ if (pUp) ((GRadioObject *)gh)->c_up = *pUp;
+ if (pDown) ((GRadioObject *)gh)->c_dn = *pDown;
+ if (pDisabled) ((GRadioObject *)gh)->c_dis = *pDisabled;
+}
+
+void gwinPressRadio(GHandle gh) {
+ GHandle gx;
+
+ if (gh->vmt != (gwinVMT *)&radioVMT || (gh->flags & GRADIO_FLG_PRESSED))
+ return;
+
+ if ((gx = gwinActiveRadio(((GRadioObject *)gh)->group))) {
+ gx->flags &= ~GRADIO_FLG_PRESSED;
+ _gwidgetRedraw(gx);
+ }
+ gh->flags |= GRADIO_FLG_PRESSED;
+ _gwidgetRedraw(gh);
+ SendButtonEvent((GWidgetObject *)gh);
+}
+
+bool_t gwinIsRadioPressed(GHandle gh) {
+ if (gh->vmt != (gwinVMT *)&radioVMT)
+ return FALSE;
+
+ return (gh->flags & GRADIO_FLG_PRESSED) ? TRUE : FALSE;
+}
+
+/**
+ * @brief Find the currently pressed radio button in the specified group
+ * @return The handle of the pressed radio button or NULL if none are pressed
+ *
+ * @param[in] gh The window handle (must be a radio widget)
+ *
+ * @api
+ */
+GHandle gwinActiveRadio(uint16_t group) {
+ const gfxQueueASyncItem * qi;
+ GHandle gh;
+
+ for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
+ gh = QItem2GWindow(qi);
+ if (gh->vmt == (gwinVMT *)&radioVMT && ((GRadioObject *)gh)->group == group && (gh->flags & GRADIO_FLG_PRESSED))
+ return gh;
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------
+ * Custom Draw Routines
+ *----------------------------------------------------------*/
+
+static GRadioColors *getDrawColors(GWidgetObject *gw) {
+ if (!(gw->g.flags & GWIN_FLG_ENABLED)) return &((GRadioObject *)gw)->c_dis;
+ if ((gw->g.flags & GRADIO_FLG_PRESSED)) return &((GRadioObject *)gw)->c_dn;
+ return &((GRadioObject *)gw)->c_up;
+}
+
+void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
+ #define gcw ((GRadioObject *)gw)
+ coord_t ld, df;
+ GRadioColors * pcol;
+ (void) param;
+
+ if (gw->g.vmt != (gwinVMT *)&radioVMT) return;
+ pcol = getDrawColors(gw);
+
+ ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
+
+ #if GDISP_NEED_CIRCLE
+ df = ld/2;
+ gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->g.bgcolor);
+ gdispDrawCircle(gw->g.x+df, gw->g.y+df, df, pcol->color_edge);
+
+ if (gw->g.flags & GRADIO_FLG_PRESSED)
+ gdispFillCircle(gw->g.x+df, gw->g.y+df, df <= 2 ? 1 : (df-2), pcol->color_fill);
+ #else
+ gdispFillArea(gw->g.x+1, gw->g.y+1, ld, ld-2, gw->g.bgcolor);
+ gdispDrawBox(gw->g.x, gw->g.y, ld, ld, pcol->color_edge);
+
+ df = ld < 4 ? 1 : 2;
+ if (gw->g.flags & GRADIO_FLG_PRESSED)
+ gdispFillArea(gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->color_fill);
+ #endif
+
+ gdispFillStringBox(gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->txt, gw->g.font, pcol->color_txt, gw->g.bgcolor, justifyLeft);
+ #undef gcw
+}
+
+void gwinRadioDraw_Button(GWidgetObject *gw, void *param) {
+ (void) param;
+ GRadioColors * pcol;
+
+ if (gw->g.vmt != (gwinVMT *)&radioVMT) return;
+ pcol = getDrawColors(gw);
+
+ gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter);
+ gdispDrawLine(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->color_edge);
+ gdispDrawLine(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->color_edge);
+}
+
+void gwinRadioDraw_Tab(GWidgetObject *gw, void *param) {
+ (void) param;
+ GRadioColors * pcol;
+
+ if (gw->g.vmt != (gwinVMT *)&radioVMT) return;
+ pcol = getDrawColors(gw);
+
+ gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->txt, gw->g.font, pcol->color_txt, pcol->color_fill, justifyCenter);
+ gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->color_edge);
+}
+
+#endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */
+/** @} */
+