updated spanish po
[wmaker-crm.git] / WINGs / wprogressindicator.c
blob54ce3f0d6ecb9b345d33c0e8b0253722a3c326c4
1 /*
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
6 */
8 #include "WINGsP.h"
10 typedef struct W_ProgressIndicator {
11 W_Class widgetClass;
12 W_View *view;
14 int value;
15 int minValue;
16 int maxValue;
18 void *clientData;
19 } 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 = {
33 NULL,
34 NULL,
35 didResizeProgressIndicator,
36 NULL,
37 NULL
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);
48 static void
49 realizeObserver(void *self, WMNotification *not)
51 realizeProgressIndicator(self);
55 WMProgressIndicator*
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));
66 if (!pPtr->view) {
67 wfree(pPtr);
68 return NULL;
71 pPtr->view->self = pPtr;
73 pPtr->view->delegate = &_ProgressIndicatorDelegate;
75 WMCreateEventHandler(pPtr->view, ExposureMask|StructureNotifyMask,
76 handleEvents, pPtr);
79 W_ResizeView(pPtr->view, DEFAULT_PROGRESS_INDICATOR_WIDTH,
80 DEFAULT_PROGRESS_INDICATOR_HEIGHT);
82 /* Initialize ProgressIndicator Values */
83 pPtr->value = 0;
84 pPtr->minValue = 0;
85 pPtr->maxValue = 100;
87 WMAddNotificationObserver(realizeObserver, pPtr,
88 WMViewRealizedNotification, pPtr->view);
90 return pPtr;
94 void
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);
109 void
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);
124 void
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;
172 static void
173 realizeProgressIndicator(ProgressIndicator *pPtr)
175 W_RealizeView(pPtr->view);
179 static void
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;
186 assert(width > 0);
187 assert(height > 0);
191 static void
192 paintProgressIndicator(ProgressIndicator *pPtr)
194 W_Screen *scr = pPtr->view->screen;
195 GC bgc;
196 GC wgc;
197 GC lgc;
198 GC dgc;
199 WMSize size = pPtr->view->size;
200 int perc, w, h;
201 double unit, i;
202 Pixmap buffer;
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));
220 h = size.height - 2;
222 if (w > (size.width - 3))
223 w = size.width - 3;
225 if (w > 0) {
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 */
231 i=(5.0*unit);
233 #ifdef SHOW_PROGRESS_TICKS_ONLY
234 while((int)i<w+5) {
235 #else
236 while ((int)i < (size.width - 3)) {
237 #endif
238 XDrawLine(scr->display, buffer, dgc, (int)i+2, h-1, i+2, h-3);
240 i+=(5.0*unit);
242 #ifdef SHOW_PROGRESS_TICKS_ONLY
243 if((int)i>=w)
244 break;
245 #endif
247 XDrawLine(scr->display, buffer, dgc, (int)i+2, h-1, i+2, h-6);
249 i+=(5.0*unit);
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);
274 static void
275 handleEvents(XEvent *event, void *data)
277 ProgressIndicator *pPtr = (ProgressIndicator*)data;
279 CHECK_CLASS(data, WC_ProgressIndicator);
281 switch (event->type) {
282 case Expose:
283 if (event->xexpose.count!=0)
284 break;
285 paintProgressIndicator(pPtr);
286 break;
287 case DestroyNotify:
288 destroyProgressIndicator(pPtr);
289 break;
294 static void
295 destroyProgressIndicator(ProgressIndicator *pPtr)
297 WMRemoveNotificationObserver(pPtr);
299 wfree(pPtr);