Files
wmaker/WINGs/wprogressindicator.c
T

284 lines
6.7 KiB
C
Raw Normal View History

/*
* Original idea and implementation by Frederik Schueler <fr.schueler@netsurf.de>
* Rewritten by Pascal Hofstee <daeron@windowmaker.org>
* - Added options to set min/max values
* - centralized drawing into one pain function
*/
#include "WINGsP.h"
typedef struct W_ProgressIndicator {
1999-10-03 03:47:21 +00:00
W_Class widgetClass;
W_View *view;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
int value;
int minValue;
int maxValue;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
void *clientData;
} ProgressIndicator;
#define DEFAULT_PROGRESS_INDICATOR_WIDTH 276
#define DEFAULT_PROGRESS_INDICATOR_HEIGHT 16
/* define if only the ticks within the progress region should be displayed */
2001-01-26 19:30:53 +00:00
#undef SHOW_PROGRESS_TICKS_ONLY
static void didResizeProgressIndicator();
W_ViewDelegate _ProgressIndicatorDelegate = {
NULL,
2002-01-10 06:03:06 +00:00
NULL,
didResizeProgressIndicator,
NULL,
NULL
};
static void destroyProgressIndicator(ProgressIndicator *pPtr);
static void paintProgressIndicator(ProgressIndicator *pPtr);
static void handleEvents(XEvent *event, void *data);
2002-01-10 06:03:06 +00:00
WMProgressIndicator*
2002-01-10 06:03:06 +00:00
WMCreateProgressIndicator(WMWidget *parent)
{
1999-10-03 03:47:21 +00:00
ProgressIndicator *pPtr;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
pPtr = wmalloc(sizeof(ProgressIndicator));
memset(pPtr, 0, sizeof(ProgressIndicator));
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
pPtr->widgetClass = WC_ProgressIndicator;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
pPtr->view = W_CreateView(W_VIEW(parent));
if (!pPtr->view) {
2004-10-12 21:28:27 +00:00
wfree(pPtr);
return NULL;
1999-10-03 03:47:21 +00:00
}
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
pPtr->view->self = pPtr;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
pPtr->view->delegate = &_ProgressIndicatorDelegate;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
WMCreateEventHandler(pPtr->view, ExposureMask|StructureNotifyMask,
2004-10-12 21:28:27 +00:00
handleEvents, pPtr);
1999-10-03 03:47:21 +00:00
W_ResizeView(pPtr->view, DEFAULT_PROGRESS_INDICATOR_WIDTH,
2004-10-12 21:28:27 +00:00
DEFAULT_PROGRESS_INDICATOR_HEIGHT);
1999-10-03 03:47:21 +00:00
/* Initialize ProgressIndicator Values */
pPtr->value = 0;
pPtr->minValue = 0;
pPtr->maxValue = 100;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
return pPtr;
}
void
WMSetProgressIndicatorMinValue(WMProgressIndicator *progressindicator, int value)
{
1999-10-03 03:47:21 +00:00
CHECK_CLASS(progressindicator, WC_ProgressIndicator);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
progressindicator->minValue = value;
if (progressindicator->value < value) {
2004-10-12 21:28:27 +00:00
progressindicator->value = value;
if (progressindicator->view->flags.mapped) {
paintProgressIndicator(progressindicator);
}
1999-10-03 03:47:21 +00:00
}
}
void
WMSetProgressIndicatorMaxValue(WMProgressIndicator *progressindicator, int value)
{
1999-10-03 03:47:21 +00:00
CHECK_CLASS(progressindicator, WC_ProgressIndicator);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
progressindicator->maxValue = value;
if (progressindicator->value > value) {
2004-10-12 21:28:27 +00:00
progressindicator->value = value;
if (progressindicator->view->flags.mapped) {
paintProgressIndicator(progressindicator);
}
1999-10-03 03:47:21 +00:00
}
}
void
WMSetProgressIndicatorValue(WMProgressIndicator *progressindicator, int value)
{
1999-10-03 03:47:21 +00:00
CHECK_CLASS(progressindicator, WC_ProgressIndicator);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
progressindicator->value = value;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
/* Check if value is within min/max-range */
if (progressindicator->minValue > value)
2004-10-12 21:28:27 +00:00
progressindicator->value = progressindicator->minValue;
1999-10-03 03:47:21 +00:00
if (progressindicator->maxValue < value)
2004-10-12 21:28:27 +00:00
progressindicator->value = progressindicator->maxValue;
1999-10-03 03:47:21 +00:00
if (progressindicator->view->flags.mapped) {
2004-10-12 21:28:27 +00:00
paintProgressIndicator(progressindicator);
1999-10-03 03:47:21 +00:00
}
}
int
WMGetProgressIndicatorMinValue(WMProgressIndicator *progressindicator)
{
1999-10-03 03:47:21 +00:00
CHECK_CLASS(progressindicator, WC_ProgressIndicator);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
return progressindicator->minValue;
}
int
WMGetProgressIndicatorMaxValue(WMProgressIndicator *progressindicator)
{
1999-10-03 03:47:21 +00:00
CHECK_CLASS(progressindicator, WC_ProgressIndicator);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
return progressindicator->maxValue;
}
int
WMGetProgressIndicatorValue(WMProgressIndicator *progressindicator)
{
1999-10-03 03:47:21 +00:00
CHECK_CLASS(progressindicator, WC_ProgressIndicator);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
return progressindicator->value;
}
static void
didResizeProgressIndicator(W_ViewDelegate *self, WMView *view)
{
1999-10-03 03:47:21 +00:00
WMProgressIndicator *pPtr = (WMProgressIndicator*)view->self;
int width = pPtr->view->size.width;
int height = pPtr->view->size.height;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
assert(width > 0);
assert(height > 0);
}
static void
paintProgressIndicator(ProgressIndicator *pPtr)
{
1999-10-03 03:47:21 +00:00
W_Screen *scr = pPtr->view->screen;
GC bgc;
GC wgc;
GC lgc;
GC dgc;
WMSize size = pPtr->view->size;
int perc, w, h;
double unit, i;
Pixmap buffer;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
bgc = WMColorGC(scr->black);
wgc = WMColorGC(scr->white);
lgc = WMColorGC(scr->gray);
dgc = WMColorGC(scr->darkGray);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
unit = (double)(size.width - 3.0) / 100;
2004-10-12 21:28:27 +00:00
buffer = XCreatePixmap(scr->display, pPtr->view->window,
size.width, size.height, scr->depth);
1999-10-03 03:47:21 +00:00
XFillRectangle(scr->display, buffer, lgc, 0, 0, size.width, size.height);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
/* Calculate size of Progress to draw and paint ticks*/
perc = (pPtr->value - pPtr->minValue) * 100 / (pPtr->maxValue - pPtr->minValue);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
w = (int)((double)(perc * unit));
h = size.height - 2;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
if (w > (size.width - 3))
2004-10-12 21:28:27 +00:00
w = size.width - 3;
1999-10-03 03:47:21 +00:00
if (w > 0) {
2004-10-12 21:28:27 +00:00
XFillRectangle(scr->display, buffer, lgc, 2, 1, w, h);
XFillRectangle(scr->display, buffer, scr->stippleGC, 2, 1, w, h);
W_DrawRelief(scr, buffer, 2, 1, w, h, WRFlat);
/* Draw Progress Marks */
i=(5.0*unit);
#ifdef SHOW_PROGRESS_TICKS_ONLY
2004-10-12 21:28:27 +00:00
while((int)i<w+5) {
#else
2004-10-12 21:28:27 +00:00
while ((int)i < (size.width - 3)) {
#endif
2004-10-12 21:28:27 +00:00
XDrawLine(scr->display, buffer, dgc, (int)i+2, h-1, i+2, h-3);
i+=(5.0*unit);
#ifdef SHOW_PROGRESS_TICKS_ONLY
2004-10-12 21:28:27 +00:00
if((int)i>=w)
break;
#endif
2004-10-12 21:28:27 +00:00
XDrawLine(scr->display, buffer, dgc, (int)i+2, h-1, i+2, h-6);
i+=(5.0*unit);
}
1999-10-03 03:47:21 +00:00
}
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
XDrawLine(scr->display, buffer, bgc, w+2, 1, w+2, h+1);
XDrawLine(scr->display, buffer, lgc, 2, h, w+2, h);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
XDrawLine(scr->display, buffer, dgc, 0, 0, 0, size.height-1);
XDrawLine(scr->display, buffer, dgc, 0, 0, size.width, 0);
XDrawLine(scr->display, buffer, bgc, 1, 1, 1, size.height-1);
XDrawLine(scr->display, buffer, bgc, 1, 1, size.width-1, 1);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
XDrawLine(scr->display, buffer, wgc, size.width-1, 0,
2004-10-12 21:28:27 +00:00
size.width-1, size.height-1);
1999-10-03 03:47:21 +00:00
XDrawLine(scr->display, buffer, wgc, 0, size.height-1,
2004-10-12 21:28:27 +00:00
size.width-1, size.height-1);
1999-10-03 03:47:21 +00:00
XCopyArea(scr->display, buffer, pPtr->view->window, scr->copyGC, 0, 0,
2004-10-12 21:28:27 +00:00
size.width, size.height, 0, 0);
1999-10-03 03:47:21 +00:00
XFreePixmap(scr->display, buffer);
}
2002-01-10 06:03:06 +00:00
static void
handleEvents(XEvent *event, void *data)
{
1999-10-03 03:47:21 +00:00
ProgressIndicator *pPtr = (ProgressIndicator*)data;
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
CHECK_CLASS(data, WC_ProgressIndicator);
2004-10-12 21:28:27 +00:00
1999-10-03 03:47:21 +00:00
switch (event->type) {
2004-10-12 21:28:27 +00:00
case Expose:
if (event->xexpose.count!=0)
break;
paintProgressIndicator(pPtr);
break;
case DestroyNotify:
destroyProgressIndicator(pPtr);
break;
1999-10-03 03:47:21 +00:00
}
}
static void
destroyProgressIndicator(ProgressIndicator *pPtr)
{
1999-10-03 03:47:21 +00:00
WMRemoveNotificationObserver(pPtr);
2004-10-12 21:28:27 +00:00
1999-10-09 20:07:23 +00:00
wfree(pPtr);
}