µGFX  2.9
version 2.9
gwin_progressbar.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_progressbar.c
10  * @brief GWIN sub-system progressbar code
11  */
12 
13 #include "../../gfx.h"
14 
15 #if (GFX_USE_GWIN && GWIN_NEED_PROGRESSBAR) || defined(__DOXYGEN__)
16 
17 #include "gwin_class.h"
18 
19 // Reset the display position back to the value predicted by the saved progressbar position
20 static void PBResetDisplayPos(GProgressbarObject *gsw) {
21  if (gsw->w.g.width < gsw->w.g.height)
22  gsw->dpos = gsw->w.g.height-1-((gsw->w.g.height-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min);
23  else
24  gsw->dpos = ((gsw->w.g.width-1)*(gsw->pos-gsw->min))/(gsw->max-gsw->min);
25 }
26 
27 // We have to deinitialize the timer which auto updates the progressbar if any
28 static void PBDestroy(GHandle gh) {
29  #if GWIN_PROGRESSBAR_AUTO
30  gtimerStop(&((GProgressbarObject *)gh)->gt);
31  gtimerDeinit(&((GProgressbarObject *)gh)->gt);
32  #endif
33 
34  _gwidgetDestroy(gh);
35 }
36 
37 // The progressbar VMT table
38 static const gwidgetVMT progressbarVMT = {
39  {
40  "Progressbar", // The classname
41  sizeof(GProgressbarObject), // The object size
42  PBDestroy, // The destroy routine
43  _gwidgetRedraw, // The redraw routine
44  0, // The after-clear routine
45  },
46  gwinProgressbarDraw_Std, // The default drawing routine
47  #if GINPUT_NEED_MOUSE
48  {
49  0, // Process mouse down events (NOT USED)
50  0, // Process mouse up events
51  0, // Process mouse move events
52  },
53  #endif
54  #if GINPUT_NEED_KEYBOARD || GWIN_NEED_KEYBOARD
55  {
56  0 // Process keyboard events
57  },
58  #endif
59  #if GINPUT_NEED_TOGGLE
60  {
61  0, // 1 toggle role
62  0, // Assign Toggles
63  0, // Get Toggles
64  0, // Process toggle off events (NOT USED)
65  0, // Process toggle on events
66  },
67  #endif
68  #if GINPUT_NEED_DIAL
69  {
70  0, // 1 dial roles
71  0, // Assign Dials
72  0, // Get Dials
73  0, // Process dial move events
74  },
75  #endif
76 };
77 
78 GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gs, const GWidgetInit *pInit) {
79  if (!(gs = (GProgressbarObject *)_gwidgetCreate(g, &gs->w, pInit, &progressbarVMT)))
80  return 0;
81 
82  gs->min = 0;
83  gs->max = 100;
84  gs->res = 1;
85  gs->pos = 0;
86 
87  #if GWIN_PROGRESSBAR_AUTO
88  gtimerInit(&gs->gt);
89  #endif
90 
91  PBResetDisplayPos(gs);
92  gwinSetVisible((GHandle)gs, pInit->g.show);
93 
94  return (GHandle)gs;
95 }
96 
97 void gwinProgressbarSetRange(GHandle gh, int min, int max) {
98  #define gsw ((GProgressbarObject *)gh)
99 
100  if (gh->vmt != (gwinVMT *)&progressbarVMT)
101  return;
102 
103  if (min == max) // prevent divide by 0 errors.
104  max++;
105  if (min <= max) {
106  gsw->min = min;
107  gsw->max = max;
108  gsw->pos = min;
109  gsw->res = 1;
110  } else {
111  gsw->min = max;
112  gsw->max = min;
113  gsw->pos = min;
114  gsw->res = -1;
115  }
116 
117  PBResetDisplayPos(gsw);
118 
119  #undef gsw
120 }
121 
123  #define gsw ((GProgressbarObject *)gh)
124 
125  if (gh->vmt != (gwinVMT *)&progressbarVMT)
126  return;
127 
128  if (pos < gsw->min) gsw->pos = gsw->min;
129  else if (pos > gsw->max) gsw->pos = gsw->max;
130  else gsw->pos = pos;
131 
132  PBResetDisplayPos(gsw);
133  _gwinUpdate(gh);
134 
135  #undef gsw
136 }
137 
138 void gwinProgressbarSetResolution(GHandle gh, int resolution) {
139  #define gsw ((GProgressbarObject *)gh)
140 
141  if (gh->vmt != (gwinVMT *)&progressbarVMT)
142  return;
143 
144  gsw->res = resolution;
145 
146  #undef gsw
147 }
148 
150  #define gsw ((GProgressbarObject *)gh)
151 
152  if (gh->vmt != (gwinVMT *)&progressbarVMT)
153  return;
154 
155  gsw->pos += gsw->res;
156  if (gsw->pos < gsw->min) gsw->pos = gsw->min;
157  else if (gsw->pos > gsw->max) gsw->pos = gsw->max;
158 
159  PBResetDisplayPos(gsw);
160  _gwinUpdate(gh);
161 
162  #undef gsw
163 }
164 
166  #define gsw ((GProgressbarObject *)gh)
167 
168  if (gh->vmt != (gwinVMT *)&progressbarVMT)
169  return;
170 
171  gsw->pos -= gsw->res;
172  if (gsw->pos < gsw->min) gsw->pos = gsw->min;
173  else if (gsw->pos > gsw->max) gsw->pos = gsw->max;
174 
175  PBResetDisplayPos(gsw);
176  _gwinUpdate(gh);
177 
178  #undef gsw
179 }
180 
181 #if GWIN_PROGRESSBAR_AUTO
182  // used by gwinProgressbarStart();
183  static void _progressbarCallback(void *param) {
184  #define gsw ((GProgressbarObject *)gh)
185  GHandle gh = (GHandle)param;
186 
187  if (gh->vmt != (gwinVMT *)&progressbarVMT)
188  return;
189 
191 
192  if (gsw->pos >= gsw->max)
193  gtimerStop(&gsw->gt);
194 
195  #undef gsw
196  }
197 
198  void gwinProgressbarStart(GHandle gh, gDelay delay) {
199  #define gsw ((GProgressbarObject *)gh)
200 
201  if (gh->vmt != (gwinVMT *)&progressbarVMT)
202  return;
203 
204  gtimerStart(&gsw->gt, _progressbarCallback, gh, gTrue, delay);
205 
206  #undef gsw
207  }
208 
209  void gwinProgressbarStop(GHandle gh) {
210  #define gsw ((GProgressbarObject *)gh)
211 
212  if (gh->vmt != (gwinVMT *)&progressbarVMT)
213  return;
214 
215  gtimerStop(&gsw->gt);
216 
217  #undef gsw
218  }
219 #endif /* GWIN_PROGRESSBAR_AUTO */
220 
221 /*----------------------------------------------------------
222  * Custom Draw Routines
223  *----------------------------------------------------------*/
224 
225 void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param) {
226  #define gsw ((GProgressbarObject *)gw)
227 
228  const GColorSet * pcol;
229  (void) param;
230 
231  if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
232  return;
233 
234  // get the colors right
235  if ((gw->g.flags & GWIN_FLG_SYSENABLED))
236  pcol = &gw->pstyle->enabled;
237  else
238  pcol = &gw->pstyle->disabled;
239 
240  // Vertical progressbar
241  if (gw->g.width < gw->g.height) {
242  if (gsw->dpos != gw->g.height-1)
243  gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, pcol->progress); // Active Area
244  if (gsw->dpos != 0)
245  gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gsw->dpos, pcol->fill); // Inactive area
246  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
247  gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb
248 
249  // Horizontal progressbar
250  } else {
251  if (gsw->dpos != gw->g.width-1)
252  gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, pcol->fill); // Inactive area
253  if (gsw->dpos != 0)
254  gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gsw->dpos, gw->g.height, pcol->progress); // Active Area
255  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
256  gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
257  }
258  gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, gJustifyCenter);
259 
260  #undef gsw
261 }
262 
263 #if GDISP_NEED_IMAGE
264 void gwinProgressbarDraw_Image(GWidgetObject *gw, void *param) {
265  #define gsw ((GProgressbarObject *)gw)
266  #define gi ((gImage *)param)
267  const GColorSet * pcol;
268  gCoord z, v;
269 
270  if (gw->g.vmt != (gwinVMT *)&progressbarVMT)
271  return;
272 
273  if ((gw->g.flags & GWIN_FLG_SYSENABLED))
274  pcol = &gw->pstyle->enabled;
275  else
276  pcol = &gw->pstyle->disabled;
277 
278  // Vertical progressbar
279  if (gw->g.width < gw->g.height) {
280  if (gsw->dpos != 0) // The unfilled area
281  gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gsw->dpos-1, gw->pstyle->enabled.progress); // Inactive area
282  if (gsw->dpos != gw->g.height-1) { // The filled area
283  for(z=gw->g.height, v=gi->height; z > gsw->dpos;) {
284  z -= v;
285  if (z < gsw->dpos) {
286  v -= gsw->dpos - z;
287  z = gsw->dpos;
288  }
289  gdispGImageDraw(gw->g.display, gi, gw->g.x+1, gw->g.y+z+1, gw->g.width-1, v-2, 0, gi->height-v);
290  }
291  }
292  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
293  gdispGDrawLine(gw->g.display, gw->g.x+1, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-2, gw->g.y+gsw->dpos, pcol->edge); // Thumb
294 
295  // Horizontal progressbar
296  } else {
297  if (gsw->dpos != gw->g.width-1) // The unfilled area
298  gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos+1, gw->g.y+1, gw->g.width-gsw->dpos-2, gw->g.height-2, gw->pstyle->enabled.progress); // Inactive area
299  if (gsw->dpos != 0) { // The filled area
300  for(z=0, v=gi->width; z < gsw->dpos; z += v) {
301  if (z+v > gsw->dpos)
302  v -= z+v - gsw->dpos;
303  gdispGImageDraw(gw->g.display, gi, gw->g.x+z+1, gw->g.y+1, v-1, gw->g.height-2, 0, 0);
304  }
305  }
306  gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
307  gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y+1, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-2, pcol->edge); // Thumb
308  }
309  gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, gJustifyCenter);
310 
311  #undef gsw
312 }
313 #endif /* GDISP_NEED_IMAGE */
314 
315 #endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */
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.
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
void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, gBool periodic, gDelay millisec)
Set a timer going or alter its properties if it is already going.
Definition: gtimer.c:139
void gtimerInit(GTimer *pt)
Initialise a timer.
Definition: gtimer.c:129
void gtimerDeinit(GTimer *pt)
Deinitialise a timer.
Definition: gtimer.c:134
void gtimerStop(GTimer *pt)
Stop a timer (periodic or otherwise)
Definition: gtimer.c:190
#define gt(str)
A wrapper macro to make writing and reading translatable applications easier.
Definition: gtrans.h:37
gdispImageError gdispGImageDraw(GDisplay *g, gImage *img, gCoord x, gCoord y, gCoord cx, gCoord cy, gCoord sx, gCoord sy)
Draw the image.
void gwinProgressbarSetRange(GHandle gh, int min, int max)
Set the progressbar range.
void gwinProgressbarStop(GHandle gh)
Stop the timer which is started by gwinProgressbarStart()
GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gs, const GWidgetInit *pInit)
Create a progressbar window.
void gwinProgressbarSetResolution(GHandle gh, int resolution)
Set the resolution for the incrementation and decrementation of the progressbar.
void gwinProgressbarSetPosition(GHandle gh, int pos)
Set the progressbar position.
void gwinProgressbarIncrement(GHandle gh)
Increment the progressbar value.
void gwinProgressbarDecrement(GHandle gh)
Decrement the progressbar value.
void gwinProgressbarStart(GHandle gh, gDelay delay)
Automatically increments the progress bar.
void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param)
The default rendering function for the progressbar widget.
void gwinProgressbarDraw_Image(GWidgetObject *gw, void *param)
Renders a progressbar using an image.
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 progress
Definition: gwin_widget.h:41
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
const char * text
Definition: gwin_widget.h:120
GColorSet disabled
Definition: gwin_widget.h:56
GColorSet enabled
Definition: gwin_widget.h:55
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