Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wprogressindicator.c
Commit [+]AuthorDateLineData
052ab01c kojima1999-09-16 02:55:56 +00001/*
2 * Original idea and implementation by Frederik Schueler <fr.schueler@netsurf.de>
90c0e656 dan2006-04-25 19:35:14 +00003 * Rewritten by Pascal Hofstee <daeron@windowmaker.info>
052ab01c kojima1999-09-16 02:55:56 +00004 * - Added options to set min/max values
5 * - centralized drawing into one pain function
6 */
7
8#include "WINGsP.h"
9
10typedef struct W_ProgressIndicator {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020011 W_Class widgetClass;
12 W_View *view;
6830b057 dan2004-10-12 21:28:27 +000013
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020014 int value;
15 int minValue;
16 int maxValue;
6830b057 dan2004-10-12 21:28:27 +000017
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020018 void *clientData;
052ab01c kojima1999-09-16 02:55:56 +000019} ProgressIndicator;
20
052ab01c kojima1999-09-16 02:55:56 +000021#define DEFAULT_PROGRESS_INDICATOR_WIDTH 276
22#define DEFAULT_PROGRESS_INDICATOR_HEIGHT 16
23
24/* define if only the ticks within the progress region should be displayed */
2cf8c125 kojima2001-01-26 19:30:53 +000025#undef SHOW_PROGRESS_TICKS_ONLY
052ab01c kojima1999-09-16 02:55:56 +000026
052ab01c kojima1999-09-16 02:55:56 +000027static void didResizeProgressIndicator();
28
052ab01c kojima1999-09-16 02:55:56 +000029W_ViewDelegate _ProgressIndicatorDelegate = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020030 NULL,
31 NULL,
32 didResizeProgressIndicator,
33 NULL,
34 NULL
052ab01c kojima1999-09-16 02:55:56 +000035};
36
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020037static void destroyProgressIndicator(ProgressIndicator * pPtr);
38static void paintProgressIndicator(ProgressIndicator * pPtr);
39static void handleEvents(XEvent * event, void *data);
052ab01c kojima1999-09-16 02:55:56 +000040
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020041WMProgressIndicator *WMCreateProgressIndicator(WMWidget * parent)
052ab01c kojima1999-09-16 02:55:56 +000042{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020043 ProgressIndicator *pPtr;
6830b057 dan2004-10-12 21:28:27 +000044
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020045 pPtr = wmalloc(sizeof(ProgressIndicator));
46 memset(pPtr, 0, sizeof(ProgressIndicator));
6830b057 dan2004-10-12 21:28:27 +000047
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020048 pPtr->widgetClass = WC_ProgressIndicator;
6830b057 dan2004-10-12 21:28:27 +000049
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020050 pPtr->view = W_CreateView(W_VIEW(parent));
51 if (!pPtr->view) {
52 wfree(pPtr);
53 return NULL;
54 }
6830b057 dan2004-10-12 21:28:27 +000055
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020056 pPtr->view->self = pPtr;
6830b057 dan2004-10-12 21:28:27 +000057
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020058 pPtr->view->delegate = &_ProgressIndicatorDelegate;
6830b057 dan2004-10-12 21:28:27 +000059
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020060 WMCreateEventHandler(pPtr->view, ExposureMask | StructureNotifyMask, handleEvents, pPtr);
6830b057 dan2004-10-12 21:28:27 +000061
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020062 W_ResizeView(pPtr->view, DEFAULT_PROGRESS_INDICATOR_WIDTH, DEFAULT_PROGRESS_INDICATOR_HEIGHT);
6830b057 dan2004-10-12 21:28:27 +000063
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020064 /* Initialize ProgressIndicator Values */
65 pPtr->value = 0;
66 pPtr->minValue = 0;
67 pPtr->maxValue = 100;
6830b057 dan2004-10-12 21:28:27 +000068
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020069 return pPtr;
052ab01c kojima1999-09-16 02:55:56 +000070}
71
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020072void WMSetProgressIndicatorMinValue(WMProgressIndicator * progressindicator, int value)
052ab01c kojima1999-09-16 02:55:56 +000073{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020074 CHECK_CLASS(progressindicator, WC_ProgressIndicator);
75
76 progressindicator->minValue = value;
77 if (progressindicator->value < value) {
78 progressindicator->value = value;
79 if (progressindicator->view->flags.mapped) {
80 paintProgressIndicator(progressindicator);
81 }
82 }
052ab01c kojima1999-09-16 02:55:56 +000083}
84
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020085void WMSetProgressIndicatorMaxValue(WMProgressIndicator * progressindicator, int value)
052ab01c kojima1999-09-16 02:55:56 +000086{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020087 CHECK_CLASS(progressindicator, WC_ProgressIndicator);
88
89 progressindicator->maxValue = value;
90 if (progressindicator->value > value) {
91 progressindicator->value = value;
92 if (progressindicator->view->flags.mapped) {
93 paintProgressIndicator(progressindicator);
94 }
95 }
052ab01c kojima1999-09-16 02:55:56 +000096}
97
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020098void WMSetProgressIndicatorValue(WMProgressIndicator * progressindicator, int value)
052ab01c kojima1999-09-16 02:55:56 +000099{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200100 CHECK_CLASS(progressindicator, WC_ProgressIndicator);
6830b057 dan2004-10-12 21:28:27 +0000101
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200102 progressindicator->value = value;
6830b057 dan2004-10-12 21:28:27 +0000103
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200104 /* Check if value is within min/max-range */
105 if (progressindicator->minValue > value)
106 progressindicator->value = progressindicator->minValue;
6830b057 dan2004-10-12 21:28:27 +0000107
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200108 if (progressindicator->maxValue < value)
109 progressindicator->value = progressindicator->maxValue;
6830b057 dan2004-10-12 21:28:27 +0000110
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200111 if (progressindicator->view->flags.mapped) {
112 paintProgressIndicator(progressindicator);
113 }
052ab01c kojima1999-09-16 02:55:56 +0000114}
115
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200116int WMGetProgressIndicatorMinValue(WMProgressIndicator * progressindicator)
052ab01c kojima1999-09-16 02:55:56 +0000117{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200118 CHECK_CLASS(progressindicator, WC_ProgressIndicator);
6830b057 dan2004-10-12 21:28:27 +0000119
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200120 return progressindicator->minValue;
052ab01c kojima1999-09-16 02:55:56 +0000121}
122
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200123int WMGetProgressIndicatorMaxValue(WMProgressIndicator * progressindicator)
052ab01c kojima1999-09-16 02:55:56 +0000124{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200125 CHECK_CLASS(progressindicator, WC_ProgressIndicator);
6830b057 dan2004-10-12 21:28:27 +0000126
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200127 return progressindicator->maxValue;
052ab01c kojima1999-09-16 02:55:56 +0000128}
129
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200130int WMGetProgressIndicatorValue(WMProgressIndicator * progressindicator)
052ab01c kojima1999-09-16 02:55:56 +0000131{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200132 CHECK_CLASS(progressindicator, WC_ProgressIndicator);
6830b057 dan2004-10-12 21:28:27 +0000133
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200134 return progressindicator->value;
052ab01c kojima1999-09-16 02:55:56 +0000135}
136
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200137static void didResizeProgressIndicator(W_ViewDelegate * self, WMView * view)
052ab01c kojima1999-09-16 02:55:56 +0000138{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200139 WMProgressIndicator *pPtr = (WMProgressIndicator *) view->self;
140 int width = pPtr->view->size.width;
141 int height = pPtr->view->size.height;
6830b057 dan2004-10-12 21:28:27 +0000142
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200143 assert(width > 0);
144 assert(height > 0);
052ab01c kojima1999-09-16 02:55:56 +0000145}
146
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200147static void paintProgressIndicator(ProgressIndicator * pPtr)
052ab01c kojima1999-09-16 02:55:56 +0000148{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200149 W_Screen *scr = pPtr->view->screen;
150 GC bgc;
151 GC wgc;
152 GC lgc;
153 GC dgc;
154 WMSize size = pPtr->view->size;
155 int perc, w, h;
156 double unit, i;
157 Pixmap buffer;
6830b057 dan2004-10-12 21:28:27 +0000158
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200159 bgc = WMColorGC(scr->black);
160 wgc = WMColorGC(scr->white);
161 lgc = WMColorGC(scr->gray);
162 dgc = WMColorGC(scr->darkGray);
6830b057 dan2004-10-12 21:28:27 +0000163
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200164 unit = (double)(size.width - 3.0) / 100;
6830b057 dan2004-10-12 21:28:27 +0000165
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200166 buffer = XCreatePixmap(scr->display, pPtr->view->window, size.width, size.height, scr->depth);
6830b057 dan2004-10-12 21:28:27 +0000167
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200168 XFillRectangle(scr->display, buffer, lgc, 0, 0, size.width, size.height);
6830b057 dan2004-10-12 21:28:27 +0000169
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200170 /* Calculate size of Progress to draw and paint ticks */
171 perc = (pPtr->value - pPtr->minValue) * 100 / (pPtr->maxValue - pPtr->minValue);
6830b057 dan2004-10-12 21:28:27 +0000172
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200173 w = (int)((double)(perc * unit));
174 h = size.height - 2;
6830b057 dan2004-10-12 21:28:27 +0000175
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200176 if (w > (size.width - 3))
177 w = size.width - 3;
6830b057 dan2004-10-12 21:28:27 +0000178
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200179 if (w > 0) {
180 XFillRectangle(scr->display, buffer, lgc, 2, 1, w, h);
181 XFillRectangle(scr->display, buffer, scr->stippleGC, 2, 1, w, h);
182 W_DrawRelief(scr, buffer, 2, 1, w, h, WRFlat);
6830b057 dan2004-10-12 21:28:27 +0000183
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200184 /* Draw Progress Marks */
185 i = (5.0 * unit);
6830b057 dan2004-10-12 21:28:27 +0000186
052ab01c kojima1999-09-16 02:55:56 +0000187#ifdef SHOW_PROGRESS_TICKS_ONLY
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200188 while ((int)i < w + 5) {
052ab01c kojima1999-09-16 02:55:56 +0000189#else
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200190 while ((int)i < (size.width - 3)) {
052ab01c kojima1999-09-16 02:55:56 +0000191#endif
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200192 XDrawLine(scr->display, buffer, dgc, (int)i + 2, h - 1, i + 2, h - 3);
6830b057 dan2004-10-12 21:28:27 +0000193
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200194 i += (5.0 * unit);
6830b057 dan2004-10-12 21:28:27 +0000195
052ab01c kojima1999-09-16 02:55:56 +0000196#ifdef SHOW_PROGRESS_TICKS_ONLY
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200197 if ((int)i >= w)
198 break;
052ab01c kojima1999-09-16 02:55:56 +0000199#endif
6830b057 dan2004-10-12 21:28:27 +0000200
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200201 XDrawLine(scr->display, buffer, dgc, (int)i + 2, h - 1, i + 2, h - 6);
6830b057 dan2004-10-12 21:28:27 +0000202
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200203 i += (5.0 * unit);
204 }
205 }
6830b057 dan2004-10-12 21:28:27 +0000206
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200207 XDrawLine(scr->display, buffer, bgc, w + 2, 1, w + 2, h + 1);
208 XDrawLine(scr->display, buffer, lgc, 2, h, w + 2, h);
6830b057 dan2004-10-12 21:28:27 +0000209
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200210 XDrawLine(scr->display, buffer, dgc, 0, 0, 0, size.height - 1);
211 XDrawLine(scr->display, buffer, dgc, 0, 0, size.width, 0);
212 XDrawLine(scr->display, buffer, bgc, 1, 1, 1, size.height - 1);
213 XDrawLine(scr->display, buffer, bgc, 1, 1, size.width - 1, 1);
6830b057 dan2004-10-12 21:28:27 +0000214
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200215 XDrawLine(scr->display, buffer, wgc, size.width - 1, 0, size.width - 1, size.height - 1);
216 XDrawLine(scr->display, buffer, wgc, 0, size.height - 1, size.width - 1, size.height - 1);
6830b057 dan2004-10-12 21:28:27 +0000217
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200218 XCopyArea(scr->display, buffer, pPtr->view->window, scr->copyGC, 0, 0, size.width, size.height, 0, 0);
6830b057 dan2004-10-12 21:28:27 +0000219
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200220 XFreePixmap(scr->display, buffer);
052ab01c kojima1999-09-16 02:55:56 +0000221}
222
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200223static void handleEvents(XEvent * event, void *data)
052ab01c kojima1999-09-16 02:55:56 +0000224{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200225 ProgressIndicator *pPtr = (ProgressIndicator *) data;
226
227 CHECK_CLASS(data, WC_ProgressIndicator);
228
229 switch (event->type) {
230 case Expose:
231 if (event->xexpose.count != 0)
232 break;
233 paintProgressIndicator(pPtr);
234 break;
235 case DestroyNotify:
236 destroyProgressIndicator(pPtr);
237 break;
238 }
052ab01c kojima1999-09-16 02:55:56 +0000239}
240
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200241static void destroyProgressIndicator(ProgressIndicator * pPtr)
052ab01c kojima1999-09-16 02:55:56 +0000242{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200243 WMRemoveNotificationObserver(pPtr);
6830b057 dan2004-10-12 21:28:27 +0000244
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200245 wfree(pPtr);
052ab01c kojima1999-09-16 02:55:56 +0000246}