µGFX  2.9
version 2.9
gwin_class.h
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_class.h
10  * @brief GWIN Graphic window subsystem header file.
11  *
12  * @defgroup Internal Internal
13  * @ingroup GWIN
14  *
15  * @note These definitions are normally not used by an application program. They are useful
16  * only if you want to create your own custom GWIN window or widget.
17  * @note To access these definitions you must include "src/gwin/gwin_class.h" in your source file.
18  *
19  * @{
20  */
21 #ifndef _CLASS_GWIN_H
22 #define _CLASS_GWIN_H
23 
24 #if GFX_USE_GWIN || defined(__DOXYGEN__)
25 
26 /**
27  * @brief The predefined flags for a Window
28  * @{
29  */
30 #define GWIN_FIRST_CONTROL_FLAG 0x00000001 /**< 8 bits free for the control to use. Don't change this value as it is relied upon definitions in widget header files. */
31 #define GWIN_LAST_CONTROL_FLAG 0x00000080 /**< 8 bits free for the control to use */
32 #define GWIN_FLG_VISIBLE 0x00000100 /**< The window is "visible" */
33 #define GWIN_FLG_SYSVISIBLE 0x00000200 /**< The window is visible after parents are tested */
34 #define GWIN_FLG_ENABLED 0x00000400 /**< The window is "enabled" */
35 #define GWIN_FLG_SYSENABLED 0x00000800 /**< The window is enabled after parents are tested */
36 #define GWIN_FLG_DYNAMIC 0x00001000 /**< The GWIN structure is allocated */
37 #define GWIN_FLG_ALLOCTXT 0x00002000 /**< The text/label is allocated */
38 #define GWIN_FLG_NEEDREDRAW 0x00004000 /**< Redraw is needed but has been delayed */
39 #define GWIN_FLG_BGREDRAW 0x00008000 /**< On redraw, if not visible redraw the revealed under-side */
40 #define GWIN_FLG_SUPERMASK 0x000F0000 /**< The bit mask to leave just the window superclass type */
41 #define GWIN_FLG_WIDGET 0x00010000 /**< This is a widget */
42 #define GWIN_FLG_CONTAINER 0x00020000 /**< This is a container */
43 #define GWIN_FLG_MINIMIZED 0x00100000 /**< The window is minimized */
44 #define GWIN_FLG_MAXIMIZED 0x00200000 /**< The window is maximized */
45 #define GWIN_FLG_MOUSECAPTURE 0x00400000 /**< The window has captured the mouse */
46 #define GWIN_FLG_FLASHING 0x00800000 /**< The window is flashing - see the _gwinFlashState boolean */
47 #define GWIN_FIRST_WM_FLAG 0x01000000 /**< 8 bits free for the window manager to use */
48 #define GWIN_LAST_WM_FLAG 0x80000000 /**< 8 bits free for the window manager to use */
49 /** @} */
50 
51 /**
52  * @brief The Virtual Method Table for a GWIN window
53  * @{
54  */
55 typedef struct gwinVMT {
56  const char * classname; /**< The GWIN classname (mandatory) */
57  gMemSize size; /**< The size of the class object */
58  void (*Destroy) (GWindowObject *gh); /**< The GWIN destroy function (optional) */
59  void (*Redraw) (GWindowObject *gh); /**< The GWIN redraw routine (optional) */
60  void (*AfterClear) (GWindowObject *gh); /**< The GWIN after-clear function (optional) */
61 } gwinVMT;
62 /** @} */
63 
64 #if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
65 
66  /**
67  * @brief An toggle/dial instance is not being used
68  */
69  #define GWIDGET_NO_INSTANCE ((gU16)-1)
70 
71  /**
72  * @brief The source handle that widgets use when sending events
73  */
74  #define GWIDGET_SOURCE ((GSourceHandle)(void *)_gwidgetCreate)
75 
76  /**
77  * @brief The Virtual Method Table for a widget
78  * @note A widget must have a destroy function. Either use @p _gwidgetDestroy() or use your own function
79  * which internally calls @p _gwidgetDestroy().
80  * @note A widget must have a redraw function. Use @p _gwidgetRedraw().
81  * @note If toggleroles != 0, ToggleAssign(), ToggleGet() and one or both of ToggleOff() and ToggleOn() must be specified.
82  * @note If dialroles != 0, DialAssign(), DialGet() and DialMove() must be specified.
83  * @{
84  */
85  typedef struct gwidgetVMT {
86  struct gwinVMT g; /**< This is still a GWIN */
87  void (*DefaultDraw) (GWidgetObject *gw, void *param); /**< The default drawing routine (mandatory) */
88  #if GINPUT_NEED_MOUSE
89  struct {
90  void (*MouseDown) (GWidgetObject *gw, gCoord x, gCoord y); /**< Process mouse down events (optional) */
91  void (*MouseUp) (GWidgetObject *gw, gCoord x, gCoord y); /**< Process mouse up events (optional) */
92  void (*MouseMove) (GWidgetObject *gw, gCoord x, gCoord y); /**< Process mouse move events (optional) */
93  };
94  #endif
95  #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
96  struct {
97  void (*KeyboardEvent) (GWidgetObject *gw, GEventKeyboard *pke); /**< Process keyboard events (optional) */
98  };
99  #endif
100  #if GINPUT_NEED_TOGGLE
101  struct {
102  gU16 toggleroles; /**< The roles supported for toggles (0->toggleroles-1) */
103  void (*ToggleAssign) (GWidgetObject *gw, gU16 role, gU16 instance); /**< Assign a toggle to a role (optional) */
104  gU16 (*ToggleGet) (GWidgetObject *gw, gU16 role); /**< Return the instance for a particular role (optional) */
105  void (*ToggleOff) (GWidgetObject *gw, gU16 role); /**< Process toggle off events (optional) */
106  void (*ToggleOn) (GWidgetObject *gw, gU16 role); /**< Process toggle on events (optional) */
107  };
108  #endif
109  #if GINPUT_NEED_DIAL
110  struct {
111  gU16 dialroles; /**< The roles supported for dials (0->dialroles-1) */
112  void (*DialAssign) (GWidgetObject *gw, gU16 role, gU16 instance); /**< Test the role and save the dial instance handle (optional) */
113  gU16 (*DialGet) (GWidgetObject *gw, gU16 role); /**< Return the instance for a particular role (optional) */
114  void (*DialMove) (GWidgetObject *gw, gU16 role, gU16 value, gU16 max); /**< Process dial move events (optional) */
115  };
116  #endif
117  } gwidgetVMT;
118  /** @} */
119 #endif
120 
121 #if GWIN_NEED_CONTAINERS || defined(__DOXYGEN__)
122 
123  /**
124  * @brief The Virtual Method Table for a container
125  * @note A container must have a destroy function. Either use @p _gcontainerDestroy() or use your own function
126  * which internally calls @p _gcontainerDestroy().
127  * @note A container must have a gwin redraw function. Use @p _containerRedraw().
128  * @note If toggleroles != 0, ToggleAssign(), ToggleGet() and one or both of ToggleOff() and ToggleOn() must be specified.
129  * @note If dialroles != 0, DialAssign(), DialGet() and DialMove() must be specified.
130  * @{
131  */
132  typedef struct gcontainerVMT {
133  gwidgetVMT gw;
134  gCoord (*LeftBorder) (GHandle gh); /**< The size of the left border (mandatory) */
135  gCoord (*TopBorder) (GHandle gh); /**< The size of the top border (mandatory) */
136  gCoord (*RightBorder) (GHandle gh); /**< The size of the right border (mandatory) */
137  gCoord (*BottomBorder) (GHandle gh); /**< The size of the bottom border (mandatory) */
138  void (*NotifyAdd) (GHandle gh, GHandle ghChild); /**< Notification that a child has been added (optional) */
139  void (*NotifyDelete) (GHandle gh, GHandle ghChild); /**< Notification that a child has been deleted (optional) */
140  } gcontainerVMT;
141  /** @} */
142 #endif
143 
144 #if GWIN_NEED_WINDOWMANAGER || defined(__DOXYGEN__)
145  // @note There is only ever one instance of each GWindowManager type
146  typedef struct GWindowManager {
147  const struct gwmVMT *vmt;
148  } GWindowManager;
149 
150  /**
151  * @brief The Virtual Method Table for a window manager
152  * @{
153  */
154  typedef struct gwmVMT {
155  void (*Init) (void); /**< The window manager has just been set as the current window manager */
156  void (*DeInit) (void); /**< The window manager has just been removed as the current window manager */
157  gBool (*Add) (GHandle gh, const GWindowInit *pInit); /**< A window has been added */
158  void (*Delete) (GHandle gh); /**< A window has been deleted */
159  void (*Redraw) (GHandle gh); /**< A window needs to be redraw (or undrawn) */
160  void (*Size) (GHandle gh, gCoord w, gCoord h); /**< A window wants to be resized */
161  void (*Move) (GHandle gh, gCoord x, gCoord y); /**< A window wants to be moved */
162  void (*Raise) (GHandle gh); /**< A window wants to be on top */
163  void (*MinMax) (GHandle gh, GWindowMinMax minmax); /**< A window wants to be minimized/maximised */
164  } gwmVMT;
165  /** @} */
166 
167  /**
168  * @brief The current window manager
169  */
170  extern GWindowManager *_GWINwm;
171  extern gBool _gwinFlashState;
172 
173 #endif
174 
175 /**
176  * @brief Initialise (and allocate if necessary) the base GWIN object
177  *
178  * @param[in] g The GDisplay to use for this window
179  * @param[in] pgw The GWindowObject structure. If NULL one is allocated from the heap
180  * @param[in] pInit The user initialization parameters
181  * @param[in] vmt The virtual method table for the GWIN object
182  * @param[in] flags The default flags to use
183  *
184  * @return The GHandle of the created window
185  *
186  * @notapi
187  */
188 GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, gU32 flags);
189 
190 /**
191  * @brief Redraw the window after a status change.
192  *
193  * @param[in] gh The widget to redraw
194  *
195  * @note Mark a window for redraw.
196  * @note The window will get redrawn at some later time.
197  * @note This call is designed to be fast and non-blocking
198  *
199  * @notapi
200  */
201 void _gwinUpdate(GHandle gh);
202 
203 /**
204  * @brief How to flush the redraws
205  * @notes REDRAW_WAIT - Wait for a drawing session to be available
206  * @notes REDRAW_NOWAIT - Do nothing if the drawing session is not available
207  * @note REDRAW_INSESSION - We are already in a drawing session
208  */
209 typedef enum GRedrawMethod { REDRAW_WAIT, REDRAW_NOWAIT, REDRAW_INSESSION } GRedrawMethod;
210 
211 /**
212  * @brief Flush any pending redraws in the system.
213  *
214  * @param[in] how Do we wait for the lock?
215  *
216  * @note This call will attempt to flush any pending redraws
217  * in the system. The doWait parameter tells this call
218  * how to handle someone already holding the drawing lock.
219  * If doWait is gTrue it waits to obtain the lock. If gFalse
220  * and the drawing lock is free then the redraw is done
221  * immediately. If the drawing lock was taken it will postpone the flush
222  * on the basis that someone else will do it for us later.
223  *
224  * @notapi
225  */
226 void _gwinFlushRedraws(GRedrawMethod how);
227 
228 /**
229  * @brief Obtain a drawing session
230  * @return gTrue if the drawing session was obtained, gFalse if the window is not visible
231  *
232  * @param[in] gh The window
233  *
234  * @note This function blocks until a drawing session is available if the window is visible
235  */
236 gBool _gwinDrawStart(GHandle gh);
237 
238 /**
239  * @brief Release a drawing session
240  *
241  * @param[in] gh The window
242  */
243 void _gwinDrawEnd(GHandle gh);
244 
245 /**
246  * @brief Destroy a window.
247  *
248  * @param[in] gh The window
249  * @param[in] how Do we wait for the lock?
250  *
251  * @note If called without the drawing lock 'how' must be REDRAW_WAIT.
252  * If called with the drawing lock 'how' must be REDRAW_INSESSION.
253  *
254  * @notapi
255  */
256 void _gwinDestroy(GHandle gh, GRedrawMethod how);
257 
258 /**
259  * @brief Add a window to the window manager and set its position and size
260  * @return gTrue if successful
261  *
262  * @param[in] gh The window
263  * @param[in] pInit The window init structure
264  */
265 gBool _gwinWMAdd(GHandle gh, const GWindowInit *pInit);
266 
267 #if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
268  /**
269  * @brief Initialise (and allocate if necessary) the base Widget object
270  *
271  * @param[in] g The GDisplay to display this window on
272  * @param[in] pgw The GWidgetObject structure. If NULL one is allocated from the heap
273  * @param[in] pInit The user initialization parameters
274  * @param[in] vmt The virtual method table for the Widget object
275  *
276  * @return The GHandle of the created widget
277  *
278  * @notapi
279  */
280  GHandle _gwidgetCreate(GDisplay *g, GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt);
281 
282  /**
283  * @brief Destroy the Widget object
284  *
285  * @param[in] gh The widget to destroy
286  *
287  * @notapi
288  */
289  void _gwidgetDestroy(GHandle gh);
290 
291  /**
292  * @brief Redraw the Widget object (VMT method only)
293  *
294  * @param[in] gh The widget to redraw
295  *
296  * @note Do not use this routine to update a widget after a status change.
297  * Use @p _gwinUpdate() instead. This routine should only be used in the
298  * VMT.
299  *
300  * @notapi
301  */
302  void _gwidgetRedraw(GHandle gh);
303 
304  /**
305  * @brief Send a standard GWIN event.
306  *
307  * @param[in] gh The window
308  * @param[in] type The event type
309  *
310  * @note No consideration is given to recording EVENT LOST statuses.
311  *
312  * @notapi
313  */
314  void _gwinSendEvent(GHandle gh, GEventType type);
315 
316  #if (GFX_USE_GINPUT && GINPUT_NEED_KEYBOARD) || GWIN_NEED_KEYBOARD || defined(__DOXYGEN__)
317  /**
318  * @brief Move the focus off the current focus window.
319  *
320  * @note The focus can stay on the same window if there is no other focusable window
321  *
322  * @notapi
323  */
324  void _gwinMoveFocus(void);
325 
326  /**
327  * @brief Do focus fixup's after a change of state for a window.
328  * @details If a focus window has become invisible or disabled then
329  * the focus must be taken away from it. If there is no focus
330  * window and this window is eligible then this window becomes
331  * the focus.
332  *
333  * @param[in] gh The window
334  *
335  * @note This routine does not actually do a redraw. It assumes that surrounding code
336  * will because of the change of state that lead to this being called.
337  *
338  * @notapi
339  */
340  void _gwinFixFocus(GHandle gh);
341 
342  /**
343  * @brief Draw a simple focus rectangle in the default style.
344  *
345  * @param[in] gw The widget
346  * @param[in] x, y The start x, y position (relative to the window)
347  * @param[in] cx, cy The width & height of the rectangle
348  *
349  * @note Assumes the widget is in a state where it can draw.
350  * @note Nothing is drawn if the window doesn't have focus.
351  * @note The focus rectangle may be more than one pixel thick and may
352  * not be a continuous line.
353  *
354  * @notapi
355  */
356  void _gwidgetDrawFocusRect(GWidgetObject *gw, gCoord x, gCoord y, gCoord cx, gCoord cy);
357 
358  /**
359  * @brief Draw a simple focus circle in the default style.
360  *
361  * @param[in] gw The widget
362  * @param[in] radius The radius of the circle
363  *
364  * @note Assumes the widget is in a state where it can draw.
365  * @note Nothing is drawn if the window doesn't have focus.
366  * @note The focus circle may be more than one pixel thick.
367  *
368  * @notapi
369  */
370  #if GDISP_NEED_CIRCLE
371  void _gwidgetDrawFocusCircle(GWidgetObject *gx, gCoord radius);
372  #endif
373 
374  #else
375  #define _gwinFixFocus(gh)
376  #define _gwidgetDrawFocusRect(gh,x,y,cx,cy)
377  #define _gwidgetDrawFocusCircle(gh,radius)
378  #endif
379 
380  #if GWIN_NEED_FLASHING || defined(__DOXYGEN__)
381  /**
382  * @brief Convert a chosen style color set pressed/enabled etc if flashing
383  * @return The colorset - after flashing is taken into account
384  *
385  * @param[in] gw The widget
386  * @param[in] pcol The style color set that has been chosen to reflect the state of the widget
387  * @param[in] flashOffState Whether the off-state should be flashed as well. If false, only the
388  * pressed color set is flashed.
389  */
390  const GColorSet *_gwinGetFlashedColor(GWidgetObject *gw, const GColorSet *pcol, gBool flashOffState);
391  #endif
392 #else
393  #define _gwinFixFocus(gh)
394 #endif
395 
396 #if GWIN_NEED_CONTAINERS || defined(__DOXYGEN__)
397  /**
398  * @brief Initialise (and allocate if necessary) the base Container object
399  *
400  * @param[in] g The GDisplay to display this window on
401  * @param[in] pgw The GContainerObject structure. If NULL one is allocated from the heap
402  * @param[in] pInit The user initialization parameters
403  * @param[in] vmt The virtual method table for the Container object
404  *
405  * @return The GHandle of the created widget
406  *
407  * @notapi
408  */
409  GHandle _gcontainerCreate(GDisplay *g, GContainerObject *pgw, const GWidgetInit *pInit, const gcontainerVMT *vmt);
410 
411  /**
412  * @brief Destroy the Container object
413  *
414  * @param[in] gh The container to destroy
415  *
416  * @notapi
417  */
418  void _gcontainerDestroy(GHandle gh);
419 
420  /**
421  * @brief Redraw the Container object (VMT method only)
422  *
423  * @param[in] gh The container to redraw
424  *
425  * @note Do not use this routine to update a container after a status change.
426  * Use @p _gwinUpdate() instead. This routine should only be used in the
427  * VMT.
428  *
429  * @notapi
430  */
431  #define _gcontainerRedraw _gwidgetRedraw
432 
433  /**
434  * @brief The visibility of something has changed. Ripple the changes.
435  *
436  * @note Does not actually trigger the redraw. It just marks as ready for redraw any
437  * visibility changes.
438  *
439  * @notapi
440  */
441  void _gwinRippleVisibility(void);
442 
443 #endif
444 
445 #endif /* GFX_USE_GWIN */
446 
447 #endif /* _CLASS_GWIN_H */
gI16 gCoord
The type for a coordinate or length on the screen.
Definition: gdisp.h:39
GWindowMinMax
A window's minimized, maximized or normal size.
Definition: gwin.h:90
The GColorSet structure.
Definition: gwin_widget.h:37
The structure to initialise a widget.
Definition: gwin_widget.h:97
The GWIN Widget structure.
Definition: gwin_widget.h:118
The structure to initialise a GWIN.
Definition: gwin.h:75
A window object structure.
Definition: gwin.h:40
The Virtual Method Table for a container.
Definition: gwin_class.h:132
void(* NotifyAdd)(GHandle gh, GHandle ghChild)
Definition: gwin_class.h:138
gCoord(* LeftBorder)(GHandle gh)
Definition: gwin_class.h:134
gCoord(* RightBorder)(GHandle gh)
Definition: gwin_class.h:136
gCoord(* TopBorder)(GHandle gh)
Definition: gwin_class.h:135
void(* NotifyDelete)(GHandle gh, GHandle ghChild)
Definition: gwin_class.h:139
gCoord(* BottomBorder)(GHandle gh)
Definition: gwin_class.h:137
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
The Virtual Method Table for a GWIN window.
Definition: gwin_class.h:55
gMemSize size
Definition: gwin_class.h:57
void(* AfterClear)(GWindowObject *gh)
Definition: gwin_class.h:60
void(* Redraw)(GWindowObject *gh)
Definition: gwin_class.h:59
const char * classname
Definition: gwin_class.h:56
void(* Destroy)(GWindowObject *gh)
Definition: gwin_class.h:58
The Virtual Method Table for a window manager.
Definition: gwin_class.h:154
void(* DeInit)(void)
Definition: gwin_class.h:156
void(* Move)(GHandle gh, gCoord x, gCoord y)
Definition: gwin_class.h:161
void(* Delete)(GHandle gh)
Definition: gwin_class.h:158
void(* Init)(void)
Definition: gwin_class.h:155
void(* MinMax)(GHandle gh, GWindowMinMax minmax)
Definition: gwin_class.h:163
gBool(* Add)(GHandle gh, const GWindowInit *pInit)
Definition: gwin_class.h:157
void(* Size)(GHandle gh, gCoord w, gCoord h)
Definition: gwin_class.h:160
void(* Raise)(GHandle gh)
Definition: gwin_class.h:162
void(* Redraw)(GHandle gh)
Definition: gwin_class.h:159