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 realizeProgressIndicator(ProgressIndicator
*pPtr
);
44 static void handleEvents(XEvent
*event
, void *data
);
49 realizeObserver(void *self
, WMNotification
*not)
51 realizeProgressIndicator(self
);
56 WMCreateProgressIndicator(WMWidget
*parent
)
58 ProgressIndicator
*pPtr
;
60 pPtr
= wmalloc(sizeof(ProgressIndicator
));
61 memset(pPtr
, 0, sizeof(ProgressIndicator
));
63 pPtr
->widgetClass
= WC_ProgressIndicator
;
65 pPtr
->view
= W_CreateView(W_VIEW(parent
));
71 pPtr
->view
->self
= pPtr
;
73 pPtr
->view
->delegate
= &_ProgressIndicatorDelegate
;
75 WMCreateEventHandler(pPtr
->view
, ExposureMask
|StructureNotifyMask
,
79 W_ResizeView(pPtr
->view
, DEFAULT_PROGRESS_INDICATOR_WIDTH
,
80 DEFAULT_PROGRESS_INDICATOR_HEIGHT
);
82 /* Initialize ProgressIndicator Values */
87 WMAddNotificationObserver(realizeObserver
, pPtr
,
88 WMViewRealizedNotification
, pPtr
->view
);
95 WMSetProgressIndicatorMinValue(WMProgressIndicator
*progressindicator
, int value
)
97 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
99 progressindicator
->minValue
= value
;
100 if (progressindicator
->value
< value
) {
101 progressindicator
->value
= value
;
102 if (progressindicator
->view
->flags
.mapped
) {
103 paintProgressIndicator(progressindicator
);
110 WMSetProgressIndicatorMaxValue(WMProgressIndicator
*progressindicator
, int value
)
112 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
114 progressindicator
->maxValue
= value
;
115 if (progressindicator
->value
> value
) {
116 progressindicator
->value
= value
;
117 if (progressindicator
->view
->flags
.mapped
) {
118 paintProgressIndicator(progressindicator
);
125 WMSetProgressIndicatorValue(WMProgressIndicator
*progressindicator
, int value
)
127 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
129 progressindicator
->value
= value
;
131 /* Check if value is within min/max-range */
132 if (progressindicator
->minValue
> value
)
133 progressindicator
->value
= progressindicator
->minValue
;
135 if (progressindicator
->maxValue
< value
)
136 progressindicator
->value
= progressindicator
->maxValue
;
139 if (progressindicator
->view
->flags
.mapped
) {
140 paintProgressIndicator(progressindicator
);
146 WMGetProgressIndicatorMinValue(WMProgressIndicator
*progressindicator
)
148 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
150 return progressindicator
->minValue
;
155 WMGetProgressIndicatorMaxValue(WMProgressIndicator
*progressindicator
)
157 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
159 return progressindicator
->maxValue
;
164 WMGetProgressIndicatorValue(WMProgressIndicator
*progressindicator
)
166 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
168 return progressindicator
->value
;
173 realizeProgressIndicator(ProgressIndicator
*pPtr
)
175 W_RealizeView(pPtr
->view
);
180 didResizeProgressIndicator(W_ViewDelegate
*self
, WMView
*view
)
182 WMProgressIndicator
*pPtr
= (WMProgressIndicator
*)view
->self
;
183 int width
= pPtr
->view
->size
.width
;
184 int height
= pPtr
->view
->size
.height
;
192 paintProgressIndicator(ProgressIndicator
*pPtr
)
194 W_Screen
*scr
= pPtr
->view
->screen
;
199 WMSize size
= pPtr
->view
->size
;
204 bgc
= WMColorGC(scr
->black
);
205 wgc
= WMColorGC(scr
->white
);
206 lgc
= WMColorGC(scr
->gray
);
207 dgc
= WMColorGC(scr
->darkGray
);
209 unit
= (double)(size
.width
- 3.0) / 100;
211 buffer
= XCreatePixmap(scr
->display
, pPtr
->view
->window
,
212 size
.width
, size
.height
, scr
->depth
);
214 XFillRectangle(scr
->display
, buffer
, lgc
, 0, 0, size
.width
, size
.height
);
216 /* Calculate size of Progress to draw and paint ticks*/
217 perc
= (pPtr
->value
- pPtr
->minValue
) * 100 / (pPtr
->maxValue
- pPtr
->minValue
);
219 w
= (int)((double)(perc
* unit
));
222 if (w
> (size
.width
- 3))
226 XFillRectangle(scr
->display
, buffer
, lgc
, 2, 1, w
, h
);
227 XFillRectangle(scr
->display
, buffer
, scr
->stippleGC
, 2, 1, w
, h
);
228 W_DrawRelief(scr
, buffer
, 2, 1, w
, h
, WRFlat
);
230 /* Draw Progress Marks */
233 #ifdef SHOW_PROGRESS_TICKS_ONLY
236 while ((int)i
< (size
.width
- 3)) {
238 XDrawLine(scr
->display
, buffer
, dgc
, (int)i
+2, h
-1, i
+2, h
-3);
242 #ifdef SHOW_PROGRESS_TICKS_ONLY
247 XDrawLine(scr
->display
, buffer
, dgc
, (int)i
+2, h
-1, i
+2, h
-6);
253 XDrawLine(scr
->display
, buffer
, bgc
, w
+2, 1, w
+2, h
+1);
254 XDrawLine(scr
->display
, buffer
, lgc
, 2, h
, w
+2, h
);
257 XDrawLine(scr
->display
, buffer
, dgc
, 0, 0, 0, size
.height
-1);
258 XDrawLine(scr
->display
, buffer
, dgc
, 0, 0, size
.width
, 0);
259 XDrawLine(scr
->display
, buffer
, bgc
, 1, 1, 1, size
.height
-1);
260 XDrawLine(scr
->display
, buffer
, bgc
, 1, 1, size
.width
-1, 1);
262 XDrawLine(scr
->display
, buffer
, wgc
, size
.width
-1, 0,
263 size
.width
-1, size
.height
-1);
264 XDrawLine(scr
->display
, buffer
, wgc
, 0, size
.height
-1,
265 size
.width
-1, size
.height
-1);
267 XCopyArea(scr
->display
, buffer
, pPtr
->view
->window
, scr
->copyGC
, 0, 0,
268 size
.width
, size
.height
, 0, 0);
270 XFreePixmap(scr
->display
, buffer
);
275 handleEvents(XEvent
*event
, void *data
)
277 ProgressIndicator
*pPtr
= (ProgressIndicator
*)data
;
279 CHECK_CLASS(data
, WC_ProgressIndicator
);
281 switch (event
->type
) {
283 if (event
->xexpose
.count
!=0)
285 paintProgressIndicator(pPtr
);
288 destroyProgressIndicator(pPtr
);
295 destroyProgressIndicator(ProgressIndicator
*pPtr
)
297 WMRemoveNotificationObserver(pPtr
);