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 #define 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
);
46 static void realizeObserver(void *self
, WMNotification
*not) {
48 realizeProgressIndicator(self
);
54 WMCreateProgressIndicator(WMWidget
*parent
)
56 ProgressIndicator
*pPtr
;
57 W_Screen
*scrPtr
= W_VIEW(parent
)->screen
;
59 pPtr
= wmalloc(sizeof(ProgressIndicator
));
60 memset(pPtr
, 0, sizeof(ProgressIndicator
));
62 pPtr
->widgetClass
= WC_ProgressIndicator
;
64 pPtr
->view
= W_CreateView(W_VIEW(parent
));
70 pPtr
->view
->self
= pPtr
;
72 pPtr
->view
->delegate
= &_ProgressIndicatorDelegate
;
74 WMCreateEventHandler(pPtr
->view
, ExposureMask
|StructureNotifyMask
,
78 W_ResizeView(pPtr
->view
, DEFAULT_PROGRESS_INDICATOR_WIDTH
,
79 DEFAULT_PROGRESS_INDICATOR_HEIGHT
);
81 /* Initialize ProgressIndicator Values */
86 WMAddNotificationObserver(realizeObserver
, pPtr
,
87 WMViewRealizedNotification
, pPtr
->view
);
94 WMSetProgressIndicatorMinValue(WMProgressIndicator
*progressindicator
, int value
)
96 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
98 progressindicator
->minValue
= value
;
99 if (progressindicator
->value
< value
) {
100 progressindicator
->value
= value
;
101 if (progressindicator
->view
->flags
.mapped
) {
102 paintProgressIndicator(progressindicator
);
109 WMSetProgressIndicatorMaxValue(WMProgressIndicator
*progressindicator
, int value
)
111 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
113 progressindicator
->maxValue
= value
;
114 if (progressindicator
->value
> value
) {
115 progressindicator
->value
= value
;
116 if (progressindicator
->view
->flags
.mapped
) {
117 paintProgressIndicator(progressindicator
);
124 WMSetProgressIndicatorValue(WMProgressIndicator
*progressindicator
, int value
)
126 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
128 progressindicator
->value
= value
;
130 /* Check if value is within min/max-range */
131 if (progressindicator
->minValue
> value
)
132 progressindicator
->value
= progressindicator
->minValue
;
134 if (progressindicator
->maxValue
< value
)
135 progressindicator
->value
= progressindicator
->maxValue
;
138 if (progressindicator
->view
->flags
.mapped
) {
139 paintProgressIndicator(progressindicator
);
145 WMGetProgressIndicatorMinValue(WMProgressIndicator
*progressindicator
)
147 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
149 return progressindicator
->minValue
;
154 WMGetProgressIndicatorMaxValue(WMProgressIndicator
*progressindicator
)
156 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
158 return progressindicator
->maxValue
;
163 WMGetProgressIndicatorValue(WMProgressIndicator
*progressindicator
)
165 CHECK_CLASS(progressindicator
, WC_ProgressIndicator
);
167 return progressindicator
->value
;
172 realizeProgressIndicator(ProgressIndicator
*pPtr
)
174 W_RealizeView(pPtr
->view
);
179 didResizeProgressIndicator(W_ViewDelegate
*self
, WMView
*view
)
181 WMProgressIndicator
*pPtr
= (WMProgressIndicator
*)view
->self
;
182 int width
= pPtr
->view
->size
.width
;
183 int height
= pPtr
->view
->size
.height
;
191 paintProgressIndicator(ProgressIndicator
*pPtr
)
193 W_Screen
*scr
= pPtr
->view
->screen
;
198 WMSize size
= pPtr
->view
->size
;
203 bgc
= WMColorGC(scr
->black
);
204 wgc
= WMColorGC(scr
->white
);
205 lgc
= WMColorGC(scr
->gray
);
206 dgc
= WMColorGC(scr
->darkGray
);
208 unit
= (double)(size
.width
- 3.0) / 100;
210 buffer
= XCreatePixmap(scr
->display
, pPtr
->view
->window
,
211 size
.width
, size
.height
, scr
->depth
);
213 XFillRectangle(scr
->display
, buffer
, lgc
, 0, 0, size
.width
, size
.height
);
215 /* Calculate size of Progress to draw and paint ticks*/
216 perc
= (pPtr
->value
- pPtr
->minValue
) * 100 / (pPtr
->maxValue
- pPtr
->minValue
);
218 w
= (int)((double)(perc
* unit
));
221 if (w
> (size
.width
- 3))
225 XFillRectangle(scr
->display
, buffer
, lgc
, 2, 1, w
, h
);
226 XFillRectangle(scr
->display
, buffer
, scr
->stippleGC
, 2, 1, w
, h
);
227 W_DrawRelief(scr
, buffer
, 2, 1, w
, h
, WRFlat
);
229 /* Draw Progress Marks */
232 #ifdef SHOW_PROGRESS_TICKS_ONLY
235 while ((int)i
< (size
.width
- 3)) {
237 XDrawLine(scr
->display
, buffer
, dgc
, (int)i
+2, h
-1, i
+2, h
-3);
241 #ifdef SHOW_PROGRESS_TICKS_ONLY
246 XDrawLine(scr
->display
, buffer
, dgc
, (int)i
+2, h
-1, i
+2, h
-6);
252 XDrawLine(scr
->display
, buffer
, bgc
, w
+2, 1, w
+2, h
+1);
253 XDrawLine(scr
->display
, buffer
, lgc
, 2, h
, w
+2, h
);
256 XDrawLine(scr
->display
, buffer
, dgc
, 0, 0, 0, size
.height
-1);
257 XDrawLine(scr
->display
, buffer
, dgc
, 0, 0, size
.width
, 0);
258 XDrawLine(scr
->display
, buffer
, bgc
, 1, 1, 1, size
.height
-1);
259 XDrawLine(scr
->display
, buffer
, bgc
, 1, 1, size
.width
-1, 1);
261 XDrawLine(scr
->display
, buffer
, wgc
, size
.width
-1, 0,
262 size
.width
-1, size
.height
-1);
263 XDrawLine(scr
->display
, buffer
, wgc
, 0, size
.height
-1,
264 size
.width
-1, size
.height
-1);
266 XCopyArea(scr
->display
, buffer
, pPtr
->view
->window
, scr
->copyGC
, 0, 0,
267 size
.width
, size
.height
, 0, 0);
269 XFreePixmap(scr
->display
, buffer
);
273 handleEvents(XEvent
*event
, void *data
)
275 ProgressIndicator
*pPtr
= (ProgressIndicator
*)data
;
277 CHECK_CLASS(data
, WC_ProgressIndicator
);
279 switch (event
->type
) {
281 if (event
->xexpose
.count
!=0)
283 paintProgressIndicator(pPtr
);
286 destroyProgressIndicator(pPtr
);
293 destroyProgressIndicator(ProgressIndicator
*pPtr
)
295 WMRemoveNotificationObserver(pPtr
);