From d435ea7468de6d5b13f275d5e08364db5ff08aeb Mon Sep 17 00:00:00 2001 From: "Carlos R. Mafra" Date: Thu, 25 Aug 2011 00:06:58 +0200 Subject: [PATCH] WINGs: Add back wprogressindicator.c The examples inside WINGs/Tests fail to compile otherwise. --- WINGs/Makefile.am | 1 + WINGs/wprogressindicator.c | 245 +++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 WINGs/wprogressindicator.c diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index 7a102ecd..2295718a 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -50,6 +50,7 @@ libWINGs_la_SOURCES = \ wpanel.c \ wpixmap.c \ wpopupbutton.c \ + wprogressindicator.c \ wruler.c \ wscroller.c \ wscrollview.c \ diff --git a/WINGs/wprogressindicator.c b/WINGs/wprogressindicator.c new file mode 100644 index 00000000..a897a9eb --- /dev/null +++ b/WINGs/wprogressindicator.c @@ -0,0 +1,245 @@ +/* + * Original idea and implementation by Frederik Schueler + * Rewritten by Pascal Hofstee + * - Added options to set min/max values + * - centralized drawing into one pain function + */ + +#include "WINGsP.h" + +typedef struct W_ProgressIndicator { + W_Class widgetClass; + W_View *view; + + int value; + int minValue; + int maxValue; + + 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 */ +#undef SHOW_PROGRESS_TICKS_ONLY + +static void didResizeProgressIndicator(); + +W_ViewDelegate _ProgressIndicatorDelegate = { + NULL, + NULL, + didResizeProgressIndicator, + NULL, + NULL +}; + +static void destroyProgressIndicator(ProgressIndicator * pPtr); +static void paintProgressIndicator(ProgressIndicator * pPtr); +static void handleEvents(XEvent * event, void *data); + +WMProgressIndicator *WMCreateProgressIndicator(WMWidget * parent) +{ + ProgressIndicator *pPtr; + + pPtr = wmalloc(sizeof(ProgressIndicator)); + + pPtr->widgetClass = WC_ProgressIndicator; + + pPtr->view = W_CreateView(W_VIEW(parent)); + if (!pPtr->view) { + wfree(pPtr); + return NULL; + } + + pPtr->view->self = pPtr; + + pPtr->view->delegate = &_ProgressIndicatorDelegate; + + WMCreateEventHandler(pPtr->view, ExposureMask | StructureNotifyMask, handleEvents, pPtr); + + W_ResizeView(pPtr->view, DEFAULT_PROGRESS_INDICATOR_WIDTH, DEFAULT_PROGRESS_INDICATOR_HEIGHT); + + /* Initialize ProgressIndicator Values */ + pPtr->value = 0; + pPtr->minValue = 0; + pPtr->maxValue = 100; + + return pPtr; +} + +void WMSetProgressIndicatorMinValue(WMProgressIndicator * progressindicator, int value) +{ + CHECK_CLASS(progressindicator, WC_ProgressIndicator); + + progressindicator->minValue = value; + if (progressindicator->value < value) { + progressindicator->value = value; + if (progressindicator->view->flags.mapped) { + paintProgressIndicator(progressindicator); + } + } +} + +void WMSetProgressIndicatorMaxValue(WMProgressIndicator * progressindicator, int value) +{ + CHECK_CLASS(progressindicator, WC_ProgressIndicator); + + progressindicator->maxValue = value; + if (progressindicator->value > value) { + progressindicator->value = value; + if (progressindicator->view->flags.mapped) { + paintProgressIndicator(progressindicator); + } + } +} + +void WMSetProgressIndicatorValue(WMProgressIndicator * progressindicator, int value) +{ + CHECK_CLASS(progressindicator, WC_ProgressIndicator); + + progressindicator->value = value; + + /* Check if value is within min/max-range */ + if (progressindicator->minValue > value) + progressindicator->value = progressindicator->minValue; + + if (progressindicator->maxValue < value) + progressindicator->value = progressindicator->maxValue; + + if (progressindicator->view->flags.mapped) { + paintProgressIndicator(progressindicator); + } +} + +int WMGetProgressIndicatorMinValue(WMProgressIndicator * progressindicator) +{ + CHECK_CLASS(progressindicator, WC_ProgressIndicator); + + return progressindicator->minValue; +} + +int WMGetProgressIndicatorMaxValue(WMProgressIndicator * progressindicator) +{ + CHECK_CLASS(progressindicator, WC_ProgressIndicator); + + return progressindicator->maxValue; +} + +int WMGetProgressIndicatorValue(WMProgressIndicator * progressindicator) +{ + CHECK_CLASS(progressindicator, WC_ProgressIndicator); + + return progressindicator->value; +} + +static void didResizeProgressIndicator(W_ViewDelegate * self, WMView * view) +{ + WMProgressIndicator *pPtr = (WMProgressIndicator *) view->self; + int width = pPtr->view->size.width; + int height = pPtr->view->size.height; + + assert(width > 0); + assert(height > 0); +} + +static void paintProgressIndicator(ProgressIndicator * pPtr) +{ + 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; + + bgc = WMColorGC(scr->black); + wgc = WMColorGC(scr->white); + lgc = WMColorGC(scr->gray); + dgc = WMColorGC(scr->darkGray); + + unit = (double)(size.width - 3.0) / 100; + + buffer = XCreatePixmap(scr->display, pPtr->view->window, size.width, size.height, scr->depth); + + XFillRectangle(scr->display, buffer, lgc, 0, 0, size.width, size.height); + + /* Calculate size of Progress to draw and paint ticks */ + perc = (pPtr->value - pPtr->minValue) * 100 / (pPtr->maxValue - pPtr->minValue); + + w = (int)((double)(perc * unit)); + h = size.height - 2; + + if (w > (size.width - 3)) + w = size.width - 3; + + if (w > 0) { + 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 + while ((int)i < w + 5) { +#else + while ((int)i < (size.width - 3)) { +#endif + XDrawLine(scr->display, buffer, dgc, (int)i + 2, h - 1, i + 2, h - 3); + + i += (5.0 * unit); + +#ifdef SHOW_PROGRESS_TICKS_ONLY + if ((int)i >= w) + break; +#endif + + XDrawLine(scr->display, buffer, dgc, (int)i + 2, h - 1, i + 2, h - 6); + + i += (5.0 * unit); + } + } + + XDrawLine(scr->display, buffer, bgc, w + 2, 1, w + 2, h + 1); + XDrawLine(scr->display, buffer, lgc, 2, h, w + 2, h); + + 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); + + XDrawLine(scr->display, buffer, wgc, size.width - 1, 0, size.width - 1, size.height - 1); + XDrawLine(scr->display, buffer, wgc, 0, size.height - 1, size.width - 1, size.height - 1); + + XCopyArea(scr->display, buffer, pPtr->view->window, scr->copyGC, 0, 0, size.width, size.height, 0, 0); + + XFreePixmap(scr->display, buffer); +} + +static void handleEvents(XEvent * event, void *data) +{ + ProgressIndicator *pPtr = (ProgressIndicator *) data; + + CHECK_CLASS(data, WC_ProgressIndicator); + + switch (event->type) { + case Expose: + if (event->xexpose.count != 0) + break; + paintProgressIndicator(pPtr); + break; + case DestroyNotify: + destroyProgressIndicator(pPtr); + break; + } +} + +static void destroyProgressIndicator(ProgressIndicator * pPtr) +{ + WMRemoveNotificationObserver(pPtr); + + wfree(pPtr); +}