µGFX  2.9
version 2.9
gwin_widget.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_widget.c
10  * @brief GWIN sub-system widget code
11  */
12 
13 #include "../../gfx.h"
14 
15 #if GFX_USE_GWIN && GWIN_NEED_WIDGET
16 
17 #include <string.h>
18 
19 #include "gwin_class.h"
20 
21 // Our listener for events for widgets
22 static GListener gl;
23 
24 #if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD
25  // Our current focus window
26  static GHandle _widgetInFocus;
27 #endif
28 
29 // Our default style - a white background theme
30 const GWidgetStyle WhiteWidgetStyle = {
31  HTML2COLOR(0xFFFFFF), // window background
32  HTML2COLOR(0x2A8FCD), // focused
33 
34  // enabled color set
35  {
36  HTML2COLOR(0x000000), // text
37  HTML2COLOR(0x404040), // edge
38  HTML2COLOR(0xE0E0E0), // fill
39  HTML2COLOR(0x00E000) // progress - active area
40  },
41 
42  // disabled color set
43  {
44  HTML2COLOR(0xC0C0C0), // text
45  HTML2COLOR(0x808080), // edge
46  HTML2COLOR(0xE0E0E0), // fill
47  HTML2COLOR(0xC0E0C0) // progress - active area
48  },
49 
50  // pressed color set
51  {
52  HTML2COLOR(0x404040), // text
53  HTML2COLOR(0x404040), // edge
54  HTML2COLOR(0x808080), // fill
55  HTML2COLOR(0x00E000) // progress - active area
56  }
57 };
58 
59 /* Our black style */
61  HTML2COLOR(0x000000), // window background
62  HTML2COLOR(0x2A8FCD), // focused
63 
64  // enabled color set
65  {
66  HTML2COLOR(0xC0C0C0), // text
67  HTML2COLOR(0xC0C0C0), // edge
68  HTML2COLOR(0x606060), // fill
69  HTML2COLOR(0x008000) // progress - active area
70  },
71 
72  // disabled color set
73  {
74  HTML2COLOR(0x808080), // text
75  HTML2COLOR(0x404040), // edge
76  HTML2COLOR(0x404040), // fill
77  HTML2COLOR(0x004000) // progress - active area
78  },
79 
80  // pressed color set
81  {
82  HTML2COLOR(0xFFFFFF), // text
83  HTML2COLOR(0xC0C0C0), // edge
84  HTML2COLOR(0xE0E0E0), // fill
85  HTML2COLOR(0x008000) // progress - active area
86  }
87 };
88 
89 static const GWidgetStyle * defaultStyle = &BlackWidgetStyle;
90 
91 // We use these everywhere in this file
92 #define gw ((GWidgetObject *)gh)
93 #define wvmt ((gwidgetVMT *)gh->vmt)
94 
95 // Process an event
96 static void gwidgetEvent(void *param, GEvent *pe) {
97  #define pme ((GEventMouse *)pe)
98  #define pke ((GEventKeyboard *)pe)
99  #define pte ((GEventToggle *)pe)
100  #define pde ((GEventDial *)pe)
101 
102  #if GFX_USE_GINPUT
103  #if GINPUT_NEED_MOUSE
104  GHandle h;
105  #endif
106  #if GINPUT_NEED_MOUSE || GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL || GINPUT_NEED_KEYBOARD
107  GHandle gh;
108  #endif
109  #if GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL
110  gU16 role;
111  #endif
112  #endif
113 
114  (void) param;
115 
116  // Process various events
117  switch (pe->type) {
118 
119  #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
120  case GEVENT_MOUSE:
121  case GEVENT_TOUCH:
122  // Cycle through all windows
123  for (gh = 0, h = gwinGetNextWindow(0); h; h = gwinGetNextWindow(h)) {
124 
125  // The window must be on this display and visible to be relevant
126  if (h->display != pme->display || !(h->flags & GWIN_FLG_SYSVISIBLE))
127  continue;
128 
129  // Is the mouse currently captured by this widget?
130  if ((h->flags & (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) == (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) {
131  gh = h;
132  if ((pme->buttons & GMETA_MOUSE_UP)) {
133  gh->flags &= ~GWIN_FLG_MOUSECAPTURE;
134  if (wvmt->MouseUp)
135  wvmt->MouseUp(gw, pme->x - gh->x, pme->y - gh->y);
136  } else if (wvmt->MouseMove)
137  wvmt->MouseMove(gw, pme->x - gh->x, pme->y - gh->y);
138 
139  // There is only ever one captured mouse. Prevent normal mouse processing if there is a captured mouse
140  gh = 0;
141 
142  break;
143  }
144 
145  // Save the highest z-order window that the mouse is over
146  if (pme->x >= h->x && pme->x < h->x + h->width && pme->y >= h->y && pme->y < h->y + h->height)
147  gh = h;
148  }
149 
150  // Process any mouse down over the highest order window if it is an enabled widget
151  if (gh && (gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) == (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) {
152  if ((pme->buttons & GMETA_MOUSE_DOWN)) {
153  gh->flags |= GWIN_FLG_MOUSECAPTURE;
154 
155  #if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD
156  // We should try and capture the focus on this window.
157  // If we can't then we don't change the focus
158  gwinSetFocus(gh);
159  #endif
160 
161  if (wvmt->MouseDown)
162  wvmt->MouseDown(gw, pme->x - gh->x, pme->y - gh->y);
163  }
164  }
165  break;
166  #endif
167 
168  #if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD
169  case GEVENT_KEYBOARD:
170  // If Tab key pressed then set focus to next widget
171  if (pke->bytecount == 1 && pke->c[0] == GKEY_TAB) {
172  if (!(pke->keystate & GKEYSTATE_KEYUP))
173  _gwinMoveFocus();
174  break;
175  }
176 
177  // Otherwise, send keyboard events only to widget in focus
178  if (_widgetInFocus)
179  ((gwidgetVMT*)_widgetInFocus->vmt)->KeyboardEvent((GWidgetObject*)_widgetInFocus, pke);
180  break;
181  #endif
182 
183  #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
184  case GEVENT_TOGGLE:
185  // Cycle through all windows
186  for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
187 
188  // check if it a widget that is enabled and visible
189  if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE))
190  continue;
191 
192  for(role = 0; role < wvmt->toggleroles; role++) {
193  if (wvmt->ToggleGet(gw, role) == pte->instance) {
194  if (pte->on) {
195  if (wvmt->ToggleOn)
196  wvmt->ToggleOn(gw, role);
197  } else {
198  if (wvmt->ToggleOff)
199  wvmt->ToggleOff(gw, role);
200  }
201  }
202  }
203  }
204  break;
205  #endif
206 
207  #if GFX_USE_GINPUT && GINPUT_NEED_DIAL
208  case GEVENT_DIAL:
209  // Cycle through all windows
210  for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
211 
212  // check if it a widget that is enabled and visible
213  if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED|GWIN_FLG_SYSVISIBLE))
214  continue;
215 
216  for(role = 0; role < wvmt->dialroles; role++) {
217  if (wvmt->DialGet(gw, role) == pte->instance) {
218  if (wvmt->DialMove)
219  wvmt->DialMove(gw, role, pde->value, pde->maxvalue);
220  }
221  }
222  }
223  break;
224  #endif
225 
226  default:
227  break;
228  }
229 
230  #undef pme
231  #undef pte
232  #undef pke
233  #undef pde
234 }
235 
236 #if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD
237  GHandle gwinGetFocus(void) {
238  return _widgetInFocus;
239  }
240 
241  gBool gwinSetFocus(GHandle gh) {
242  GHandle oldFocus;
243 
244  // Do we already have the focus?
245  if (gh == _widgetInFocus)
246  return gTrue;
247 
248  // The new window must be NULLL or a visible enabled widget with a keyboard handler
249  if (!gh || ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED|GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE)) == (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED|GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE)
250  && ((gwidgetVMT*)gh->vmt)->KeyboardEvent)) {
251  // Move the current focus
252  oldFocus = _widgetInFocus;
253  _widgetInFocus = gh;
254  if (oldFocus) _gwinUpdate(oldFocus);
255  if (gh) _gwinUpdate(gh);
256  return gTrue;
257  }
258  return gFalse;
259  }
260 
261  void _gwinMoveFocus(void) {
262  GHandle gh;
263  gBool looponce;
264 
265  // Find a new focus window (one may or may not exist).
266  looponce = gFalse;
267  for(gh = gwinGetNextWindow(_widgetInFocus); ; gh = gwinGetNextWindow(gh)) {
268  if (!gh && !looponce) {
269  looponce = gTrue;
270  gh = gwinGetNextWindow(0);
271  }
272  if (gwinSetFocus(gh))
273  break;
274  }
275  }
276 
277  void _gwinFixFocus(GHandle gh) {
278  GHandle oldFocus;
279 
280  if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED|GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE)) == (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED|GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE)
281  && ((gwidgetVMT*)gh->vmt)->KeyboardEvent) {
282 
283  // We are a candidate to be able to claim the focus
284 
285  // Claim the focus if no-one else has
286  if (!_widgetInFocus)
287  _widgetInFocus = gh;
288 
289  return;
290  }
291 
292  // We have lost any right to the focus
293 
294  // Did we have the focus
295  if (gh != _widgetInFocus)
296  return;
297 
298  // We did - we need to find a new focus window
299  oldFocus = _widgetInFocus;
300  for(gh = gwinGetNextWindow(oldFocus); gh && gh != oldFocus; gh = gwinGetNextWindow(gh)) {
301 
302  // Must be a visible enabled widget with a keyboard handler
303  if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED|GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE)) == (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED|GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE)
304  && ((gwidgetVMT*)gh->vmt)->KeyboardEvent) {
305 
306  // Grab the focus for the new window
307  _widgetInFocus = gh;
308 
309  // This new window still needs to be marked for redraw (but don't actually do it yet).
310  gh->flags |= GWIN_FLG_NEEDREDRAW;
311  // RedrawPending |= DOREDRAW_VISIBLES; - FIX LATER
312  return;
313  }
314  }
315 
316  // No-one has the right to the focus
317  _widgetInFocus = 0;
318  }
319 
320  void _gwidgetDrawFocusRect(GWidgetObject *gx, gCoord x, gCoord y, gCoord cx, gCoord cy) {
321  gCoord i;
322 
323  // Don't do anything if we don't have the focus
324  if (&gx->g != _widgetInFocus)
325  return;
326 
327  // Use the very simplest possible focus rectangle for now
328  for (i = 0; i < GWIN_FOCUS_HIGHLIGHT_WIDTH; i++) {
329  gdispGDrawBox(gx->g.display, gx->g.x+x+i, gx->g.y+y+i, cx-2*i, cy-2*i, gx->pstyle->focus);
330  }
331  }
332 
333  #if GDISP_NEED_CIRCLE
334  void _gwidgetDrawFocusCircle(GWidgetObject *gx, gCoord radius) {
335  gCoord i;
336 
337  // Don't do anything if we don't have the focus
338  if (&gx->g != _widgetInFocus)
339  return;
340 
341  for (i = 0; i < GWIN_FOCUS_HIGHLIGHT_WIDTH; i++) {
342  gdispGDrawCircle(gx->g.display, gx->g.x + radius, gx->g.y + radius, radius + i, gx->pstyle->focus);
343  }
344  }
345  #endif
346 #endif
347 
348 #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
349  static GHandle FindToggleUser(gU16 instance) {
350  GHandle gh;
351  gU16 role;
352 
353  for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
354  if (!(gh->flags & GWIN_FLG_WIDGET)) // check if it a widget
355  continue;
356 
357  for(role = 0; role < wvmt->toggleroles; role++) {
358  if (wvmt->ToggleGet(gw, role) == instance)
359  return gh;
360  }
361  }
362  return 0;
363  }
364 #endif
365 
366 #if GFX_USE_GINPUT && GINPUT_NEED_DIAL
367  static GHandle FindDialUser(gU16 instance) {
368  GHandle gh;
369  gU16 role;
370 
371  for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
372  if (!(gh->flags & GWIN_FLG_WIDGET)) // check if it a widget
373  continue;
374 
375  for(role = 0; role < wvmt->dialroles; role++) {
376  if (wvmt->DialGet(gw, role) == instance)
377  return gh;
378  }
379  }
380  return 0;
381  }
382 #endif
383 
384 void _gwidgetInit(void)
385 {
386  geventListenerInit(&gl);
387  geventRegisterCallback(&gl, gwidgetEvent, 0);
388  #if GINPUT_NEED_MOUSE
389  geventAttachSource(&gl, ginputGetMouse(GMOUSE_ALL_INSTANCES), GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES);
390  #endif
391  #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
392  geventAttachSource(&gl, ginputGetKeyboard(GKEYBOARD_ALL_INSTANCES), GLISTEN_KEYUP);
393  #endif
394 }
395 
396 void _gwidgetDeinit(void)
397 {
398  /* ToDo */
399 }
400 
401 GHandle _gwidgetCreate(GDisplay *g, GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt) {
402  if (!(pgw = (GWidgetObject *)_gwindowCreate(g, &pgw->g, &pInit->g, &vmt->g, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED)))
403  return 0;
404 
405  #if GWIN_NEED_CONTAINERS
406  // This window can't be system enabled if the parent is not enabled
407  if (pgw->g.parent && !(pgw->g.parent->flags & GWIN_FLG_SYSENABLED))
408  pgw->g.flags &= ~GWIN_FLG_SYSENABLED;
409  #endif
410  pgw->text = pInit->text ? pInit->text : "";
411  pgw->fnDraw = pInit->customDraw ? pInit->customDraw : vmt->DefaultDraw;
412  pgw->fnParam = pInit->customParam;
413  pgw->pstyle = pInit->customStyle ? pInit->customStyle : defaultStyle;
414  #if GWIN_WIDGET_TAGS
415  pgw->tag = pInit->tag;
416  #endif
417 
418  return &pgw->g;
419 }
420 
421 void _gwidgetDestroy(GHandle gh) {
422  #if GFX_USE_GINPUT && (GINPUT_NEED_TOGGLE || GINPUT_NEED_DIAL)
423  gU16 role, instance;
424  #endif
425 
426  // Make the window is invisible so it is not eligible for focus
427  gh->flags &= ~GWIN_FLG_VISIBLE;
428  _gwinFixFocus(gh);
429 
430  // Deallocate the text (if necessary)
431  if ((gh->flags & GWIN_FLG_ALLOCTXT)) {
432  gh->flags &= ~GWIN_FLG_ALLOCTXT;
433  gfxFree((void *)gw->text);
434  }
435 
436  #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
437  // Detach any toggles from this object
438  for(role = 0; role < wvmt->toggleroles; role++) {
439  instance = wvmt->ToggleGet(gw, role);
440  if (instance != GWIDGET_NO_INSTANCE) {
441  wvmt->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE);
442  if (!FindToggleUser(instance))
443  geventDetachSource(&gl, ginputGetToggle(instance));
444  }
445  }
446  #endif
447 
448  #if GFX_USE_GINPUT && GINPUT_NEED_DIAL
449  // Detach any dials from this object
450  for(role = 0; role < wvmt->dialroles; role++) {
451  instance = wvmt->DialGet(gw, role);
452  if (instance != GWIDGET_NO_INSTANCE) {
453  wvmt->DialAssign(gw, role, GWIDGET_NO_INSTANCE);
454  if (!FindDialUser(instance))
455  geventDetachSource(&gl, ginputGetDial(instance));
456  }
457  }
458  #endif
459 
460  // Remove any listeners on this object.
461  geventDetachSourceListeners((GSourceHandle)gh);
462 }
463 
464 void _gwidgetRedraw(GHandle gh) {
465  if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
466  return;
467 
468  gw->fnDraw(gw, gw->fnParam);
469 }
470 
471 void _gwinSendEvent(GHandle gh, GEventType type) {
472  GSourceListener * psl;
473  GEventGWin * pge;
474 
475  // Trigger a GWIN Event
476  psl = 0;
477  while ((psl = geventGetSourceListener(GWIDGET_SOURCE, psl))) {
478  if (!(pge = (GEventGWin *)geventGetEventBuffer(psl)))
479  continue;
480  pge->type = type;
481  pge->gwin = gh;
482  #if GWIN_WIDGET_TAGS
483  pge->tag = (gh->flags & GWIN_FLG_WIDGET) ? ((GWidgetObject *)gh)->tag : 0;
484  #endif
485  geventSendEvent(psl);
486  }
487 }
488 
489 void gwinWidgetClearInit(GWidgetInit *pwi) {
490  char *p;
491  unsigned len;
492 
493  for(p = (char *)pwi, len = sizeof(GWidgetInit); len; len--)
494  *p++ = 0;
495 }
496 
497 void gwinSetDefaultStyle(const GWidgetStyle *pstyle, gBool updateAll) {
498  if (!pstyle)
499  pstyle = &BlackWidgetStyle;
500 
501  if (updateAll) {
502  GHandle gh;
503 
504  for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
505  if ((gh->flags & GWIN_FLG_WIDGET) && ((GWidgetObject *)gh)->pstyle == defaultStyle)
506  gwinSetStyle(gh, pstyle);
507  else
508  gwinRedraw(gh);
509  }
510  }
512  defaultStyle = pstyle;
513 }
514 
515 /**
516  * @brief Get the current default style.
517  *
518  * @api
519  */
520 const GWidgetStyle *gwinGetDefaultStyle(void) {
521  return defaultStyle;
522 }
523 
524 void gwinSetText(GHandle gh, const char *text, gBool useAlloc) {
525  if (!(gh->flags & GWIN_FLG_WIDGET))
526  return;
527 
528  // Dispose of the old string
529  if ((gh->flags & GWIN_FLG_ALLOCTXT)) {
530  gh->flags &= ~GWIN_FLG_ALLOCTXT;
531  if (gw->text) {
532  gfxFree((void *)gw->text);
533  gw->text = "";
534  }
535  }
536 
537  // Alloc the new text if required
538  if (!text || !*text)
539  gw->text = "";
540  else if (useAlloc) {
541  char *str;
542 
543  if ((str = gfxAlloc(strlen(text)+1))) {
544  gh->flags |= GWIN_FLG_ALLOCTXT;
545  strcpy(str, text);
546  }
547  gw->text = (const char *)str;
548  } else
549  gw->text = text;
550  _gwinUpdate(gh);
551 }
552 
553 #if GFX_USE_GFILE && GFILE_NEED_PRINTG && GFILE_NEED_STRINGS
554  #include <stdarg.h>
555 
556  void gwinPrintg(GHandle gh, const char * fmt, ...) {
557  char *str;
558  va_list va;
559  int size;
560 
561  if (!(gh->flags & GWIN_FLG_WIDGET))
562  return;
563 
564  // Dispose of the old string
565  if ((gh->flags & GWIN_FLG_ALLOCTXT)) {
566  gh->flags &= ~GWIN_FLG_ALLOCTXT;
567  if (gw->text) {
568  gfxFree((void *)gw->text);
569  gw->text = "";
570  }
571  }
572 
573  // Alloc the new text
574  va_start (va, fmt);
575 
576  size = vsnprintg(0, 0, fmt, va) + 1; //determine the buffer size required
577 
578  if ((str = gfxAlloc(size))) {
579  gh->flags |= GWIN_FLG_ALLOCTXT;
580  vsnprintg(str, size, fmt, va);
581  gw->text = (const char *)str;
582  } else
583  gw->text = "";
584 
585  va_end (va);
586 
587  _gwinUpdate(gh);
588  }
589 #endif
590 
591 const char *gwinGetText(GHandle gh) {
592  if (!(gh->flags & GWIN_FLG_WIDGET))
593  return 0;
594 
595  return gw->text;
596 }
597 
598 gBool gwinIsWidget(GHandle gh) {
599  if (gh->flags & GWIN_FLG_WIDGET) {
600  return gTrue;
601  }
602 
603  return gFalse;
604 }
605 
606 void gwinSetStyle(GHandle gh, const GWidgetStyle *pstyle) {
607  if (!(gh->flags & GWIN_FLG_WIDGET))
608  return;
609 
610  gw->pstyle = pstyle ? pstyle : defaultStyle;
611  gh->bgcolor = gw->pstyle->background;
612  gh->color = gw->pstyle->enabled.text;
613 
614  _gwinUpdate(gh);
615 }
616 
617 const GWidgetStyle *gwinGetStyle(GHandle gh) {
618  if (!(gh->flags & GWIN_FLG_WIDGET))
619  return 0;
620 
621  return gw->pstyle;
622 }
623 
624 void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) {
625  if (!(gh->flags & GWIN_FLG_WIDGET))
626  return;
627 
628  gw->fnDraw = fn ? fn : wvmt->DefaultDraw;
629  gw->fnParam = param;
630  _gwinUpdate(gh);
631 }
632 
633 gBool gwinAttachListener(GListener *pl) {
634  return geventAttachSource(pl, GWIDGET_SOURCE, 0);
635 }
636 
637 #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
638  gBool DEPRECATED("This call can now be removed. Attaching the mouse to GWIN is now automatic.") gwinAttachMouse(gU16 instance) {
639  // This is now a NULL event because we automatically attach to all mice in the system.
640  (void) instance;
641  return gTrue;
642  }
643 #endif
644 
645 #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
646  gBool gwinAttachToggle(GHandle gh, gU16 role, gU16 instance) {
647  GSourceHandle gsh;
648  gU16 oi;
649 
650  // Is this a widget
651  if (!(gh->flags & GWIN_FLG_WIDGET))
652  return gFalse;
653 
654  // Is the role valid
655  if (role >= wvmt->toggleroles)
656  return gFalse;
657 
658  // Is this a valid device
659  if (!(gsh = ginputGetToggle(instance)))
660  return gFalse;
661 
662  // Is this already done?
663  oi = wvmt->ToggleGet(gw, role);
664  if (instance == oi)
665  return gTrue;
666 
667  // Remove the old instance
668  if (oi != GWIDGET_NO_INSTANCE) {
669  wvmt->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE);
670  if (!FindToggleUser(oi))
672  }
673 
674  // Assign the new
675  wvmt->ToggleAssign(gw, role, instance);
676  return geventAttachSource(&gl, gsh, GLISTEN_TOGGLE_ON|GLISTEN_TOGGLE_OFF);
677  }
678 
679  gBool gwinDetachToggle(GHandle gh, gU16 role) {
680  gU16 oi;
681 
682  // Is this a widget
683  if (!(gh->flags & GWIN_FLG_WIDGET))
684  return gFalse;
685 
686  // Is the role valid
687  if (role >= ((gwidgetVMT *)gh->vmt)->toggleroles)
688  return gFalse;
689 
690  oi = ((gwidgetVMT *)gh->vmt)->ToggleGet(gw, role);
691 
692  // Remove the instance
693  if (oi != GWIDGET_NO_INSTANCE) {
694  ((gwidgetVMT *)gh->vmt)->ToggleAssign(gw, role, GWIDGET_NO_INSTANCE);
695  if (!FindToggleUser(oi))
697  }
698  return gTrue;
699  }
700 
701 #endif
702 
703 #if GFX_USE_GINPUT && GINPUT_NEED_DIAL
704  gBool gwinAttachDial(GHandle gh, gU16 role, gU16 instance) {
705  GSourceHandle gsh;
706  gU16 oi;
707 
708  if (!(gh->flags & GWIN_FLG_WIDGET))
709  return gFalse;
710 
711  // Is the role valid
712  if (role >= wvmt->dialroles)
713  return gFalse;
714 
715  // Is this a valid device
716  if (!(gsh = ginputGetDial(instance)))
717  return gFalse;
718 
719  // Is this already done?
720  oi = wvmt->DialGet(gw, role);
721  if (instance == oi)
722  return gTrue;
723 
724  // Remove the old instance
725  if (oi != GWIDGET_NO_INSTANCE) {
726  wvmt->DialAssign(gw, role, GWIDGET_NO_INSTANCE);
727  if (!FindDialUser(oi))
729  }
730 
731  // Assign the new
732  wvmt->DialAssign(gw, role, instance);
733  return geventAttachSource(&gl, gsh, 0);
734  }
735 #endif
736 
737 #if GWIN_WIDGET_TAGS
738  void gwinSetTag(GHandle gh, WidgetTag tag) {
739  if ((gh->flags & GWIN_FLG_WIDGET))
740  gw->tag = tag;
741  }
742 
744  return ((gh->flags & GWIN_FLG_WIDGET)) ? gw->tag : 0;
745  }
746 #endif
747 
748 #undef gw
749 #undef wvmt
750 
751 #endif /* GFX_USE_GWIN && GWIN_NEED_WIDGET */
#define HTML2COLOR(h)
Convert a 6 digit HTML code (hex) into a color value.
Definition: gdisp_colors.h:201
GSourceHandle ginputGetDial(gU16 instance)
Create a dial input instance.
void gdispGDrawCircle(GDisplay *g, gCoord x, gCoord y, gCoord radius, gColor color)
Draw a circle.
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.
void geventListenerInit(GListener *pl)
Create a Listener.
Definition: gevent.c:64
GEvent * geventGetEventBuffer(GSourceListener *psl)
Get the event buffer from the GSourceListener.
Definition: gevent.c:187
void geventDetachSource(GListener *pl, GSourceHandle gsh)
Detach a source from a listener.
Definition: gevent.c:108
void geventSendEvent(GSourceListener *psl)
Called by a source to indicate the listener's event buffer has been filled.
Definition: gevent.c:200
gBool geventAttachSource(GListener *pl, GSourceHandle gsh, gU32 flags)
Attach a source to a listener.
Definition: gevent.c:71
GSourceListener * geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr)
Called by a source with a possible event to get a listener record.
Definition: gevent.c:163
void geventDetachSourceListeners(GSourceHandle gsh)
Detach any listener that has this source attached.
Definition: gevent.c:220
#define DEPRECATED(msg)
Mark a function as deprecated.
void * gfxAlloc(gMemSize sz)
Allocate memory.
void gfxFree(void *ptr)
Free memory.
#define GWIN_FOCUS_HIGHLIGHT_WIDTH
The width of the rectangle that highlights a widget that is focused.
Definition: gwin_options.h:52
GSourceHandle ginputGetKeyboard(unsigned instance)
Create a keyboard input instance.
GSourceHandle ginputGetMouse(unsigned instance)
Get the Source handler for a mouse using the instance number.
GSourceHandle ginputGetToggle(gU16 instance)
Create a toggle input instance.
Definition: ginput_toggle.c:95
gBool gwinDetachToggle(GHandle gh, gU16 role)
Detach a toggle from a widget.
void gwinSetText(GHandle gh, const char *text, gBool useAlloc)
Set the text of a widget.
const char * gwinGetText(GHandle gh)
Get the text of a widget.
void(* CustomWidgetDrawFunction)(struct GWidgetObject *gw, void *param)
Defines a custom drawing function for a widget.
Definition: gwin_widget.h:76
const GWidgetStyle * gwinGetStyle(GHandle gh)
Get the style of a widget.
gBool gwinAttachToggle(GHandle gh, gU16 role, gU16 instance)
Attach a toggle to a widget.
gBool gwinAttachListener(GListener *pl)
Attach a Listener to listen for widget events.
void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param)
Set the routine to perform a custom widget drawing.
void gwinPrintg(GHandle gh, const char *fmt,...)
Set the text of a widget using a printf style format.
void gwinSetStyle(GHandle gh, const GWidgetStyle *pstyle)
Set the style of a widget.
const GWidgetStyle * gwinGetDefaultStyle(void)
Get the current default style.
gBool gwinIsWidget(GHandle gh)
Check whether a handles is a widget handle or not.
GHandle gwinGetFocus(void)
Get the widget that is currently in focus.
gU16 WidgetTag
Defines a the type of a tag on a widget.
Definition: gwin_widget.h:81
gBool gwinAttachDial(GHandle gh, gU16 role, gU16 instance)
Attach a toggle to a widget.
void gwinWidgetClearInit(GWidgetInit *pwi)
Clear a GWidgetInit structure to all zero's.
gBool gwinSetFocus(GHandle gh)
Set the keyboard focus to a specific window.
void gwinSetDefaultStyle(const GWidgetStyle *pstyle, gBool updateAll)
Set the default style for widgets created hereafter.
const GWidgetStyle BlackWidgetStyle
We define a couple of GWidgetStyle's that you can use in your application. The Black style is the def...
void gwinSetTag(GHandle gh, WidgetTag tag)
Set the tag of a widget.
WidgetTag gwinGetTag(GHandle gh)
Get the tag of a widget.
void gwinRedraw(GHandle gh)
Redraw a window.
GHandle gwinGetNextWindow(GHandle gh)
Get the next window in the z-order.
void gwinSetDefaultBgColor(gColor bgclr)
Set the default background color for all new GWIN windows.
A Generic GWIN Event.
Definition: gwin_widget.h:149
GEventType type
Definition: gwin_widget.h:150
GHandle gwin
Definition: gwin_widget.h:151
The structure to initialise a widget.
Definition: gwin_widget.h:97
GWindowInit g
Definition: gwin_widget.h:98
WidgetTag tag
Definition: gwin_widget.h:104
const char * text
Definition: gwin_widget.h:99
CustomWidgetDrawFunction customDraw
Definition: gwin_widget.h:100
void * customParam
Definition: gwin_widget.h:101
const GWidgetStyle * customStyle
Definition: gwin_widget.h:102
The GWIN Widget structure.
Definition: gwin_widget.h:118
GWindowObject g
Definition: gwin_widget.h:119
CustomWidgetDrawFunction fnDraw
Definition: gwin_widget.h:121
void * fnParam
Definition: gwin_widget.h:122
const GWidgetStyle * pstyle
Definition: gwin_widget.h:123
WidgetTag tag
Definition: gwin_widget.h:125
const char * text
Definition: gwin_widget.h:120
The GWidgetStyle structure.
Definition: gwin_widget.h:52
gColor background
Definition: gwin_widget.h:53
gColor focus
Definition: gwin_widget.h:54
A window object structure.
Definition: gwin.h:40
gColor bgcolor
Definition: gwin.h:52
GDisplay * display
Definition: gwin.h:46
gCoord x
Definition: gwin.h:47
gColor color
Definition: gwin.h:51
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
void(* DefaultDraw)(GWidgetObject *gw, void *param)
Definition: gwin_class.h:87
struct gwinVMT g
Definition: gwin_class.h:86