2 * Original idea and implementation by Frederik Schueler <fr.schueler@netsurf.de>
3 * Rewritten by Pascal Hofstee <daeron@windowmaker.org>
4 * - Added options to set min/max values
5 * - centralized drawing into one pain function
10 typedef struct W_ProgressIndicator
{
22 #define DEFAULT_PROGRESS_INDICATOR_WIDTH 276
23 #define DEFAULT_PROGRESS_INDICATOR_HEIGHT 16
25 /* define if only the ticks within the progress region should be displayed */
26 #undef SHOW_PROGRESS_TICKS_ONLY
29 static void didResizeProgressIndicator();
32 W_ViewDelegate _ProgressIndicatorDelegate
= {
35 didResizeProgressIndicator
,
41 static void destroyProgressIndicator(ProgressIndicator
*pPtr
);
42 static void paintProgressIndicator(ProgressIndicator
*pPtr
);
43 static void handleEvents(XEvent
*event
, void *data
);
48 WMCreateProgressIndicator(WMWidget
*parent
)
50 ProgressIndicator
*pPtr
;
52 pPtr
= wmalloc(sizeof(ProgressIndicator
));
53 memset(pPtr
, 0, sizeof(ProgressIndicator
));
55 pPtr
->widgetClass
= WC_ProgressIndicator
;
57 pPtr
->view
= W_CreateView(W_VIEW(parent
));
63 pPtr
->view
->self
= pPtr
;
65 pPtr
->view
->delegate
= &_ProgressIndicatorDelegate
;
67 WMCreateEventHandler(pPtr
->view
, ExposureMask
|StructureNotifyMask
,
71 W_ResizeView(pPtr
->view
, DEFAULT_PROGRESS_INDICATOR_WIDTH
,
72 DEFAULT_PROGRESS_INDICATOR_HEIGHT
);
74 /* Initialize ProgressIndicator Values */
84 WMSetProgressIndicatorMinValue(WMProgressIndicator
*progressindicator
, int value
)
86 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
88 progressindicator
->minValue
= value
;
89 if (progressindicator
->value
< value
) {
90 progressindicator
->value
= value
;
91 if (progressindicator
->view
->flags
.mapped
) {
92 paintProgressIndicator(progressindicator
);
99 WMSetProgressIndicatorMaxValue(WMProgressIndicator
*progressindicator
, int value
)
101 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
103 progressindicator
->maxValue
= value
;
104 if (progressindicator
->value
> value
) {
105 progressindicator
->value
= value
;
106 if (progressindicator
->view
->flags
.mapped
) {
107 paintProgressIndicator(progressindicator
);
114 WMSetProgressIndicatorValue(WMProgressIndicator
*progressindicator
, int value
)
116 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
118 progressindicator
->value
= value
;
120 /* Check if value is within min/max-range */
121 if (progressindicator
->minValue
> value
)
122 progressindicator
->value
= progressindicator
->minValue
;
124 if (progressindicator
->maxValue
< value
)
125 progressindicator
->value
= progressindicator
->maxValue
;
128 if (progressindicator
->view
->flags
.mapped
) {
129 paintProgressIndicator(progressindicator
);
135 WMGetProgressIndicatorMinValue(WMProgressIndicator
*progressindicator
)
137 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
139 return progressindicator
->minValue
;
144 WMGetProgressIndicatorMaxValue(WMProgressIndicator
*progressindicator
)
146 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
148 return progressindicator
->maxValue
;
153 WMGetProgressIndicatorValue(WMProgressIndicator
*progressindicator
)
155 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
157 return progressindicator
->value
;
162 didResizeProgressIndicator(W_ViewDelegate
*self
, WMView
*view
)
164 WMProgressIndicator
*pPtr
= (WMProgressIndicator
*)view
->self
;
165 int width
= pPtr
->view
->size
.width
;
166 int height
= pPtr
->view
->size
.height
;
174 paintProgressIndicator(ProgressIndicator
*pPtr
)
176 W_Screen
*scr
= pPtr
->view
->screen
;
181 WMSize size
= pPtr
->view
->size
;
186 bgc
= WMColorGC(scr
->black
);
187 wgc
= WMColorGC(scr
->white
);
188 lgc
= WMColorGC(scr
->gray
);
189 dgc
= WMColorGC(scr
->darkGray
);
191 unit
= (double)(size
.width
- 3.0) / 100;
193 buffer
= XCreatePixmap(scr
->display
, pPtr
->view
->window
,
194 size
.width
, size
.height
, scr
->depth
);
196 XFillRectangle(scr
->display
, buffer
, lgc
, 0, 0, size
.width
, size
.height
);
198 /* Calculate size of Progress to draw and paint ticks*/
199 perc
= (pPtr
->value
- pPtr
->minValue
) * 100 / (pPtr
->maxValue
- pPtr
->minValue
);
201 w
= (int)((double)(perc
* unit
));
204 if (w
> (size
.width
- 3))
208 XFillRectangle(scr
->display
, buffer
, lgc
, 2, 1, w
, h
);
209 XFillRectangle(scr
->display
, buffer
, scr
->stippleGC
, 2, 1, w
, h
);
210 W_DrawRelief(scr
, buffer
, 2, 1, w
, h
, WRFlat
);
212 /* Draw Progress Marks */
215 #ifdef SHOW_PROGRESS_TICKS_ONLY
218 while ((int)i
< (size
.width
- 3)) {
220 XDrawLine(scr
->display
, buffer
, dgc
, (int)i
+2, h
-1, i
+2, h
-3);
224 #ifdef SHOW_PROGRESS_TICKS_ONLY
229 XDrawLine(scr
->display
, buffer
, dgc
, (int)i
+2, h
-1, i
+2, h
-6);
235 XDrawLine(scr
->display
, buffer
, bgc
, w
+2, 1, w
+2, h
+1);
236 XDrawLine(scr
->display
, buffer
, lgc
, 2, h
, w
+2, h
);
239 XDrawLine(scr
->display
, buffer
, dgc
, 0, 0, 0, size
.height
-1);
240 XDrawLine(scr
->display
, buffer
, dgc
, 0, 0, size
.width
, 0);
241 XDrawLine(scr
->display
, buffer
, bgc
, 1, 1, 1, size
.height
-1);
242 XDrawLine(scr
->display
, buffer
, bgc
, 1, 1, size
.width
-1, 1);
244 XDrawLine(scr
->display
, buffer
, wgc
, size
.width
-1, 0,
245 size
.width
-1, size
.height
-1);
246 XDrawLine(scr
->display
, buffer
, wgc
, 0, size
.height
-1,
247 size
.width
-1, size
.height
-1);
249 XCopyArea(scr
->display
, buffer
, pPtr
->view
->window
, scr
->copyGC
, 0, 0,
250 size
.width
, size
.height
, 0, 0);
252 XFreePixmap(scr
->display
, buffer
);
257 handleEvents(XEvent
*event
, void *data
)
259 ProgressIndicator
*pPtr
= (ProgressIndicator
*)data
;
261 CHECK_CLASS(data
, WC_ProgressIndicator
);
263 switch (event
->type
) {
265 if (event
->xexpose
.count
!=0)
267 paintProgressIndicator(pPtr
);
270 destroyProgressIndicator(pPtr
);
277 destroyProgressIndicator(ProgressIndicator
*pPtr
)
279 WMRemoveNotificationObserver(pPtr
);