Add Radio buttons (can also be used as a Tab group)
This commit is contained in:
parent
ab44f32859
commit
5191c278e7
@ -80,6 +80,7 @@
|
||||
#define GWIN_NEED_CHECKBOX TRUE
|
||||
#define GWIN_NEED_LABEL TRUE
|
||||
#define GWIN_NEED_IMAGE TRUE
|
||||
#define GWIN_NEED_RADIO TRUE
|
||||
|
||||
/* Features for the GINPUT sub-system. */
|
||||
#define GINPUT_NEED_MOUSE TRUE
|
||||
|
@ -30,19 +30,36 @@
|
||||
|
||||
static GListener gl;
|
||||
static GHandle ghConsole;
|
||||
static GHandle ghTabButtons, ghTabSliders, ghTabCheckboxes, ghTabLabels, ghTabRadios, ghTabImages;
|
||||
static GHandle ghButton1, ghButton2, ghButton3, ghButton4;
|
||||
static GHandle ghSlider1, ghSlider2, ghSlider3, ghSlider4;
|
||||
static GHandle ghCheckbox1, ghCheckbox2;
|
||||
static GHandle ghLabel1;
|
||||
static GHandle ghRadio1, ghRadio2;
|
||||
//static GHandle ghImage1;
|
||||
|
||||
#define ScrWidth gdispGetWidth()
|
||||
#define ScrHeight gdispGetHeight()
|
||||
|
||||
#define TAB_HEIGHT 30
|
||||
#define BUTTON_WIDTH 50
|
||||
#define BUTTON_HEIGHT 30
|
||||
#define SLIDER_WIDTH 20
|
||||
#define CHECKBOX_WIDTH 80
|
||||
#define CHECKBOX_HEIGHT 20
|
||||
#define RADIO_WIDTH 50
|
||||
#define RADIO_HEIGHT 20
|
||||
#define GROUP_TABS 0
|
||||
#define GROUP_R1R2 1
|
||||
|
||||
static GHandle createTab(GWidgetInit *pwi) {
|
||||
GHandle gh;
|
||||
|
||||
gh = gwinCreateRadio(NULL, pwi, GROUP_TABS);
|
||||
gwinSetCustomDraw(gh, gwinRadioDraw_Tab, 0);
|
||||
gwinSetVisible(gh, TRUE);
|
||||
return gh;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
GEvent * pe;
|
||||
@ -69,10 +86,17 @@ int main(void) {
|
||||
{
|
||||
GWidgetInit wi;
|
||||
|
||||
wi.g.show = TRUE;
|
||||
// Create the Tabs
|
||||
wi.g.show = FALSE; wi.g.width = ScrWidth/6; wi.g.height = TAB_HEIGHT; wi.g.y = 0;
|
||||
wi.g.x = 0*wi.g.width; wi.text = "Buttons"; ghTabButtons = createTab(&wi);
|
||||
wi.g.x = 1*wi.g.width; wi.text = "Sliders"; ghTabSliders = createTab(&wi);
|
||||
wi.g.x = 2*wi.g.width; wi.text = "Checkbox"; ghTabCheckboxes = createTab(&wi);
|
||||
wi.g.x = 3*wi.g.width; wi.text = "Labels"; ghTabLabels = createTab(&wi);
|
||||
wi.g.x = 4*wi.g.width; wi.text = "Radios"; ghTabRadios = createTab(&wi);
|
||||
wi.g.x = 5*wi.g.width; wi.text = "Images"; ghTabImages = createTab(&wi);
|
||||
|
||||
// Buttons
|
||||
wi.g.width = BUTTON_WIDTH; wi.g.height = BUTTON_HEIGHT; wi.g.y = 0;
|
||||
wi.g.width = BUTTON_WIDTH; wi.g.height = BUTTON_HEIGHT; wi.g.y = TAB_HEIGHT+5;
|
||||
wi.g.x = 0+0*(BUTTON_WIDTH+1); wi.text = "B1"; ghButton1 = gwinCreateButton(NULL, &wi);
|
||||
wi.g.x = 0+1*(BUTTON_WIDTH+1); wi.text = "B2"; ghButton2 = gwinCreateButton(NULL, &wi);
|
||||
wi.g.x = 0+2*(BUTTON_WIDTH+1); wi.text = "B3"; ghButton3 = gwinCreateButton(NULL, &wi);
|
||||
@ -90,24 +114,25 @@ int main(void) {
|
||||
|
||||
// Checkboxes - for the 2nd checkbox we apply special drawing before making it visible
|
||||
wi.g.width = CHECKBOX_WIDTH; wi.g.height = CHECKBOX_HEIGHT; wi.g.x = 0;
|
||||
wi.g.y = BUTTON_HEIGHT+1+0*(CHECKBOX_HEIGHT+1); wi.text = "C1"; ghCheckbox1 = gwinCreateCheckbox(NULL, &wi);
|
||||
wi.g.show = FALSE;
|
||||
wi.g.y = BUTTON_HEIGHT+1+1*(CHECKBOX_HEIGHT+1); wi.text = "C2"; ghCheckbox2 = gwinCreateCheckbox(NULL, &wi);
|
||||
wi.g.y = TAB_HEIGHT+5+0*(CHECKBOX_HEIGHT+1); wi.text = "C1"; ghCheckbox1 = gwinCreateCheckbox(NULL, &wi);
|
||||
wi.g.y = TAB_HEIGHT+5+1*(CHECKBOX_HEIGHT+1); wi.text = "C2"; ghCheckbox2 = gwinCreateCheckbox(NULL, &wi);
|
||||
gwinSetCustomDraw(ghCheckbox2, gwinCheckboxDraw_CheckOnRight, 0);
|
||||
gwinSetVisible(ghCheckbox2, TRUE);
|
||||
|
||||
wi.g.show = TRUE; wi.g.width = 0;
|
||||
wi.g.y = BUTTON_HEIGHT+1+2*(CHECKBOX_HEIGHT+1); wi.text = "L1"; ghLabel1 = gwinLabelCreate(NULL, &wi);
|
||||
// Labels
|
||||
wi.g.width = 0; // dynamic width
|
||||
wi.g.y = TAB_HEIGHT+5+2*(CHECKBOX_HEIGHT+1); wi.text = "L1"; ghLabel1 = gwinLabelCreate(NULL, &wi);
|
||||
|
||||
// Radio Buttons
|
||||
wi.g.width = RADIO_WIDTH; wi.g.height = RADIO_HEIGHT; wi.g.y = TAB_HEIGHT+5;
|
||||
wi.g.x = 0*wi.g.width; wi.text = "Yes"; ghRadio1 = gwinCreateRadio(NULL, &wi, GROUP_R1R2);
|
||||
wi.g.x = 1*wi.g.width; wi.text = "No"; ghRadio2 = gwinCreateRadio(NULL, &wi, GROUP_R1R2);
|
||||
|
||||
// Console - we apply some special colors before making it visible
|
||||
wi.g.show = FALSE;
|
||||
wi.g.width = ScrWidth/2-1; wi.g.height = ScrHeight/2-1;
|
||||
wi.g.x = ScrWidth/2+1; wi.g.y = ScrHeight/2+1;
|
||||
ghConsole = gwinCreateConsole(NULL, &wi.g);
|
||||
gwinSetColor(ghConsole, Yellow);
|
||||
gwinSetBgColor(ghConsole, Black);
|
||||
gwinSetVisible(ghConsole, TRUE);
|
||||
gwinClear(ghConsole);
|
||||
}
|
||||
|
||||
// Assign toggles and dials to the buttons & sliders etc.
|
||||
@ -120,15 +145,12 @@ int main(void) {
|
||||
gwinAttachDial(ghSlider3, 0, 1);
|
||||
#endif
|
||||
|
||||
gfxSleepMilliseconds(5000);
|
||||
gwinSetBgColor(ghLabel1, Blue);
|
||||
gwinSetColor(ghLabel1, Yellow);
|
||||
gwinSetText(ghLabel1, "Very Big Label", FALSE);
|
||||
// Make the console visible
|
||||
gwinSetVisible(ghConsole, TRUE);
|
||||
gwinClear(ghConsole);
|
||||
|
||||
gfxSleepMilliseconds(5000);
|
||||
gwinSetBgColor(ghLabel1, Yellow);
|
||||
gwinSetColor(ghLabel1, Red);
|
||||
gwinSetText(ghLabel1, "L1", FALSE);
|
||||
// Press the Buttons Tab
|
||||
gwinPressRadio(ghTabButtons);
|
||||
|
||||
while(1) {
|
||||
// Get an Event
|
||||
@ -144,6 +166,48 @@ int main(void) {
|
||||
case GEVENT_GWIN_CHECKBOX:
|
||||
gwinPrintf(ghConsole, "Checkbox %s=%s\n", gwinGetText(((GEventGWinCheckbox *)pe)->checkbox), ((GEventGWinCheckbox *)pe)->isChecked ? "Checked" : "UnChecked");
|
||||
break;
|
||||
case GEVENT_GWIN_RADIO:
|
||||
gwinPrintf(ghConsole, "Radio Group %u=%s\n", ((GEventGWinRadio *)pe)->group, gwinGetText(((GEventGWinRadio *)pe)->radio));
|
||||
|
||||
// Is this the tab radio's
|
||||
if (((GEventGWinRadio *)pe)->group == GROUP_TABS) {
|
||||
|
||||
// Do some special animation for Label1
|
||||
if (((GEventGWinRadio *)pe)->radio == ghTabLabels) {
|
||||
gwinSetBgColor(ghLabel1, gwinGetDefaultBgColor());
|
||||
gwinSetColor(ghLabel1, gwinGetDefaultColor());
|
||||
}
|
||||
|
||||
// Set control visibility depending on the tab selected
|
||||
gwinSetVisible(ghButton1, ((GEventGWinRadio *)pe)->radio == ghTabButtons);
|
||||
gwinSetVisible(ghButton2, ((GEventGWinRadio *)pe)->radio == ghTabButtons);
|
||||
gwinSetVisible(ghButton3, ((GEventGWinRadio *)pe)->radio == ghTabButtons);
|
||||
gwinSetVisible(ghButton4, ((GEventGWinRadio *)pe)->radio == ghTabButtons);
|
||||
gwinSetVisible(ghSlider1, ((GEventGWinRadio *)pe)->radio == ghTabSliders);
|
||||
gwinSetVisible(ghSlider2, ((GEventGWinRadio *)pe)->radio == ghTabSliders);
|
||||
gwinSetVisible(ghSlider3, ((GEventGWinRadio *)pe)->radio == ghTabSliders);
|
||||
gwinSetVisible(ghSlider4, ((GEventGWinRadio *)pe)->radio == ghTabSliders);
|
||||
gwinSetVisible(ghCheckbox1, ((GEventGWinRadio *)pe)->radio == ghTabCheckboxes);
|
||||
gwinSetVisible(ghCheckbox2, ((GEventGWinRadio *)pe)->radio == ghTabCheckboxes);
|
||||
gwinSetVisible(ghLabel1, ((GEventGWinRadio *)pe)->radio == ghTabLabels);
|
||||
gwinSetVisible(ghRadio1, ((GEventGWinRadio *)pe)->radio == ghTabRadios);
|
||||
gwinSetVisible(ghRadio2, ((GEventGWinRadio *)pe)->radio == ghTabRadios);
|
||||
//gwinSetVisible(ghImage1, ((GEventGWinRadio *)pe)->radio == ghTabImages);
|
||||
|
||||
// Do some special animation for Label1
|
||||
if (((GEventGWinRadio *)pe)->radio == ghTabLabels) {
|
||||
gfxSleepMilliseconds(1000);
|
||||
gwinSetBgColor(ghLabel1, Blue);
|
||||
gwinSetColor(ghLabel1, Yellow);
|
||||
gwinSetText(ghLabel1, "Very Big Label", FALSE);
|
||||
|
||||
gfxSleepMilliseconds(1000);
|
||||
gwinSetBgColor(ghLabel1, Yellow);
|
||||
gwinSetColor(ghLabel1, Red);
|
||||
gwinSetText(ghLabel1, "L1", FALSE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gwinPrintf(ghConsole, "Unknown %d\n", pe->type);
|
||||
break;
|
||||
|
@ -51,7 +51,14 @@
|
||||
#error "GWIN: GDISP_NEED_IMAGE is required when GWIN_NEED_IMAGE is TRUE."
|
||||
#endif
|
||||
#endif
|
||||
#if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX || GWIN_NEED_LABEL
|
||||
#if GWIN_NEED_RADIO
|
||||
#if !GDISP_NEED_CIRCLE
|
||||
#if GFX_DISPLAY_RULE_WARNINGS
|
||||
#warning "GWIN: GDISP_NEED_CIRCLE should be set to TRUE for much nicer radio button widgets."
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX || GWIN_NEED_LABEL || GWIN_NEED_RADIO
|
||||
#if !GWIN_NEED_WIDGET
|
||||
#if GFX_DISPLAY_RULE_WARNINGS
|
||||
#warning "GWIN: GWIN_NEED_WIDGET is required when a Widget is used. It has been turned on for you."
|
||||
|
@ -195,6 +195,9 @@ bool_t gwinAttachListener(GListener *pl);
|
||||
#if GWIN_NEED_CHECKBOX || defined(__DOXYGEN__)
|
||||
#include "gwin/checkbox.h"
|
||||
#endif
|
||||
#if GWIN_NEED_RADIO || defined(__DOXYGEN__)
|
||||
#include "gwin/radio.h"
|
||||
#endif
|
||||
|
||||
#endif /* _GWIDGET_H */
|
||||
/** @} */
|
||||
|
@ -83,6 +83,13 @@
|
||||
#ifndef GWIN_NEED_LABEL
|
||||
#define GWIN_NEED_LABEL FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Should radio button functions be included.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GWIN_NEED_RADIO
|
||||
#define GWIN_NEED_RADIO FALSE
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
169
include/gwin/radio.h
Normal file
169
include/gwin/radio.h
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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 include/gwin/radio.h
|
||||
* @brief GWIN Graphic window subsystem header file.
|
||||
*
|
||||
* @defgroup RadioButton RadioButton
|
||||
* @ingroup GWIN
|
||||
*
|
||||
* @details GWIN allows it to easily create radio buttons with different styles.
|
||||
*
|
||||
* @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h
|
||||
* @pre GWIN_NEED_RADIO must be set to TRUE in your gfxconf.h
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GWIN_RADIO_H
|
||||
#define _GWIN_RADIO_H
|
||||
|
||||
/* This file is included within "gwin/gwidget.h" */
|
||||
|
||||
/**
|
||||
* @brief The Event Type for a Radio Event
|
||||
*/
|
||||
#define GEVENT_GWIN_RADIO (GEVENT_GWIN_FIRST+3)
|
||||
|
||||
/**
|
||||
* @brief A Button Event
|
||||
* @note There are currently no GEventGWinRadio listening flags - use 0 as the flags to @p gwinAttachListener()
|
||||
*/
|
||||
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
|
||||
} GEventGWinRadio;
|
||||
|
||||
/**
|
||||
* @brief Button colors
|
||||
*/
|
||||
typedef struct GRadioColors {
|
||||
color_t color_edge;
|
||||
color_t color_fill;
|
||||
color_t color_txt;
|
||||
} GRadioColors;
|
||||
|
||||
/**
|
||||
* @brief The radio button widget structure
|
||||
* @note Do not use the members directly - treat it as a black-box.
|
||||
*/
|
||||
typedef struct GRadioObject_t {
|
||||
GWidgetObject w;
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
uint16_t toggle;
|
||||
#endif
|
||||
uint16_t group;
|
||||
GRadioColors c_up;
|
||||
GRadioColors c_dn;
|
||||
GRadioColors c_dis;
|
||||
} GRadioObject;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Create a radio widget.
|
||||
* @return NULL if there is no resultant drawing area, otherwise a window handle.
|
||||
*
|
||||
* @param[in] gb The GRadioObject structure to initialise. If this is NULL the structure is dynamically allocated.
|
||||
* @param[in] pInit The initialisation parameters
|
||||
* @param[in] group The group of radio buttons this radio button belongs to.
|
||||
*
|
||||
* @note Only one radio button in any group is ever pressed at one time. Pressing one radio button will
|
||||
* release all others in the group.
|
||||
* @note The drawing color and the background color get set to the current defaults. If you haven't called
|
||||
* @p gwinSetDefaultColor() or @p gwinSetDefaultBgColor() then these are White and Black respectively.
|
||||
* @note The font gets set to the current default font. If you haven't called @p gwinSetDefaultFont() then there
|
||||
* is no default font and text drawing operations will no nothing.
|
||||
* @note A radio button remembers its normal drawing state. If there is a window manager then it is automatically
|
||||
* redrawn if the window is moved or its visibility state is changed.
|
||||
* @note A radio button supports mouse and a toggle input.
|
||||
* @note When assigning a toggle, only one toggle is supported. If you try to assign more than one toggle it will
|
||||
* forget the previous toggle. When assigning a toggle the role parameter must be 0.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
GHandle gwinCreateRadio(GRadioObject *gb, const GWidgetInit *pInit, uint16_t group);
|
||||
|
||||
/**
|
||||
* @brief Set the colors of a button.
|
||||
*
|
||||
* @param[in] gh The window handle (must be a radio widget)
|
||||
* @param[in] pUp The colors for the button when in the up state.
|
||||
* @param[in] pDown The colors for the button when in the down state.
|
||||
* @param[in] pDisabled The colors for the button when it is disabled.
|
||||
*
|
||||
* @note The button is not automatically redrawn. Call gwinButtonDraw() after changing the button style
|
||||
* @note The button style is copied into the internal button structure - there is no need to
|
||||
* maintain static style structures (they can be temporary structures on the stack).
|
||||
* @note The pUp, pDown and pDisabled parameters can be NULL. If they are then the existing color styles
|
||||
* are not changed for that button state.
|
||||
* @note Some custom drawn buttons will ignore he specified colors
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinSetRadioColors(GHandle gh, const GRadioColors *pUp, const GRadioColors *pDown, const GRadioColors *pDisabled);
|
||||
|
||||
/**
|
||||
* @brief Press this radio button (and by definition unset any others in the group)
|
||||
*
|
||||
* @param[in] gh The window handle (must be a radio widget)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void gwinPressRadio(GHandle gh);
|
||||
|
||||
/**
|
||||
* @brief Is the radio button currently pressed
|
||||
* @return TRUE if the button is pressed
|
||||
*
|
||||
* @param[in] gh The window handle (must be a radio widget)
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool_t gwinIsRadioPressed(GHandle gh);
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Some custom radio button drawing routines
|
||||
* @details These function may be passed to @p gwinSetCustomDraw() to get different radio button drawing styles
|
||||
*
|
||||
* @param[in] gw The widget object (in this case a radio button)
|
||||
* @param[in] param A parameter passed in from the user
|
||||
*
|
||||
* @note In your custom radio drawing function you may optionally call these
|
||||
* standard functions and then draw your extra details on top.
|
||||
* @note The standard functions below ignore the param parameter.
|
||||
* @note These custom drawing routines don't have to worry about setting clipping as the framework
|
||||
* sets clipping to the object window prior to calling these routines.
|
||||
*
|
||||
* @api
|
||||
* @{
|
||||
*/
|
||||
void gwinRadioDraw_Radio(GWidgetObject *gw, void *param); // @< A standard radio button
|
||||
void gwinRadioDraw_Button(GWidgetObject *gw, void *param); // @< Draw as a button
|
||||
void gwinRadioDraw_Tab(GWidgetObject *gw, void *param); // @< Draw as a tab
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GWIN_RADIO_H */
|
||||
/** @} */
|
||||
|
@ -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 \
|
||||
|
||||
|
260
src/gwin/radio.c
Normal file
260
src/gwin/radio.c
Normal file
@ -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 */
|
||||
/** @} */
|
||||
|
Loading…
Reference in New Issue
Block a user