µGFX  2.9
version 2.9
gwin_checkbox.c
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.io/license.html
6  */
7 
8 /**
9  * @file src/gwin/gwin_checkbox.c
10  * @brief GWIN sub-system button code
11  */
12 
13 #include "../../gfx.h"
14 
15 #if (GFX_USE_GWIN && GWIN_NEED_CHECKBOX) || defined(__DOXYGEN__)
16 
17 #include "gwin_class.h"
18 
19 // Parameters for button custom draw
20 #define CHK_TOP_FADE 50 // (CHK_TOP_FADE/255)% fade to white for top of button
21 #define CHK_BOTTOM_FADE 25 // (CHK_BOTTOM_FADE/255)% fade to black for bottom of button
22 
23 // Send the checkbox event
24 static void SendCheckboxEvent(GWidgetObject *gw) {
25  GSourceListener * psl;
26  GEvent * pe;
27  #define pce ((GEventGWinCheckbox *)pe)
28 
29  // Trigger a GWIN Checkbox Event
30  psl = 0;
31  while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
32  if (!(pe = geventGetEventBuffer(psl)))
33  continue;
34  pce->type = GEVENT_GWIN_CHECKBOX;
35  pce->gwin = &gw->g;
36  pce->isChecked = (gw->g.flags & GCHECKBOX_FLG_CHECKED) ? gTrue : gFalse;
37  #if GWIN_WIDGET_TAGS
38  pce->tag = gw->tag;
39  #endif
40  geventSendEvent(psl);
41  }
42 
43  #undef pce
44 }
45 
46 #if GINPUT_NEED_MOUSE
47  static void CheckboxMouseDown(GWidgetObject *gw, gCoord x, gCoord y) {
48  (void) x; (void) y;
50  _gwinUpdate((GHandle)gw);
51  SendCheckboxEvent(gw);
52  }
53 #endif
54 
55 #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
56  static void CheckboxKeyboard(GWidgetObject* gw, GEventKeyboard* pke)
57  {
58  // Only react on KEYDOWN events. Ignore KEYUP events.
59  if ((pke->keystate & GKEYSTATE_KEYUP))
60  return;
61 
62  // ENTER and SPACE keys to check/uncheck the checkbox
63  if (pke->c[0] == GKEY_ENTER || pke->c[0] == GKEY_SPACE) {
65  _gwinUpdate((GHandle)gw);
66  SendCheckboxEvent(gw);
67  }
68  }
69 #endif
70 
71 #if GINPUT_NEED_TOGGLE
72  static void CheckboxToggleOn(GWidgetObject *gw, gU16 role) {
73  (void) role;
75  _gwinUpdate((GHandle)gw);
76  SendCheckboxEvent(gw);
77  }
78 
79  static void CheckboxToggleAssign(GWidgetObject *gw, gU16 role, gU16 instance) {
80  (void) role;
81  ((GCheckboxObject *)gw)->toggle = instance;
82  }
83 
84  static gU16 CheckboxToggleGet(GWidgetObject *gw, gU16 role) {
85  (void) role;
86  return ((GCheckboxObject *)gw)->toggle;
87  }
88 #endif
89 
90 // The checkbox VMT table
91 static const gwidgetVMT checkboxVMT = {
92  {
93  "Checkbox", // The classname
94  sizeof(GCheckboxObject),// The object size
95  _gwidgetDestroy, // The destroy routine
96  _gwidgetRedraw, // The redraw routine
97  0, // The after-clear routine
98  },
99  gwinCheckboxDraw_CheckOnLeft, // The default drawing routine
100  #if GINPUT_NEED_MOUSE
101  {
102  CheckboxMouseDown, // Process mouse down events
103  0, // Process mouse up events (NOT USED)
104  0, // Process mouse move events (NOT USED)
105  },
106  #endif
107  #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
108  {
109  CheckboxKeyboard // Process keyboard events
110  },
111  #endif
112  #if GINPUT_NEED_TOGGLE
113  {
114  1, // 1 toggle role
115  CheckboxToggleAssign, // Assign Toggles
116  CheckboxToggleGet, // Get Toggles
117  0, // Process toggle off events (NOT USED)
118  CheckboxToggleOn, // Process toggle on events
119  },
120  #endif
121  #if GINPUT_NEED_DIAL
122  {
123  0, // No dial roles
124  0, // Assign Dials (NOT USED)
125  0, // Get Dials (NOT USED)
126  0, // Process dial move events (NOT USED)
127  },
128  #endif
129 };
130 
131 GHandle gwinGCheckboxCreate(GDisplay *g, GCheckboxObject *gb, const GWidgetInit *pInit) {
132  if (!(gb = (GCheckboxObject *)_gwidgetCreate(g, &gb->w, pInit, &checkboxVMT)))
133  return 0;
134 
135  #if GINPUT_NEED_TOGGLE
136  gb->toggle = GWIDGET_NO_INSTANCE;
137  #endif
138  gwinSetVisible((GHandle)gb, pInit->g.show);
139  return (GHandle)gb;
140 }
141 
142 void gwinCheckboxCheck(GHandle gh, gBool isChecked) {
143  if (gh->vmt != (gwinVMT *)&checkboxVMT)
144  return;
145 
146  if (isChecked) {
147  if ((gh->flags & GCHECKBOX_FLG_CHECKED)) return;
149  } else {
150  if (!(gh->flags & GCHECKBOX_FLG_CHECKED)) return;
152  }
153  _gwinUpdate(gh);
154  SendCheckboxEvent((GWidgetObject *)gh);
155 }
156 
158  if (gh->vmt != (gwinVMT *)&checkboxVMT)
159  return gFalse;
160 
161  return (gh->flags & GCHECKBOX_FLG_CHECKED) ? gTrue : gFalse;
162 }
163 
164 /*----------------------------------------------------------
165  * Custom Draw Routines
166  *----------------------------------------------------------*/
167 
168 static const GColorSet *getCheckboxColors(GWidgetObject *gw) {
169  if (!(gw->g.flags & GWIN_FLG_SYSENABLED)) return &gw->pstyle->disabled;
170  if ((gw->g.flags & GCHECKBOX_FLG_CHECKED)) return &gw->pstyle->pressed;
171  return &gw->pstyle->enabled;
172 }
173 
175  #define gcw ((GCheckboxObject *)gw)
176  gCoord ld, df;
177  const GColorSet * pcol;
178  (void) param;
179 
180  if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
181  pcol = getCheckboxColors(gw);
182 
183  // Get the dimension of the check box (sans text)
184  ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
185 
186  // Draw the empty check box
187  gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
188  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, ld, ld, pcol->edge);
189 
190  // Draw the check
191  df = ld < 4 ? 1 : 2;
192  if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
193  gdispGFillArea(gw->g.display, gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
194 
195  // Render highlighted border if focused
196  _gwidgetDrawFocusRect(gw, 1, 1, ld-2, ld-2);
197 
198  // Draw the text
199  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, gJustifyLeft);
200  #undef gcw
201 }
202 
204  #define gcw ((GCheckboxObject *)gw)
205  gCoord ep, ld, df;
206  const GColorSet * pcol;
207  (void) param;
208 
209  if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
210  pcol = getCheckboxColors(gw);
211 
212  // Get the dimension of the check box (sans text)
213  ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
214 
215  // Get the position of the check box
216  ep = gw->g.width-ld;
217 
218  // Draw the empty check box
219  gdispGFillArea(gw->g.display, gw->g.x+ep-1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
220  gdispGDrawBox(gw->g.display, gw->g.x+ep, gw->g.y, ld, ld, pcol->edge);
221 
222  // Draw the check
223  df = ld < 4 ? 1 : 2;
224  if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
225  gdispGFillArea(gw->g.display, gw->g.x+ep+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
226 
227  // Render highlighted border if focused
228  _gwidgetDrawFocusRect(gw, ep+1, 1, ld-2, ld-2);
229 
230  // Draw the text
231  gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, ep-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, gJustifyRight);
232  #undef gcw
233 }
234 
235 #if GWIN_FLAT_STYLING
236  void gwinCheckboxDraw_Button(GWidgetObject *gw, void *param) {
237  const GColorSet * pcol;
238  (void) param;
239 
240  if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
241  pcol = getCheckboxColors(gw);
242 
243  #if GWIN_NEED_FLASHING
244  // Flash the on and off state.
245  pcol = _gwinGetFlashedColor(gw, pcol, gTrue);
246  #endif
247 
248  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, gJustifyCenter);
249  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);
250  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);
251  }
252 #else
253  void gwinCheckboxDraw_Button(GWidgetObject *gw, void *param) {
254  const GColorSet * pcol;
255  fixed alpha;
256  fixed dalpha;
257  gCoord i;
258  gColor tcol, bcol;
259  (void) param;
260 
261  if (gw->g.vmt != (gwinVMT *)&checkboxVMT) return;
262  pcol = getCheckboxColors(gw);
263 
264  #if GWIN_NEED_FLASHING
265  // Flash the on and off state.
266  pcol = _gwinGetFlashedColor(gw, pcol, gTrue);
267  #endif
268 
269  /* Fill the box blended from variants of the fill color */
270  tcol = gdispBlendColor(GFX_WHITE, pcol->fill, CHK_TOP_FADE);
271  bcol = gdispBlendColor(GFX_BLACK, pcol->fill, CHK_BOTTOM_FADE);
272  dalpha = FIXED(255)/gw->g.height;
273  for(alpha = 0, i = 0; i < gw->g.height; i++, alpha += dalpha)
274  gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+i, gw->g.x+gw->g.width-2, gw->g.y+i, gdispBlendColor(bcol, tcol, NONFIXED(alpha)));
275 
276  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, gJustifyCenter);
277  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);
278  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);
279  }
280 #endif
281 
282 #endif /* (GFX_USE_GWIN && GWIN_NEED_CHECKBOX) */
GHandle gwinGCheckboxCreate(GDisplay *g, GCheckboxObject *gb, const GWidgetInit *pInit)
Create a checkbox window.
gBool gwinCheckboxIsChecked(GHandle gh)
Get the state of a checkbox.
void gwinCheckboxCheck(GHandle gh, gBool isChecked)
Set the state of a checkbox.
#define GCHECKBOX_FLG_CHECKED
The internal checkbox flags.
Definition: gwin_checkbox.h:53
COLOR_TYPE gColor
The color type definition.
Definition: gdisp_colors.h:437
gColor gdispBlendColor(gColor fg, gColor bg, gU8 alpha)
Blend 2 colors according to the alpha.
void gdispGDrawStringBox(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, const char *str, gFont font, gColor color, gJustify justify)
Draw a text string vertically centered within the specified box.
void gdispGFillArea(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, gColor color)
Fill an area with a color.
void gdispGDrawLine(GDisplay *g, gCoord x0, gCoord y0, gCoord x1, gCoord y1, gColor color)
Draw a line.
void gdispGFillStringBox(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, const char *str, gFont font, gColor color, gColor bgColor, gJustify justify)
Draw a text string vertically centered within the specified box. The box background is filled with th...
gI16 gCoord
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
void gdispGDrawBox(GDisplay *g, gCoord x, gCoord y, gCoord cx, gCoord cy, gColor color)
Draw a rectangular box.
@ gJustifyCenter
Definition: gdisp.h:62
@ gJustifyLeft
Definition: gdisp.h:61
@ gJustifyRight
Definition: gdisp.h:63
GEvent * geventGetEventBuffer(GSourceListener *psl)
Get the event buffer from the GSourceListener.
Definition: gevent.c:187
void geventSendEvent(GSourceListener *psl)
Called by a source to indicate the listener's event buffer has been filled.
Definition: gevent.c:200
GSourceListener * geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr)
Called by a source with a possible event to get a listener record.
Definition: gevent.c:163
gI32 fixed
The type for a fixed point type.
Definition: gmisc.h:60
#define FIXED(x)
Macros to convert to and from a fixed point.
Definition: gmisc.h:66
void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param)
Renders a square checkbox where the text is on the left side of the checkbox.
void gwinCheckboxDraw_Button(GWidgetObject *gw, void *param)
Renders a checkbox in form of a rectangular button with the text inside of it.
void gwinCheckboxDraw_CheckOnLeft(GWidgetObject *gw, void *param)
Renders a square checkbox where the text is on the right side of the checkbox.
void gwinSetVisible(GHandle gh, gBool visible)
Sets whether a window is visible or not.
The GColorSet structure.
Definition: gwin_widget.h:37
gColor fill
Definition: gwin_widget.h:40
gColor text
Definition: gwin_widget.h:38
gColor edge
Definition: gwin_widget.h:39
The structure to initialise a widget.
Definition: gwin_widget.h:97
GWindowInit g
Definition: gwin_widget.h:98
The GWIN Widget structure.
Definition: gwin_widget.h:118
GWindowObject g
Definition: gwin_widget.h:119
const GWidgetStyle * pstyle
Definition: gwin_widget.h:123
WidgetTag tag
Definition: gwin_widget.h:125
const char * text
Definition: gwin_widget.h:120
gColor background
Definition: gwin_widget.h:53
GColorSet disabled
Definition: gwin_widget.h:56
GColorSet enabled
Definition: gwin_widget.h:55
GColorSet pressed
Definition: gwin_widget.h:57
gBool show
Definition: gwin.h:80
A window object structure.
Definition: gwin.h:40
GDisplay * display
Definition: gwin.h:46
gCoord x
Definition: gwin.h:47
gCoord width
Definition: gwin.h:49
const struct gwinVMT * vmt
Definition: gwin.h:45
gU32 flags
Definition: gwin.h:53
gCoord y
Definition: gwin.h:48
gCoord height
Definition: gwin.h:50
The Virtual Method Table for a widget.
Definition: gwin_class.h:85
The Virtual Method Table for a GWIN window.
Definition: gwin_class.h:55