|
From: Kevin W. <sw...@wo...> - 2005-02-25 22:32:13
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 D'oh. I built the new Tile correctly, but didn't place it in /Library/Tcl. Moving things over fixed the problem. This is really cool, and absolutely perfect for the DarwinPorts GUI I'm working on. Thanks for putting it together. Cheers, Kevin Walzer, PhD WordTech Software--Open Source Applications and Packages for OS X http://www.wordtech-software.com http://www.smallbizmac.com http://www.kevin-walzer.com mailto:sw...@wo... Michael Kirkham wrote: | On Fri, 25 Feb 2005, Kevin Walzer wrote: | |> Michael, |> |> OK, I think I've gotten the patches applied correctly, and the new |> version of Tile built. I have written a little script to display the |> barber pole, and I'm not getting it right (nothing displays but the |> "trough" where the progress bar should be). Can you take a look and let |> me know what I'm doing wrong? | | | What you have should work. I'd have to guess the patches weren't | applied correctly, or it's using your unpatched version or something. | Perhaps the attached will work better if the former (unified diff format). | |> package require tile |> |> ttk::progress .p1 -from 0 -to 0 |> pack .p1 | | | This should actually be sufficient to get the barber pole, as currently | implemented. It uses timer events to animate, rather than relying set | calls to refresh. Otherwise the animation would be anything but smooth. | | To turn off the barber pole: | | .p1 config -to 1; # anything non-zero, really | |> .p1 set 0 |> set i1 0 |> |> proc showprog {} { |> global i1 |> incr i1 |> .p1 set $i1 |> after 10 showprog |> } |> |> after 10 showprog | | | This will actually never set the value beyond 0 (with or without the | patch): the set value gets capped at the -to value. i.e., | | .p1 config -to 0 | .p1 set 10000 | puts [.p1 get] | | ...will print 0. | | -- | Michael Kirkham | www.muonics.com | | | ------------------------------------------------------------------------ | | Index: generic/scale.c | =================================================================== | RCS file: /cvsroot/tktable/tile/generic/scale.c,v | retrieving revision 1.39 | diff -u -r1.39 scale.c | --- generic/scale.c 11 Dec 2004 00:36:38 -0000 1.39 | +++ generic/scale.c 25 Feb 2005 22:07:04 -0000 | @@ -18,6 +18,10 @@ | #define DEF_SCALE_WIDTH "15" | #define DEF_SCALE_LENGTH "100" | #define DEF_SCALE_SHOW_VALUE "1" | +#define DEF_SCALE_PERIOD 100 | + | +#define DEF_SCALE_STRIPE_WIDTH 10.0 | +#define DEF_SCALE_STRIPE_PHASES 4 | | #ifndef MAX | #define MAX(a,b) ((a) > (b) ? (a) : (b)) | @@ -45,6 +49,9 @@ | | /* internal state */ | int orient; | + | + /* Timer handler for animated progress bars */ | + Tcl_TimerToken timer; | } ScalePart; | | typedef struct | @@ -98,6 +105,8 @@ | { | Scale *scalePtr = recordPtr; | | + scalePtr->scale.timer = (Tcl_TimerToken) NULL; | + | TrackElementState(&scalePtr->core); | return TCL_OK; | } | @@ -235,6 +244,11 @@ | return r; | } | | +static void | +AnimateProgress(Scale *scalePtr); | +static void | +CancelAnimation(Scale *scalePtr); | + | static int | ScaleSetCommand( | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], void *recordPtr) | @@ -279,6 +293,7 @@ | scalePtr->scale.valueObj, TCL_GLOBAL_ONLY); | } | if (WidgetDestroyed(&scalePtr->core)) { | + CancelAnimation(scalePtr); | return TCL_ERROR; | } | | @@ -466,6 +481,27 @@ | } | } | | +/* | + * ProgressDisplay -- | + * Display progress bar, possibly with animation. | + */ | +void ProgressDisplay(void *clientData, Drawable d) | +{ | + WidgetCore *corePtr = clientData; | + Scale *scalePtr = clientData; | + | + Ttk_DrawLayout(corePtr->layout, corePtr->state, d); | + | + /* | + * Set a new timer handler for animation re-display if necessary. | + * This is done here so that animation will resume on a progress | + * bar that hasn't changed its current value between theme | + * changes to/from animated/non-animated themes. | + */ | + | + AnimateProgress(scalePtr); | +} | + | /* | * ScaleSize -- | * Compute requested size of scale. | @@ -553,12 +589,56 @@ | * Progress widget overrides. | */ | | +static void | +AnimateProgressProc(ClientData clientData) | +{ | + Scale *scalePtr = (Scale *)clientData; | + | + WidgetChanged(&scalePtr->core, REDISPLAY_REQUIRED); | +} | + | +static void | +CancelAnimation(Scale *scalePtr) | +{ | + if (scalePtr->scale.timer) { | + Tcl_DeleteTimerHandler(scalePtr->scale.timer); | + scalePtr->scale.timer = (Tcl_TimerToken) NULL; | + } | +} | + | +static void | +AnimateProgress(Scale *scalePtr) | +{ | + double from = 0, to = 0, current = 0; | + | + Tcl_GetDoubleFromObj(NULL, scalePtr->scale.fromObj, &from); | + Tcl_GetDoubleFromObj(NULL, scalePtr->scale.toObj, &to); | + Tcl_GetDoubleFromObj(NULL, scalePtr->scale.valueObj, ¤t); | + | + /* | + * Cancel pending animation redisplay timer handler, if any | + */ | + | + CancelAnimation(scalePtr); | + | + /* | + * Only animate if the current value is within the from/to range | + * or from and to are the same for an indeterminate progress bar. | + */ | + | + if (((current > from) && (current < to)) || ((from == 0) && (to == 0))) { | + scalePtr->scale.timer = Tcl_CreateTimerHandler(DEF_SCALE_PERIOD, | + AnimateProgressProc, (ClientData)scalePtr); | + } | +} | + | static int | ProgressInitialize(Tcl_Interp *interp, void *recordPtr) | { | Scale *scalePtr = recordPtr; | | scalePtr->scale.showValue = 0; | + scalePtr->scale.timer = (Tcl_TimerToken) NULL; | | return TCL_OK; | } | @@ -622,7 +702,7 @@ | ProgressGetLayout, /* getLayoutProc */ | ScaleSize, /* sizeProc */ | ProgressDoLayout, /* layoutProc */ | - WidgetDisplay, /* displayProc */ | + ProgressDisplay, /* displayProc */ | WIDGET_SPEC_END /* sentinel */ | }; | | Index: generic/tkElements.c | =================================================================== | RCS file: /cvsroot/tktable/tile/generic/tkElements.c,v | retrieving revision 1.69 | diff -u -r1.69 tkElements.c | --- generic/tkElements.c 31 Dec 2004 01:32:57 -0000 1.69 | +++ generic/tkElements.c 25 Feb 2005 22:07:05 -0000 | @@ -9,6 +9,7 @@ | #include <tcl.h> | #include <tk.h> | #include <string.h> | +#include <sys/time.h> | #include "tkTheme.h" | | #define DEFAULT_BORDERWIDTH "2" | @@ -901,6 +902,9 @@ | Tcl_Obj *reliefObj; /* the relief for this object */ | Tcl_Obj *borderObj; /* the background color */ | Tcl_Obj *borderWidthObj; /* the size of the border */ | + Tcl_Obj *fromObj; /* minimum value for progress range */ | + Tcl_Obj *toObj; /* maximum value for progress range */ | + Tcl_Obj *stripeObj; /* stripe color for indeterminite progress */ | } SliderElement; | | static Ttk_ElementOptionSpec SliderElementOptions[] = | @@ -917,6 +921,12 @@ | DEFAULT_BACKGROUND }, | { "-orient", TK_OPTION_ANY, Tk_Offset(SliderElement,orientObj), | "horizontal" }, | + { "-from", TK_OPTION_DOUBLE, Tk_Offset(SliderElement,fromObj), | + "0" }, | + { "-to", TK_OPTION_DOUBLE, Tk_Offset(SliderElement,toObj), | + "1.0" }, | + { "-stripecolor", TK_OPTION_COLOR, Tk_Offset(SliderElement,stripeObj), | + "white" }, | { NULL } | }; | | @@ -1004,22 +1014,94 @@ | * A progress bar. | */ | | +#define DEF_SCALE_PERIOD 100 | +#define DEF_SCALE_STRIPE_WIDTH 10.0 | +#define DEF_SCALE_STRIPE_PHASES 4 | + | static void | ProgressElementDraw(void *clientData, void *elementRecord, | Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state) | { | SliderElement *slider = elementRecord; | - Tk_3DBorder border = NULL; | - int relief, borderWidth, orient; | + double from, to; | | - border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj); | - Ttk_GetOrientationFromObj(NULL, slider->orientObj, &orient); | - Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth); | - Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief); | + Tcl_GetDoubleFromObj(NULL, slider->fromObj, &from); | + Tcl_GetDoubleFromObj(NULL, slider->toObj, &to); | | - Tk_Fill3DRectangle(tkwin, d, border, | - b.x, b.y, b.width, b.height, | - borderWidth, relief); | + /* | + * Display barberpole-style stripes for an indefinite progress bar | + * if the from and to values are both zero. | + */ | + | + if ((from == 0) && (to == 0)) { | + Display *display = Tk_Display(tkwin); | + struct timeval tv; | + struct timezone tz; | + int phase; | + int x; | + int ofs1 = b.height/2; | + int ofs2 = b.height*3/2; | + GC gc; | + XGCValues gcValues; | + XColor* colorPtr = Tk_GetColorFromObj(tkwin, slider->borderObj); | + | + gc = Tk_GCForColor(colorPtr, d); | + | + XFillRectangle(display, d, gc, b.x, b.y, b.width, b.height); | + | + /* | + * Calculate the phase based on the time of day and hard-coded | + * phase period. | + */ | + | + gettimeofday(&tv, &tz); | + | + phase = (((tv.tv_sec * 1000) + (tv.tv_usec / 1000)) / DEF_SCALE_PERIOD); | + phase %= DEF_SCALE_STRIPE_PHASES; | + | + /* | + * Start drawing the stripes within the region one stripe width to | + * the left of the visible area so that the stripes don't jump | + * between phase resets. | + */ | + | + x = -b.height; | + x += ((b.height * 1.5) / DEF_SCALE_STRIPE_PHASES)*phase; | + | + colorPtr = Tk_GetColorFromObj(tkwin, slider->stripeObj); | + | + /* | + * colorPtr = Tk_GetColorFromObj(tkwin, scalePtr->scale.foregroundObj); | + */ | + | + gcValues.foreground = colorPtr->pixel; | + gcValues.line_width = (int)b.height/2; | + | + gc = Tk_GetGC(tkwin, GCForeground | GCLineWidth, &gcValues); | + | + /* | + * Draw the stripes. | + */ | + | + while (x < b.width + b.height / 2) { | + XDrawLine(display, d, gc, x - ofs1, -ofs1, (x + ofs2), ofs2); | + x += (int)(b.height * 1.5); | + } | + | + Tk_FreeGC(display, gc); | + } else { | + Tk_3DBorder border = NULL; | + int relief, borderWidth, orient; | + | + border = Tk_Get3DBorderFromObj(tkwin, slider->borderObj); | + Ttk_GetOrientationFromObj(NULL, slider->orientObj, &orient); | + Tk_GetPixelsFromObj(NULL, tkwin, slider->borderWidthObj, &borderWidth); | + Tk_GetReliefFromObj(NULL, slider->reliefObj, &relief); | + | + Tk_Fill3DRectangle(tkwin, d, border, | + b.x, b.y, b.width, b.height, | + borderWidth, relief); | + } | } | | static Ttk_ElementSpec ProgressElementSpec = | Index: macosx/aquaTheme.c | =================================================================== | RCS file: /cvsroot/tktable/tile/macosx/aquaTheme.c,v | retrieving revision 1.19 | diff -u -r1.19 aquaTheme.c | --- macosx/aquaTheme.c 11 Dec 2004 00:36:41 -0000 1.19 | +++ macosx/aquaTheme.c 25 Feb 2005 22:07:06 -0000 | @@ -35,6 +35,8 @@ | #include <tkMacOSX.h> | #include "tkTheme.h" | | +#define DEF_SCALE_PERIOD 100 | + | /*---------------------------------------------------------------------- | * +++ Utilities. | */ | @@ -507,7 +509,25 @@ | | switch (data->kind) { | case kThemeProgressBar: | - drawInfo.trackInfo.progress.phase = 0; /* 1-4: animation phase */ | + { | + struct timeval tv; | + struct timezone tz; | + gettimeofday(&tv, &tz); | + | + /* @@@ Should check -period style setting and divide by | + * @@@ period rather than 100 if non-zero, or set phase to 0 | + * @@@ if period is 0? | + */ | + | + drawInfo.trackInfo.progress.phase = | + (UInt8)(((tv.tv_sec * 1000) + (tv.tv_usec / 1000)) | + / DEF_SCALE_PERIOD); | + | + if ((from == 0) && (to == 0)) { | + drawInfo.max = 1; | + drawInfo.kind = kThemeIndeterminateBar; | + } | + } | break; | case kThemeSlider: | drawInfo.trackInfo.slider.pressState = 0; /* @@@ fill this in */ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (Darwin) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCH6doJmdQs+6YVcoRAsvqAJ41InCX2Bk0VVEkek9cKjW6CIx0VgCghl04 5lyQ2sLiSlQkUIB52DZ3/7U= =HEga -----END PGP SIGNATURE----- |