Mercurial > hg > xemacs-beta
comparison lwlib/xlwscrollbar.c @ 26:441bb1e64a06 r19-15b96
Import from CVS: tag r19-15b96
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:51:32 +0200 |
parents | 9ee227acff29 |
children | 131b0175ea99 |
comparison
equal
deleted
inserted
replaced
25:383a494979f8 | 26:441bb1e64a06 |
---|---|
1 /* Implements a lightweight scrollbar widget. | 1 /* Implements a lightweight scrollbar widget. |
2 Copyright (C) 1992, 1993, 1994 Lucid, Inc. | 2 Copyright (C) 1992, 1993, 1994 Lucid, Inc. |
3 Copyright (C) 1997 Sun Microsystems, Inc. | |
3 | 4 |
4 This file is part of the Lucid Widget Library. | 5 This file is part of the Lucid Widget Library. |
5 | 6 |
6 The Lucid Widget Library is free software; you can redistribute it and/or | 7 The Lucid Widget Library is free software; you can redistribute it and/or |
7 modify it under the terms of the GNU General Public License as published by | 8 modify it under the terms of the GNU General Public License as published by |
17 along with XEmacs; see the file COPYING. If not, write to | 18 along with XEmacs; see the file COPYING. If not, write to |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 Boston, MA 02111-1307, USA. */ | 20 Boston, MA 02111-1307, USA. */ |
20 | 21 |
21 /* Created by Douglas Keller <dkeller@vnet.ibm.com> */ | 22 /* Created by Douglas Keller <dkeller@vnet.ibm.com> */ |
23 /* Lots of hacking by Martin Buchholz */ | |
22 | 24 |
23 /* | 25 /* |
24 * Athena-style scrollbar button bindings added on Sun Dec 24 22:03:57 1995 | 26 * Athena-style scrollbar button bindings added on Sun Dec 24 22:03:57 1995 |
25 * by Jonathan Stigelman <Stig@hackvan.com>... Ho ho ho! | 27 * by Jonathan Stigelman <Stig@hackvan.com>... Ho ho ho! |
26 * | 28 * |
59 * XmNpageDecrementCallback | 61 * XmNpageDecrementCallback |
60 * XmNtoTopCallback | 62 * XmNtoTopCallback |
61 * XmNtoBottomCallback | 63 * XmNtoBottomCallback |
62 * XmNdragCallback | 64 * XmNdragCallback |
63 * | 65 * |
64 * XmNknobStyle - values can be: "plain" or "dimple" | 66 * XmNsliderStyle - values can be: "plain" or "dimple" |
65 * XmNarrowPosition - values can be: "opposite" or "same" | 67 * XmNarrowPosition - values can be: "opposite" or "same" |
66 * | 68 * |
67 */ | 69 */ |
68 | 70 |
69 #include <stdio.h> | 71 #include <stdio.h> |
84 | 86 |
85 #define VERT(w) ((w)->sb.orientation == XmVERTICAL) | 87 #define VERT(w) ((w)->sb.orientation == XmVERTICAL) |
86 | 88 |
87 #define SS_MIN 8 | 89 #define SS_MIN 8 |
88 | 90 |
89 #define ARROW_UP 0 | 91 typedef enum |
90 #define ARROW_DOWN 1 | 92 { |
91 #define ARROW_LEFT 2 | 93 BUTTON_NONE, |
92 #define ARROW_RIGHT 3 | 94 BUTTON_SLIDER, |
93 | 95 BUTTON_UP_ARROW, |
94 #define ARM_NONE 0 | 96 BUTTON_DOWN_ARROW, |
95 #define ARM_KNOB 1 | 97 BUTTON_TROUGH_ABOVE, |
96 #define ARM_UP 2 | 98 BUTTON_TROUGH_BELOW |
97 #define ARM_DOWN 3 | 99 } button_where; |
98 #define ARM_PAGEUP 4 | 100 |
99 #define ARM_PAGEDOWN 5 | 101 typedef enum |
100 | 102 { |
101 #define BUTTON_NONE 0 | 103 SLIDER_PLAIN, |
102 #define BUTTON_KNOB 1 | 104 SLIDER_DIMPLE |
103 #define BUTTON_UP_ARROW 2 | 105 } SliderStyle; |
104 #define BUTTON_DOWN_ARROW 3 | 106 |
105 #define BUTTON_TROUGH_ABOVE 4 | 107 /*-------------------------- Resources ----------------------------------*/ |
106 #define BUTTON_TROUGH_BELOW 5 | |
107 | |
108 #define KNOB_PLAIN 0 | |
109 #define KNOB_DIMPLE 1 | |
110 | |
111 /************************************************************************ | |
112 ** | |
113 ** Resources | |
114 ** | |
115 */ | |
116 #define offset(field) XtOffset(XlwScrollBarWidget, field) | 108 #define offset(field) XtOffset(XlwScrollBarWidget, field) |
117 | 109 |
118 static XtResource resources[] = { | 110 static XtResource resources[] = { |
119 { XmNforeground, XmCForeground, XtRPixel, sizeof(Pixel), | 111 { XmNforeground, XmCForeground, XtRPixel, sizeof(Pixel), |
120 offset(sb.foreground), XtRImmediate, (XtPointer) XtDefaultForeground }, | 112 offset(sb.foreground), XtRImmediate, (XtPointer) XtDefaultForeground }, |
187 { XmNtoBottomCallback, XmCToBottomCallback, XtRCallback, | 179 { XmNtoBottomCallback, XmCToBottomCallback, XtRCallback, |
188 sizeof(XtPointer), offset(sb.toBottomCBL), XtRCallback, NULL}, | 180 sizeof(XtPointer), offset(sb.toBottomCBL), XtRCallback, NULL}, |
189 { XmNdragCallback, XmCDragCallback, XtRCallback, | 181 { XmNdragCallback, XmCDragCallback, XtRCallback, |
190 sizeof(XtPointer), offset(sb.dragCBL), XtRCallback, NULL}, | 182 sizeof(XtPointer), offset(sb.dragCBL), XtRCallback, NULL}, |
191 | 183 |
184 /* "knob" is obsolete; use "slider" instead. */ | |
185 { XmNsliderStyle, XmCSliderStyle, XtRString, sizeof(char *), | |
186 offset(sb.sliderStyle), XtRImmediate, NULL}, | |
192 { XmNknobStyle, XmCKnobStyle, XtRString, sizeof(char *), | 187 { XmNknobStyle, XmCKnobStyle, XtRString, sizeof(char *), |
193 offset(sb.knobStyle), XtRImmediate, NULL}, | 188 offset(sb.sliderStyle), XtRImmediate, NULL}, |
194 | 189 |
195 { XmNarrowPosition, XmCArrowPosition, XtRString, | 190 { XmNarrowPosition, XmCArrowPosition, XtRString, |
196 sizeof(char *), offset(sb.arrowPosition), XtRImmediate, NULL}, | 191 sizeof(char *), offset(sb.arrowPosition), XtRImmediate, NULL}, |
197 }; | 192 }; |
198 | 193 |
199 /************************************************************************ | 194 /*-------------------------- Prototypes ---------------------------------*/ |
200 ** | 195 |
201 ** Prototypes | 196 /* Actions */ |
202 ** | 197 typedef void Action(Widget w, XEvent *event, String *parms, Cardinal *num_parms); |
203 */ | 198 static Action Select, PageUpOrLeft, PageDownOrRight, Drag, Release, Jump, Abort; |
204 | 199 |
205 /* | 200 /* Methods */ |
206 ** Actions | |
207 */ | |
208 static void Select(Widget w, XEvent *event, String *parms, Cardinal *num_parms); | |
209 static void PageUpOrLeft(Widget w, XEvent *event, String *parms, Cardinal *num_parms); | |
210 static void PageDownOrRight(Widget w, XEvent *event, String *parms, Cardinal *num_parms); | |
211 static void Drag(Widget w, XEvent *event, String *parms, Cardinal *num_parms); | |
212 static void Release(Widget w, XEvent *event, String *parms, Cardinal *num_parms); | |
213 static void Jump(Widget w, XEvent *event, String *parms, Cardinal *num_parms); | |
214 static void Abort(Widget w, XEvent *event, String *parms, Cardinal *num_parms); | |
215 | |
216 /* | |
217 ** Methods | |
218 */ | |
219 static void Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num_args); | 201 static void Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num_args); |
220 static Boolean SetValues(Widget current, Widget request, Widget nw, ArgList args, Cardinal *num_args); | 202 static Boolean SetValues(Widget current, Widget request, Widget nw, ArgList args, Cardinal *num_args); |
221 static void Destroy(Widget widget); | 203 static void Destroy(Widget widget); |
222 static void Redisplay(Widget widget, XEvent *event, Region region); | 204 static void Redisplay(Widget widget, XEvent *event, Region region); |
223 static void Resize(Widget widget); | 205 static void Resize(Widget widget); |
224 static void Realize(Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr); | 206 static void Realize(Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr); |
225 | 207 |
226 /* | 208 /* Private */ |
227 ** Private | 209 |
228 */ | 210 /*-------------------------- Actions Table ------------------------------*/ |
229 | 211 static XtActionsRec actions[] = |
230 | 212 { |
231 /************************************************************************ | 213 {"Select", Select}, |
232 ** | 214 {"PageDownOrRight", PageDownOrRight}, |
233 ** Actions Table | 215 {"PageUpOrLeft", PageUpOrLeft}, |
234 ** | 216 {"Drag", Drag}, |
235 */ | 217 {"Release", Release}, |
236 static XtActionsRec actions[] = { | 218 {"Jump", Jump}, |
237 {"Select", Select}, | 219 {"Abort", Abort}, |
238 {"PageDownOrRight", PageDownOrRight}, | |
239 {"PageUpOrLeft", PageUpOrLeft}, | |
240 {"Drag", Drag}, | |
241 {"Release", Release}, | |
242 {"Jump", Jump}, | |
243 {"Abort", Abort}, | |
244 }; | 220 }; |
245 | 221 |
246 /************************************************************************ | 222 /*--------------------- Default Translation Table -----------------------*/ |
247 ** | |
248 ** Default Translation Table | |
249 ** | |
250 */ | |
251 static char default_translations[] = | 223 static char default_translations[] = |
252 "<Btn1Down>: Select()\n" | 224 "<Btn1Down>: Select()\n" |
253 "<Btn1Motion>: Drag()\n" | 225 "<Btn1Motion>: Drag()\n" |
254 "<Btn1Up>: Release()\n" | 226 "<Btn1Up>: Release()\n" |
255 "<Btn2Down>: Jump()\n" | 227 "<Btn2Down>: Jump()\n" |
256 "<Btn2Motion>: Drag()\n" | 228 "<Btn2Motion>: Drag()\n" |
257 "<Btn2Up>: Release()\n" | 229 "<Btn2Up>: Release()\n" |
258 "<Key>Delete: Abort()" | 230 "<Key>Delete: Abort()" |
259 ; | 231 ; |
260 | 232 |
261 /************************************************************************ | 233 /*------------------- Class record initialization -----------------------*/ |
262 ** | |
263 ** Class record initalization | |
264 ** | |
265 */ | |
266 XlwScrollBarClassRec xlwScrollBarClassRec = { | 234 XlwScrollBarClassRec xlwScrollBarClassRec = { |
267 /* core_class fields */ | 235 /* core_class fields */ |
268 { | 236 { |
269 /* superclass */ (WidgetClass) &coreClassRec, | 237 /* superclass */ (WidgetClass) &coreClassRec, |
270 /* class_name */ "XlwScrollBar", | 238 /* class_name */ "XlwScrollBar", |
303 }, | 271 }, |
304 }; | 272 }; |
305 | 273 |
306 WidgetClass xlwScrollBarWidgetClass = (WidgetClass) &xlwScrollBarClassRec; | 274 WidgetClass xlwScrollBarWidgetClass = (WidgetClass) &xlwScrollBarClassRec; |
307 | 275 |
308 /************************************************************************ | 276 /*-------------------------- Debug Functions ----------------------------*/ |
309 ** | |
310 ** Debug functions | |
311 ** | |
312 */ | |
313 | 277 |
314 #ifdef SHOW_CLEAR | 278 #ifdef SHOW_CLEAR |
315 static void | 279 static void |
316 myXClearArea(Display *dpy, Drawable d, int x, int y, int w, int h, | 280 myXClearArea(Display *dpy, Drawable d, int x, int y, int w, int h, |
317 Boolean exp, XlwScrollBarWidget widget) | 281 Boolean exp, XlwScrollBarWidget widget) |
327 | 291 |
328 #ifdef CHECK_VALUES | 292 #ifdef CHECK_VALUES |
329 static void | 293 static void |
330 check(XlwScrollBarWidget w) | 294 check(XlwScrollBarWidget w) |
331 { | 295 { |
332 int height; | 296 int height = widget_h (w); |
333 | 297 if (w->sb.showArrows) |
334 height= widget_h (w); | 298 height -= (2 * arrow_h (w)); |
335 if (w->sb.showArrows) height -= (2 * arrow_h (w)); | |
336 | 299 |
337 if ((w->sb.above + w->sb.ss + w->sb.below > height) || | 300 if ((w->sb.above + w->sb.ss + w->sb.below > height) || |
338 (w->sb.value < w->sb.minimum) || | 301 (w->sb.value < w->sb.minimum) || |
339 (w->sb.value > w->sb.maximum - w->sb.sliderSize) | 302 (w->sb.value > w->sb.maximum - w->sb.sliderSize)) |
340 ) | |
341 { | 303 { |
342 printf("above=%d ss=%d below=%d height=%d\n", | 304 printf("above=%d ss=%d below=%d height=%d\n", |
343 w->sb.above, w->sb.ss, w->sb.below, height); | 305 w->sb.above, w->sb.ss, w->sb.below, height); |
344 printf("value=%d min=%d max=%d ss=%d max-ss=%d\n", | 306 printf("value=%d min=%d max=%d ss=%d max-ss=%d\n", |
345 w->sb.value, w->sb.minimum, w->sb.maximum, | 307 w->sb.value, w->sb.minimum, w->sb.maximum, |
351 # define CHECK(w) check(w) | 313 # define CHECK(w) check(w) |
352 #else | 314 #else |
353 # define CHECK(w) | 315 # define CHECK(w) |
354 #endif | 316 #endif |
355 | 317 |
356 /************************************************************************ | 318 /*-------------------------- Static functions ---------------------------*/ |
357 ** | |
358 ** Static functions | |
359 ** | |
360 */ | |
361 | 319 |
362 static void | 320 static void |
363 call_callbacks (XlwScrollBarWidget w, int reason, | 321 call_callbacks (XlwScrollBarWidget w, int reason, |
364 int value, int pixel, XEvent *event) | 322 int value, int pixel, XEvent *event) |
365 { | 323 { |
435 cbs.reason = XmCR_VALUE_CHANGED; | 393 cbs.reason = XmCR_VALUE_CHANGED; |
436 XtCallCallbackList ((Widget) w, w->sb.valueChangedCBL, &cbs); | 394 XtCallCallbackList ((Widget) w, w->sb.valueChangedCBL, &cbs); |
437 } | 395 } |
438 } | 396 } |
439 | 397 |
440 /* | 398 /* Widget sizes minus the shadow and highlight area */ |
441 ** Widget sizes minus the shadow and highlight area | 399 |
442 */ | |
443 static int | 400 static int |
444 widget_x (XlwScrollBarWidget w) | 401 widget_x (XlwScrollBarWidget w) |
445 { | 402 { |
446 return w->sb.shadowThickness; | 403 return w->sb.shadowThickness; |
447 } | 404 } |
453 } | 410 } |
454 | 411 |
455 static int | 412 static int |
456 widget_w (XlwScrollBarWidget w) | 413 widget_w (XlwScrollBarWidget w) |
457 { | 414 { |
458 int width, x = w->sb.shadowThickness; | 415 int x = w->sb.shadowThickness; |
459 | 416 int width = (VERT (w) ? w->core.width : w->core.height) - (2 * x); |
460 width = VERT (w) ? w->core.width : w->core.height; | 417 return width > 1 ? width : 1; |
461 | |
462 if (width <= (2 * x)) | |
463 return 1; | |
464 else | |
465 return width - (2 * x); | |
466 } | 418 } |
467 | 419 |
468 static int | 420 static int |
469 widget_h (XlwScrollBarWidget w) | 421 widget_h (XlwScrollBarWidget w) |
470 { | 422 { |
471 int height, y = w->sb.shadowThickness; | 423 int y = w->sb.shadowThickness; |
472 | 424 int height = (VERT (w) ? w->core.height : w->core.width) - (2 * y); |
473 height = VERT (w) ? w->core.height : w->core.width; | 425 |
474 | 426 return height > 1 ? height : 1; |
475 if (height <= (2 * y)) | |
476 return 1; | |
477 else | |
478 return height - (2 * y); | |
479 } | 427 } |
480 | 428 |
481 static int | 429 static int |
482 arrow_h (XlwScrollBarWidget w) | 430 arrow_h (XlwScrollBarWidget w) |
483 { | 431 { |
484 int width, height; | 432 int width = widget_w (w); |
485 | 433 int minimum_size = ((widget_h (w) - SS_MIN) / 2) - 1; |
486 width = widget_w (w); | 434 return minimum_size < width ? minimum_size : width; |
487 height= widget_h (w); | |
488 | |
489 if (width > ((height / 2) - (SS_MIN / 2) - 1)) | |
490 return (height / 2) - (SS_MIN / 2) - 1 ; | |
491 else | |
492 return width; | |
493 } | 435 } |
494 | 436 |
495 static int | 437 static int |
496 event_x (XlwScrollBarWidget w, XEvent *event) | 438 event_x (XlwScrollBarWidget w, XEvent *event) |
497 { | 439 { |
502 event_y (XlwScrollBarWidget w, XEvent *event) | 444 event_y (XlwScrollBarWidget w, XEvent *event) |
503 { | 445 { |
504 return VERT (w) ? event->xbutton.y : event->xbutton.x; | 446 return VERT (w) ? event->xbutton.y : event->xbutton.x; |
505 } | 447 } |
506 | 448 |
507 /* | 449 /* Safe addition and subtraction */ |
508 ** Safe addition and subtraction | 450 static void |
509 */ | 451 increment_value (XlwScrollBarWidget w, int diff) |
510 static int | 452 { |
511 safe_add (int a, int b) | 453 w->sb.value = w->sb.maximum - diff < w->sb.value ? |
512 { | 454 w->sb.maximum : |
513 if (a > 0 && INT_MAX - a < b) return INT_MAX; | 455 w->sb.value + diff; |
514 else return a + b; | 456 } |
515 } | 457 |
516 | 458 static void |
517 static int | 459 decrement_value (XlwScrollBarWidget w, int diff) |
518 safe_subtract (int a, int b) | 460 { |
519 { | 461 w->sb.value = w->sb.minimum + diff > w->sb.value ? |
520 if (a < 0 && -(INT_MIN - a) < b) return INT_MIN; | 462 w->sb.minimum : |
521 else return a - b; | 463 w->sb.value - diff; |
522 } | 464 } |
523 | 465 |
524 static int | 466 static SliderStyle |
525 knob_style (XlwScrollBarWidget w) | 467 slider_style (XlwScrollBarWidget w) |
526 { | 468 { |
527 return w->sb.knobStyle && w->sb.knobStyle[0] == 'd' ? | 469 return w->sb.sliderStyle && w->sb.sliderStyle[0] == 'd' ? |
528 KNOB_DIMPLE : | 470 SLIDER_DIMPLE : |
529 KNOB_PLAIN; | 471 SLIDER_PLAIN; |
530 } | 472 } |
531 | 473 |
532 static Boolean | 474 static Boolean |
533 arrow_same_end (XlwScrollBarWidget w) | 475 arrow_same_end (XlwScrollBarWidget w) |
534 { | 476 { |
535 return w->sb.arrowPosition && w->sb.arrowPosition[0] == 's' ? True : False; | 477 return w->sb.arrowPosition && w->sb.arrowPosition[0] == 's' ? True : False; |
536 } | 478 } |
537 | 479 |
538 /* | 480 /*-------------------------- GC and Pixel allocation --------------------*/ |
539 ** GC and Pixel allocation | |
540 */ | |
541 static GC | 481 static GC |
542 get_gc (XlwScrollBarWidget w, Pixel fg, Pixel bg, Pixmap pm) | 482 get_gc (XlwScrollBarWidget w, Pixel fg, Pixel bg, Pixmap pm) |
543 { | 483 { |
544 XGCValues values; | 484 XGCValues values; |
545 XtGCMask mask; | 485 XtGCMask mask; |
557 | 497 |
558 values.foreground = fg; | 498 values.foreground = fg; |
559 values.background = bg; | 499 values.background = bg; |
560 values.fill_style = FillOpaqueStippled; | 500 values.fill_style = FillOpaqueStippled; |
561 values.stipple = pm; | 501 values.stipple = pm; |
562 mask = GCForeground | GCBackground | | 502 mask = GCForeground | GCBackground | |
563 (pm == None ? 0 : GCStipple | GCFillStyle); | 503 (pm == None ? 0 : GCStipple | GCFillStyle); |
564 return XtGetGC((Widget) w, mask, &values); | 504 return XtGetGC((Widget) w, mask, &values); |
565 } | 505 } |
566 | 506 |
567 /* Replacement for XAllocColor() that tries to return the nearest | 507 /* Replacement for XAllocColor() that tries to return the nearest |
568 available color if the colormap is full. From FSF Emacs. */ | 508 available color if the colormap is full. From FSF Emacs. */ |
714 { | 654 { |
715 /* Assume we're in mono. This code should be okay even if we're | 655 /* Assume we're in mono. This code should be okay even if we're |
716 * really in color but just short on color cells -- We want the | 656 * really in color but just short on color cells -- We want the |
717 * following behavior, which has been empirically determined to | 657 * following behavior, which has been empirically determined to |
718 * work well for all fg/bg combinations in mono: If the trough | 658 * work well for all fg/bg combinations in mono: If the trough |
719 * and thumb are BOTH black, then use a white top shadow and a | 659 * and slider are BOTH black, then use a white top shadow and a |
720 * grey bottom shadow, otherwise use a grey top shadow and a | 660 * grey bottom shadow, otherwise use a grey top shadow and a |
721 * black bottom shadow. | 661 * black bottom shadow. |
722 */ | 662 */ |
723 | 663 |
724 Pixel white = WhitePixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); | 664 Pixel white = WhitePixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); |
725 Pixel black = BlackPixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); | 665 Pixel black = BlackPixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); |
726 | 666 |
727 /* Note: core.background_pixel is the color of the thumb ... */ | 667 /* Note: core.background_pixel is the color of the slider ... */ |
728 | 668 |
729 if (w->core.background_pixel == black && | 669 if (w->core.background_pixel == black && |
730 w->sb.troughColor == black) | 670 w->sb.troughColor == black) |
731 { | 671 { |
732 w->sb.topShadowColor = white; | 672 w->sb.topShadowColor = white; |
757 if (allocate_nearest_color (dpy, cmap, &troughC)) | 697 if (allocate_nearest_color (dpy, cmap, &troughC)) |
758 w->sb.troughColor = troughC.pixel; | 698 w->sb.troughColor = troughC.pixel; |
759 } | 699 } |
760 } | 700 } |
761 | 701 |
762 /* | 702 /*-------------------------- Draw 3D Border -----------------------------*/ |
763 ** Draw 3d border | |
764 */ | |
765 static void | 703 static void |
766 draw_shadows (Display *dpy, Drawable d, GC shine_gc, GC shadow_gc, | 704 draw_shadows (Display *dpy, Drawable d, GC shine_gc, GC shadow_gc, |
767 int x, int y, int width, int height, int shadowT) | 705 int x, int y, int width, int height, int shadowT) |
768 { | 706 { |
769 XSegment shine[10], shadow[10]; | 707 XSegment shine[10], shadow[10]; |
796 | 734 |
797 XDrawSegments (dpy, d, shine_gc, shine, shadowT * 2); | 735 XDrawSegments (dpy, d, shine_gc, shine, shadowT * 2); |
798 XDrawSegments (dpy, d, shadow_gc, shadow, shadowT * 2); | 736 XDrawSegments (dpy, d, shadow_gc, shadow, shadowT * 2); |
799 } | 737 } |
800 | 738 |
801 /* | 739 /*------------------ Draw 3D Arrows: left, up, down, right --------------*/ |
802 ** Draw 3d arrows, left, up, down, and right | |
803 */ | |
804 static int | 740 static int |
805 make_vert_seg (XSegment *seg, int x1, int y1, int x2, int y2, int shadowT) | 741 make_vert_seg (XSegment *seg, int x1, int y1, int x2, int y2, int shadowT) |
806 { | 742 { |
807 int i; | 743 int i; |
808 | 744 |
809 for (i=0; i<shadowT; i++) | 745 for (i=0; i<shadowT; i++, seg++) |
810 { | 746 { |
811 seg[i].x1 = x1; | 747 seg->x1 = x1; |
812 seg[i].y1 = y1 + i; | 748 seg->y1 = y1++; |
813 seg[i].x2 = x2; | 749 seg->x2 = x2; |
814 seg[i].y2 = y2 + i; | 750 seg->y2 = y2++; |
815 } | 751 } |
816 return shadowT; | 752 return shadowT; |
817 } | 753 } |
818 | 754 |
819 static int | 755 static int |
820 make_hor_seg (XSegment *seg, int x1, int y1, int x2, int y2, int shadowT) | 756 make_hor_seg (XSegment *seg, int x1, int y1, int x2, int y2, int shadowT) |
821 { | 757 { |
822 int i; | 758 int i; |
823 | 759 |
824 for (i=0; i<shadowT; i++) | 760 for (i=0; i<shadowT; i++, seg++) |
825 { | 761 { |
826 seg[i].x1 = x1 + i; | 762 seg->x1 = x1++; |
827 seg[i].y1 = y1; | 763 seg->y1 = y1; |
828 seg[i].x2 = x2 + i; | 764 seg->x2 = x2++; |
829 seg[i].y2 = y2; | 765 seg->y2 = y2; |
830 } | 766 } |
831 return shadowT; | 767 return shadowT; |
832 } | 768 } |
833 | 769 |
834 static void | 770 static void |
841 | 777 |
842 mid = width / 2; | 778 mid = width / 2; |
843 | 779 |
844 if (shadowT > (width / 2)) shadowT = (width / 2); | 780 if (shadowT > (width / 2)) shadowT = (width / 2); |
845 if (shadowT > (height / 2)) shadowT = (height / 2); | 781 if (shadowT > (height / 2)) shadowT = (height / 2); |
846 if (shadowT <= 0) shadowT = 0; | 782 if (shadowT < 0) shadowT = 0; |
847 | 783 |
848 /* / */ | 784 /* / */ |
849 make_vert_seg (shine, | 785 make_vert_seg (shine, |
850 x, y + height - shadowT - 1, | 786 x, y + height - shadowT - 1, |
851 x + mid, y, shadowT); | 787 x + mid, y, shadowT); |
852 /* _\ */ | 788 /* _\ */ |
853 make_vert_seg (shadow, | 789 make_vert_seg (shadow, |
854 x, y + height - shadowT - 1, | 790 x, y + height - shadowT - 1, |
855 x + width - 1, y + height - shadowT - 1, shadowT); | 791 x + width - 1, y + height - shadowT - 1, shadowT); |
856 make_vert_seg (shadow + shadowT, | 792 make_vert_seg (shadow + shadowT, |
857 x + mid, y, | 793 x + mid, y, |
858 x + width - 1, y + height - shadowT - 1, shadowT); | 794 x + width - 1, y + height - shadowT - 1, shadowT); |
859 | 795 |
860 triangle[0].x = x; | 796 triangle[0].x = x; |
861 triangle[0].y = y + height - 1; | 797 triangle[0].y = y + height - 1; |
862 triangle[1].x = x + mid; | 798 triangle[1].x = x + mid; |
874 draw_arrow_left (Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC, | 810 draw_arrow_left (Display *dpy, Drawable win, GC bgGC, GC shineGC, GC shadowGC, |
875 int x, int y, int width, int height, int shadowT) | 811 int x, int y, int width, int height, int shadowT) |
876 { | 812 { |
877 XSegment shine[10], shadow[10]; | 813 XSegment shine[10], shadow[10]; |
878 XPoint triangle[3]; | 814 XPoint triangle[3]; |
879 int mid; | 815 |
880 | 816 int mid = width / 2; |
881 mid = width / 2; | |
882 | 817 |
883 if (shadowT > (width / 2)) shadowT = (width / 2); | 818 if (shadowT > (width / 2)) shadowT = (width / 2); |
884 if (shadowT > (height / 2)) shadowT = (height / 2); | 819 if (shadowT > (height / 2)) shadowT = (height / 2); |
885 if (shadowT <= 0) shadowT = 0; | 820 if (shadowT < 0) shadowT = 0; |
886 | 821 |
887 /* / */ | 822 /* / */ |
888 make_hor_seg (shine, | 823 make_hor_seg (shine, |
889 x, y + mid, | 824 x, y + mid, |
890 x + width - shadowT - 1, y, shadowT); | 825 x + width - shadowT - 1, y, shadowT); |
891 /* \| */ | 826 /* \| */ |
892 make_hor_seg (shadow, | 827 make_hor_seg (shadow, |
893 x, y + mid, | 828 x, y + mid, |
894 x + width - shadowT - 1, y + height - 1, shadowT); | 829 x + width - shadowT - 1, y + height - 1, shadowT); |
895 make_hor_seg (shadow + shadowT, | 830 make_hor_seg (shadow + shadowT, |
896 x + width - shadowT - 1, y, | 831 x + width - shadowT - 1, y, |
897 x + width - shadowT - 1, y + height - 1, shadowT); | 832 x + width - shadowT - 1, y + height - 1, shadowT); |
898 | 833 |
919 | 854 |
920 mid = width / 2; | 855 mid = width / 2; |
921 | 856 |
922 if (shadowT > (width / 2)) shadowT = (width / 2); | 857 if (shadowT > (width / 2)) shadowT = (width / 2); |
923 if (shadowT > (height / 2)) shadowT = (height / 2); | 858 if (shadowT > (height / 2)) shadowT = (height / 2); |
924 if (shadowT <= 0) shadowT = 0; | 859 if (shadowT < 0) shadowT = 0; |
925 | 860 |
926 /* \- */ | 861 /* \- */ |
927 make_vert_seg (shine, | 862 make_vert_seg (shine, |
928 x, y, | 863 x, y, |
929 x + mid, y + height - shadowT - 1, shadowT); | 864 x + mid, y + height - shadowT - 1, shadowT); |
930 make_vert_seg (shine + shadowT, | 865 make_vert_seg (shine + shadowT, |
931 x, y, | 866 x, y, |
932 x + width - 1, y, shadowT); | 867 x + width - 1, y, shadowT); |
933 /* / */ | 868 /* / */ |
934 make_vert_seg (shadow, | 869 make_vert_seg (shadow, |
935 x + width - 1, y, | 870 x + width - 1, y, |
936 x + mid, y + height - shadowT - 1, shadowT); | 871 x + mid, y + height - shadowT - 1, shadowT); |
937 | 872 |
938 triangle[0].x = x; | 873 triangle[0].x = x; |
939 triangle[0].y = y; | 874 triangle[0].y = y; |
940 triangle[1].x = x + mid; | 875 triangle[1].x = x + mid; |
941 triangle[1].y = y + height - 1; | 876 triangle[1].y = y + height - 1; |
958 | 893 |
959 mid = width / 2; | 894 mid = width / 2; |
960 | 895 |
961 if (shadowT > (width / 2)) shadowT = (width / 2); | 896 if (shadowT > (width / 2)) shadowT = (width / 2); |
962 if (shadowT > (height / 2)) shadowT = (height / 2); | 897 if (shadowT > (height / 2)) shadowT = (height / 2); |
963 if (shadowT <= 0) shadowT = 0; | 898 if (shadowT < 0) shadowT = 0; |
964 | 899 |
965 /* |\ */ | 900 /* |\ */ |
966 make_hor_seg (shine, | 901 make_hor_seg (shine, |
967 x, y, | 902 x, y, |
968 x + width - shadowT - 1, y + mid, shadowT); | 903 x + width - shadowT - 1, y + mid, shadowT); |
969 make_hor_seg (shine + shadowT, | 904 make_hor_seg (shine + shadowT, |
970 x, y, | 905 x, y, |
971 x, y + height -1, shadowT); | 906 x, y + height - 1, shadowT); |
972 /* / */ | 907 /* / */ |
973 make_hor_seg (shadow, | 908 make_hor_seg (shadow, |
974 x, y + height -1, | 909 x, y + height - 1, |
975 x + width - shadowT - 1, y + mid, shadowT); | 910 x + width - shadowT - 1, y + mid, shadowT); |
976 | 911 |
977 triangle[0].x = x + 1; | 912 triangle[0].x = x + 1; |
978 triangle[0].y = y + height - 1; | 913 triangle[0].y = y + height - 1; |
979 triangle[1].x = x + width - 1; | 914 triangle[1].x = x + width - 1; |
980 triangle[1].y = y + mid; | 915 triangle[1].y = y + mid; |
981 triangle[2].x = x + 1; | 916 triangle[2].x = x + 1; |
982 triangle[2].y = y; | 917 triangle[2].y = y; |
983 | 918 |
984 XFillPolygon (dpy, win, bgGC, triangle, 3, Convex, ArcChord); | 919 XFillPolygon (dpy, win, bgGC, triangle, 3, Convex, ArcChord); |
993 { | 928 { |
994 XDrawArc (dpy, win, shine, x, y, width, height, 46*64, 180*64); | 929 XDrawArc (dpy, win, shine, x, y, width, height, 46*64, 180*64); |
995 XDrawArc (dpy, win, shadow, x, y, width, height, 45*64, -179*64); | 930 XDrawArc (dpy, win, shadow, x, y, width, height, 45*64, -179*64); |
996 } | 931 } |
997 | 932 |
998 /* | 933 /*------- Scrollbar values -> pixels, pixels -> scrollbar values --------*/ |
999 ** Scrollbar values -> pixels, pixels -> scrollbar values | |
1000 */ | |
1001 | 934 |
1002 static void | 935 static void |
1003 seg_pixel_sizes (XlwScrollBarWidget w, int *above_return, | 936 seg_pixel_sizes (XlwScrollBarWidget w, int *above_return, |
1004 int *ss_return, int *below_return) | 937 int *ss_return, int *below_return) |
1005 { | 938 { |
1017 | 950 |
1018 ss = ((height * w->sb.sliderSize + fuz) / total); | 951 ss = ((height * w->sb.sliderSize + fuz) / total); |
1019 above = ((height * value + fuz) / total); | 952 above = ((height * value + fuz) / total); |
1020 below = ((height) - (ss + above)); | 953 below = ((height) - (ss + above)); |
1021 | 954 |
1022 /* Dont' let knob get smaller than SS_MIN */ | 955 /* Don't let slider get smaller than SS_MIN */ |
1023 if (ss < SS_MIN) | 956 if (ss < SS_MIN) |
1024 { | 957 { |
1025 /* add a percent amount for integer rounding */ | 958 /* add a percent amount for integer rounding */ |
1026 float tmp = ((((float) (SS_MIN - ss) * (float) value)) / total) + 0.5; | 959 float tmp = ((((float) (SS_MIN - ss) * (float) value)) / total) + 0.5; |
1027 | 960 |
1028 above -= (int) tmp; | 961 above -= (int) tmp; |
1029 ss = SS_MIN; | 962 ss = SS_MIN; |
1030 below = ((height) - (ss + above)); | 963 below = ((height) - (ss + above)); |
1031 | 964 |
1032 if (above < 0) | 965 if (above < 0) |
1033 { | 966 { |
1034 above = 0; | 967 above = 0; |
1069 w->sb.increment = total; | 1002 w->sb.increment = total; |
1070 | 1003 |
1071 if (w->sb.value < w->sb.minimum) | 1004 if (w->sb.value < w->sb.minimum) |
1072 w->sb.value = w->sb.minimum; | 1005 w->sb.value = w->sb.minimum; |
1073 | 1006 |
1074 if (w->sb.value > w->sb.maximum - w->sb.sliderSize) | 1007 if (w->sb.value > w->sb.maximum) |
1075 w->sb.value = w->sb.maximum - w->sb.sliderSize; | 1008 w->sb.value = w->sb.maximum; |
1009 | |
1010 if (w->sb.sliderSize > w->sb.maximum - w->sb.value) | |
1011 w->sb.sliderSize = w->sb.maximum - w->sb.value; | |
1076 } | 1012 } |
1077 | 1013 |
1078 static int | 1014 static int |
1079 value_from_pixel (XlwScrollBarWidget w, int above) | 1015 value_from_pixel (XlwScrollBarWidget w, int above) |
1080 { | 1016 { |
1081 float total, height, fuz; | 1017 float total, height, fuz; |
1082 int value, ss; | 1018 int value, ss; |
1083 | 1019 |
1084 height= widget_h (w); | 1020 height = widget_h (w); |
1085 if (w->sb.showArrows) height -= (2 * arrow_h (w)); | 1021 if (w->sb.showArrows) |
1022 height -= (2 * arrow_h (w)); | |
1086 | 1023 |
1087 total = w->sb.maximum - w->sb.minimum; | 1024 total = w->sb.maximum - w->sb.minimum; |
1088 fuz = height / 2; | 1025 fuz = height / 2; |
1089 | 1026 |
1090 ss = ((height * w->sb.sliderSize + (total / 2)) / total); | 1027 ss = ((height * w->sb.sliderSize + (total / 2)) / total); |
1112 | 1049 |
1113 static void | 1050 static void |
1114 redraw_dimple (XlwScrollBarWidget w, Display *dpy, Window win, | 1051 redraw_dimple (XlwScrollBarWidget w, Display *dpy, Window win, |
1115 int x, int y, int width, int height) | 1052 int x, int y, int width, int height) |
1116 { | 1053 { |
1117 GC shine, shadow; | 1054 if (SLIDER_DIMPLE == slider_style (w)) |
1118 int shadowT, size; | 1055 { |
1119 | 1056 int size; |
1120 if (KNOB_DIMPLE == knob_style (w)) | 1057 int slider_p = (w->sb.armed == ARM_SLIDER); |
1121 { | 1058 GC shine = slider_p ? w->sb.bottomShadowGC : w->sb.topShadowGC; |
1122 if (w->sb.armed == ARM_KNOB) | 1059 GC shadow = slider_p ? w->sb.topShadowGC : w->sb.bottomShadowGC; |
1123 { | 1060 int shadowT = w->sb.shadowThickness; |
1124 shine = w->sb.bottomShadowGC; | |
1125 shadow = w->sb.topShadowGC; | |
1126 } | |
1127 else | |
1128 { | |
1129 shine = w->sb.topShadowGC; | |
1130 shadow = w->sb.bottomShadowGC; | |
1131 } | |
1132 | |
1133 shadowT = w->sb.shadowThickness; | |
1134 | 1061 |
1135 x += shadowT; | 1062 x += shadowT; |
1136 y += shadowT; | 1063 y += shadowT; |
1137 width -= 2*shadowT; | 1064 width -= 2*shadowT; |
1138 height -= 2*shadowT; | 1065 height -= 2*shadowT; |
1151 size, size); | 1078 size, size); |
1152 } | 1079 } |
1153 } | 1080 } |
1154 | 1081 |
1155 static void | 1082 static void |
1156 draw_knob (XlwScrollBarWidget w, int above, int ss, int below) | 1083 draw_slider (XlwScrollBarWidget w, int above, int ss, int below) |
1157 { | 1084 { |
1158 Display *dpy = XtDisplay ((Widget) w); | 1085 Display *dpy = XtDisplay ((Widget) w); |
1159 Window win = XtWindow ((Widget) w); | 1086 Window win = XtWindow ((Widget) w); |
1160 int x, y, width, height; | 1087 |
1161 int shadowT; | 1088 int x = widget_x (w); |
1162 | 1089 int y = widget_y (w); |
1163 x = widget_x (w); | 1090 int width = widget_w (w); |
1164 y = widget_y (w); | 1091 int height = widget_h (w); |
1165 width = widget_w (w); | 1092 int shadowT = w->sb.shadowThickness; |
1166 height = widget_h (w); | 1093 int vert_p = VERT (w); |
1167 | |
1168 shadowT = w->sb.shadowThickness; | |
1169 | 1094 |
1170 if (shadowT > (width / 2)) shadowT = (width / 2); | 1095 if (shadowT > (width / 2)) shadowT = (width / 2); |
1171 if (shadowT > (height / 2)) shadowT = (height / 2); | 1096 if (shadowT > (height / 2)) shadowT = (height / 2); |
1172 if (shadowT <= 0) return; | 1097 if (shadowT < 0) shadowT = 0; |
1173 | 1098 |
1174 if (w->sb.showArrows && !arrow_same_end (w)) y += arrow_h (w); | 1099 if (w->sb.showArrows && !arrow_same_end (w)) |
1175 | 1100 y += arrow_h (w); |
1176 /* trough above knob */ | 1101 |
1102 /* trough above slider */ | |
1177 if (above > 0) | 1103 if (above > 0) |
1178 { | 1104 { |
1179 if (VERT (w)) | 1105 if (vert_p) |
1180 XClearArea (dpy, win, x, y, width, above, False); | 1106 XClearArea (dpy, win, x, y, width, above, False); |
1181 else | 1107 else |
1182 XClearArea (dpy, win, y, x, above, width, False); | 1108 XClearArea (dpy, win, y, x, above, width, False); |
1183 } | 1109 } |
1184 | 1110 |
1185 /* knob */ | 1111 /* slider */ |
1186 if (VERT (w)) | 1112 if (vert_p) |
1187 { | 1113 { |
1188 draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, | 1114 draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, |
1189 x, y + above, width, ss, shadowT); | 1115 x, y + above, width, ss, shadowT); |
1190 XFillRectangle (dpy, win, | 1116 XFillRectangle (dpy, win, w->sb.backgroundGC, |
1191 w->sb.backgroundGC, | 1117 x+shadowT, y + above + shadowT, |
1192 x+shadowT, y + above + shadowT, width-2*shadowT, ss-2*shadowT); | 1118 width-2*shadowT, ss-2*shadowT); |
1193 redraw_dimple (w, dpy, win, x, y + above, width, ss); | 1119 redraw_dimple (w, dpy, win, x, y + above, width, ss); |
1194 } | 1120 } |
1195 else | 1121 else |
1196 { | 1122 { |
1197 draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, | 1123 draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, |
1198 y + above, x, ss, width, shadowT); | 1124 y + above, x, ss, width, shadowT); |
1199 XFillRectangle (dpy, win, | 1125 XFillRectangle (dpy, win, w->sb.backgroundGC, |
1200 w->sb.backgroundGC, | 1126 y + above + shadowT, x+shadowT, |
1201 y + above + shadowT, x+shadowT, ss-2*shadowT, width-2*shadowT); | 1127 ss-2*shadowT, width-2*shadowT); |
1202 redraw_dimple (w, dpy, win, y + above, x, ss, width); | 1128 redraw_dimple (w, dpy, win, y + above, x, ss, width); |
1203 } | 1129 } |
1204 | 1130 |
1205 /* trough below knob */ | 1131 /* trough below slider */ |
1206 if (below > 0) | 1132 if (below > 0) |
1207 { | 1133 { |
1208 if (VERT (w)) | 1134 if (vert_p) |
1209 XClearArea (dpy, win, x, y + above + ss, width, below, False); | 1135 XClearArea (dpy, win, x, y + above + ss, width, below, False); |
1210 else | 1136 else |
1211 XClearArea (dpy, win, y + above + ss, x, below, width, False); | 1137 XClearArea (dpy, win, y + above + ss, x, below, width, False); |
1212 } | 1138 } |
1213 | 1139 |
1217 static void | 1143 static void |
1218 redraw_up_arrow (XlwScrollBarWidget w, Boolean armed, Boolean clear_behind) | 1144 redraw_up_arrow (XlwScrollBarWidget w, Boolean armed, Boolean clear_behind) |
1219 { | 1145 { |
1220 Display *dpy = XtDisplay ((Widget) w); | 1146 Display *dpy = XtDisplay ((Widget) w); |
1221 Window win = XtWindow ((Widget) w); | 1147 Window win = XtWindow ((Widget) w); |
1222 GC bg, shine, shadow; | 1148 |
1223 int x, y, width, height, arrow_height, shadowT; | 1149 int x = widget_x (w); |
1224 | 1150 int y = widget_y (w); |
1225 x = widget_x (w); | 1151 int width = widget_w (w); |
1226 y = widget_y (w); | 1152 int height = widget_h (w); |
1227 width = widget_w (w); | 1153 int shadowT = w->sb.shadowThickness; |
1228 height = widget_h (w); | 1154 int arrow_height = arrow_h (w); |
1229 arrow_height = arrow_h (w); | 1155 |
1230 | 1156 GC bg = w->sb.backgroundGC; |
1231 shadowT = w->sb.shadowThickness; | 1157 GC shine = armed ? w->sb.bottomShadowGC : w->sb.topShadowGC; |
1232 bg = w->sb.backgroundGC; | 1158 GC shadow = armed ? w->sb.topShadowGC : w->sb.bottomShadowGC; |
1233 | |
1234 if (armed) | |
1235 { | |
1236 shine = w->sb.bottomShadowGC; | |
1237 shadow = w->sb.topShadowGC; | |
1238 } | |
1239 else | |
1240 { | |
1241 shine = w->sb.topShadowGC; | |
1242 shadow = w->sb.bottomShadowGC; | |
1243 } | |
1244 | 1159 |
1245 if (VERT (w)) | 1160 if (VERT (w)) |
1246 { | 1161 { |
1247 if (arrow_same_end (w)) | 1162 if (arrow_same_end (w)) |
1248 { | 1163 y += height - 2 * arrow_height; |
1249 y += height - 2 * arrow_h (w) + 2; | |
1250 } | |
1251 if (clear_behind) | 1164 if (clear_behind) |
1252 XClearArea (dpy, win, x, y, width, arrow_height + 1, False); | 1165 XClearArea (dpy, win, x, y, width, arrow_height + 1, False); |
1253 draw_arrow_up (dpy, win, bg, shine, shadow, | 1166 draw_arrow_up (dpy, win, bg, shine, shadow, |
1254 x + (width - arrow_height)/2, y, | 1167 x + (width - arrow_height)/2, y, |
1255 arrow_height, arrow_height, shadowT); | 1168 arrow_height, arrow_height, shadowT); |
1256 } | 1169 } |
1257 else | 1170 else |
1258 { | 1171 { |
1259 if (arrow_same_end (w)) | 1172 if (arrow_same_end (w)) |
1260 { | 1173 y += height - 2 * arrow_height; |
1261 y += height - 2 * arrow_h (w); | |
1262 } | |
1263 if (clear_behind) | 1174 if (clear_behind) |
1264 XClearArea (dpy, win, y, x, arrow_height + 1, height, False); | 1175 XClearArea (dpy, win, y, x, arrow_height + 1, height, False); |
1265 draw_arrow_left (dpy, win, bg, shine, shadow, | 1176 draw_arrow_left (dpy, win, bg, shine, shadow, |
1266 y, x + (width - arrow_height)/2, | 1177 y, x + (width - arrow_height)/2, |
1267 arrow_height, arrow_height, shadowT); | 1178 arrow_height, arrow_height, shadowT); |
1271 static void | 1182 static void |
1272 redraw_down_arrow (XlwScrollBarWidget w, Boolean armed, Boolean clear_behind) | 1183 redraw_down_arrow (XlwScrollBarWidget w, Boolean armed, Boolean clear_behind) |
1273 { | 1184 { |
1274 Display *dpy = XtDisplay ((Widget) w); | 1185 Display *dpy = XtDisplay ((Widget) w); |
1275 Window win = XtWindow ((Widget) w); | 1186 Window win = XtWindow ((Widget) w); |
1276 GC bg, shine, shadow; | 1187 |
1277 int x, y, width, height, arrow_height, shadowT; | 1188 int x = widget_x (w); |
1278 | 1189 int y = widget_y (w); |
1279 x = widget_x (w); | 1190 int width = widget_w (w); |
1280 y = widget_y (w); | 1191 int height = widget_h (w); |
1281 width = widget_w (w); | 1192 int shadowT = w->sb.shadowThickness; |
1282 height = widget_h (w); | 1193 int arrow_height = arrow_h (w); |
1283 arrow_height = arrow_h (w); | 1194 |
1284 | 1195 GC bg = w->sb.backgroundGC; |
1285 shadowT = w->sb.shadowThickness; | 1196 GC shine = armed ? w->sb.bottomShadowGC : w->sb.topShadowGC; |
1286 bg = w->sb.backgroundGC; | 1197 GC shadow = armed ? w->sb.topShadowGC : w->sb.bottomShadowGC; |
1287 | |
1288 if (armed) | |
1289 { | |
1290 shine = w->sb.bottomShadowGC; | |
1291 shadow = w->sb.topShadowGC; | |
1292 } | |
1293 else | |
1294 { | |
1295 shine = w->sb.topShadowGC; | |
1296 shadow = w->sb.bottomShadowGC; | |
1297 } | |
1298 | 1198 |
1299 if (VERT (w)) | 1199 if (VERT (w)) |
1300 { | 1200 { |
1301 if (clear_behind) | 1201 if (clear_behind) |
1302 XClearArea (dpy, win, x, y + height - arrow_height, width, | 1202 XClearArea (dpy, win, x, y + height - arrow_height, width, |
1321 static void | 1221 static void |
1322 redraw_everything (XlwScrollBarWidget w, Region region, Boolean behind_arrows) | 1222 redraw_everything (XlwScrollBarWidget w, Region region, Boolean behind_arrows) |
1323 { | 1223 { |
1324 Display *dpy = XtDisplay ((Widget) w); | 1224 Display *dpy = XtDisplay ((Widget) w); |
1325 Window win = XtWindow ((Widget) w); | 1225 Window win = XtWindow ((Widget) w); |
1326 int x, y, width, height, shadowT, tmp; | |
1327 | |
1328 x = widget_x (w); | |
1329 y = widget_y (w); | |
1330 width = widget_w (w); | |
1331 height = widget_h (w); | |
1332 shadowT = w->sb.shadowThickness; | |
1333 | 1226 |
1334 if (w->sb.showArrows) | 1227 if (w->sb.showArrows) |
1335 { | 1228 { |
1336 if (region == NULL || XRectInRegion (region, x, y, width, width)) | 1229 if (region == NULL) |
1337 { | 1230 { |
1338 redraw_up_arrow (w, False, behind_arrows); | 1231 redraw_up_arrow (w, False, behind_arrows); |
1339 } | 1232 redraw_down_arrow (w, False, behind_arrows); |
1340 if (VERT (w)) | |
1341 { | |
1342 y = y + height - width + 1; | |
1343 } | 1233 } |
1344 else | 1234 else |
1345 { | 1235 { |
1346 tmp = y; | 1236 int x = widget_x (w); |
1347 y = x; | 1237 int y = widget_y (w); |
1348 x = tmp + height - width + 1; | 1238 int width = widget_w (w); |
1349 } | 1239 int height = widget_h (w); |
1350 if (region == NULL || XRectInRegion (region, x, y, width, width)) | 1240 int arrow_height = arrow_h (w); |
1351 { | 1241 int ax = x, ay = y; |
1352 redraw_down_arrow (w, False, behind_arrows); | 1242 |
1353 } | 1243 if (arrow_same_end (w)) |
1354 } | 1244 { |
1355 | 1245 if (VERT (w)) |
1356 draw_shadows (dpy, win, w->sb.bottomShadowGC, w->sb.topShadowGC, | 1246 ay = y + height - arrow_height - arrow_height; |
1357 0, 0, w->core.width, w->core.height, shadowT); | 1247 else |
1358 | 1248 ax = x + height - arrow_height - arrow_height; |
1359 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1249 } |
1360 | 1250 if (XRectInRegion (region, ax, ay, width, width)) |
1361 } | 1251 redraw_up_arrow (w, False, behind_arrows); |
1362 | 1252 |
1363 /************************************************************************ | 1253 if (VERT (w)) |
1364 ** | 1254 ay = y + height - arrow_height; |
1365 ** Method functions | 1255 else |
1366 ** | 1256 ax = x + height - arrow_height; |
1367 */ | 1257 if (XRectInRegion (region, ax, ay, width, width)) |
1258 redraw_down_arrow (w, False, behind_arrows); | |
1259 } | |
1260 } | |
1261 | |
1262 draw_shadows (dpy, win, w->sb.bottomShadowGC, w->sb.topShadowGC, 0, 0, | |
1263 w->core.width, w->core.height, w->sb.shadowThickness); | |
1264 | |
1265 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); | |
1266 } | |
1267 | |
1268 /*-------------------------- Method Functions ---------------------------*/ | |
1368 | 1269 |
1369 static void | 1270 static void |
1370 Initialize (Widget treq, Widget tnew, ArgList args, Cardinal *num_args) | 1271 Initialize (Widget treq, Widget tnew, ArgList args, Cardinal *num_args) |
1371 { | 1272 { |
1372 XlwScrollBarWidget request = (XlwScrollBarWidget) treq; | 1273 XlwScrollBarWidget request = (XlwScrollBarWidget) treq; |
1373 XlwScrollBarWidget w = (XlwScrollBarWidget) tnew; | 1274 XlwScrollBarWidget w = (XlwScrollBarWidget) tnew; |
1374 Display *dpy = XtDisplay ((Widget) w); | 1275 Display *dpy = XtDisplay ((Widget) w); |
1375 Window win = RootWindowOfScreen (DefaultScreenOfDisplay (dpy)); | 1276 Window win = RootWindowOfScreen (DefaultScreenOfDisplay (dpy)); |
1376 | |
1377 DBUG (fprintf (stderr, "Initialize\n")); | |
1378 | 1277 |
1379 if (request->core.width == 0) w->core.width += (VERT (w) ? 12 : 25); | 1278 if (request->core.width == 0) w->core.width += (VERT (w) ? 12 : 25); |
1380 if (request->core.height == 0) w->core.height += (VERT (w) ? 25 : 12); | 1279 if (request->core.height == 0) w->core.height += (VERT (w) ? 25 : 12); |
1381 | 1280 |
1382 verify_values (w); | 1281 verify_values (w); |
1384 w->sb.lastY = 0; | 1283 w->sb.lastY = 0; |
1385 w->sb.above = 0; | 1284 w->sb.above = 0; |
1386 w->sb.ss = 0; | 1285 w->sb.ss = 0; |
1387 w->sb.below = 0; | 1286 w->sb.below = 0; |
1388 w->sb.armed = ARM_NONE; | 1287 w->sb.armed = ARM_NONE; |
1288 w->sb.forced_scroll = FORCED_SCROLL_NONE; | |
1389 | 1289 |
1390 if (w->sb.shadowThickness > 5) w->sb.shadowThickness = 5; | 1290 if (w->sb.shadowThickness > 5) w->sb.shadowThickness = 5; |
1391 | 1291 |
1392 w->sb.grayPixmap = | 1292 w->sb.grayPixmap = |
1393 XCreatePixmapFromBitmapData (dpy, win, (char *) gray_bits, gray_width, | 1293 XCreatePixmapFromBitmapData (dpy, win, (char *) gray_bits, gray_width, |
1415 Destroy (Widget widget) | 1315 Destroy (Widget widget) |
1416 { | 1316 { |
1417 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1317 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
1418 Display *dpy = XtDisplay ((Widget) w); | 1318 Display *dpy = XtDisplay ((Widget) w); |
1419 | 1319 |
1420 DBUG (fprintf (stderr, "Destroy\n")); | |
1421 | |
1422 XtReleaseGC (widget, w->sb.bottomShadowGC); | 1320 XtReleaseGC (widget, w->sb.bottomShadowGC); |
1423 XtReleaseGC (widget, w->sb.topShadowGC); | 1321 XtReleaseGC (widget, w->sb.topShadowGC); |
1424 XtReleaseGC (widget, w->sb.backgroundGC); | 1322 XtReleaseGC (widget, w->sb.backgroundGC); |
1425 | 1323 |
1426 XFreePixmap (dpy, w->sb.grayPixmap); | 1324 XFreePixmap (dpy, w->sb.grayPixmap); |
1427 | 1325 |
1428 if (w->sb.timerActive) | 1326 if (w->sb.timerActive) |
1429 XtRemoveTimeOut (w->sb.timerId); | 1327 { |
1328 XtRemoveTimeOut (w->sb.timerId); | |
1329 w->sb.timerActive = False; /* Should be a no-op, but you never know */ | |
1330 } | |
1430 } | 1331 } |
1431 | 1332 |
1432 static void | 1333 static void |
1433 Realize (Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr) | 1334 Realize (Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr) |
1434 { | 1335 { |
1435 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1336 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
1436 Display *dpy = XtDisplay ((Widget) w); | 1337 Display *dpy = XtDisplay ((Widget) w); |
1437 Window win; | 1338 Window win; |
1438 XSetWindowAttributes win_attr; | 1339 XSetWindowAttributes win_attr; |
1439 | 1340 |
1440 DBUG (fprintf (stderr, "Realize\n")); | |
1441 | |
1442 (*coreClassRec.core_class.realize)(widget, valuemask, attr); | 1341 (*coreClassRec.core_class.realize)(widget, valuemask, attr); |
1443 | 1342 |
1444 win = XtWindow ((Widget) w); | 1343 win = XtWindow ((Widget) w); |
1445 | 1344 |
1446 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); | 1345 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); |
1447 | 1346 |
1448 XSetWindowBackground (dpy, win, w->sb.troughColor); | 1347 XSetWindowBackground (dpy, win, w->sb.troughColor); |
1449 | 1348 |
1450 /* Change bit gravity so widget is not cleared on resize */ | 1349 /* Change bit gravity so widget is not cleared on resize */ |
1451 win_attr.bit_gravity = NorthWestGravity; | 1350 win_attr.bit_gravity = NorthWestGravity; |
1452 XChangeWindowAttributes (dpy, win, CWBitGravity , &win_attr); | 1351 XChangeWindowAttributes (dpy, win, CWBitGravity , &win_attr); |
1453 | 1352 |
1454 } | 1353 } |
1455 | 1354 |
1456 static void | 1355 static void |
1464 { | 1363 { |
1465 DBUG (fprintf (stderr, "Resize = %08lx\n", w)); | 1364 DBUG (fprintf (stderr, "Resize = %08lx\n", w)); |
1466 | 1365 |
1467 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); | 1366 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); |
1468 | 1367 |
1469 /*redraw_everything(w, NULL, True);*/ | 1368 /* redraw_everything (w, NULL, True); */ |
1470 | 1369 |
1471 w->sb.fullRedrawNext = True; | 1370 w->sb.fullRedrawNext = True; |
1472 /* Force expose event */ | 1371 /* Force expose event */ |
1473 XClearArea (dpy, win, widget_x(w), widget_y(w), 1, 1, True); | 1372 XClearArea (dpy, win, widget_x (w), widget_y (w), 1, 1, True); |
1373 } | |
1374 | |
1375 if (w->sb.timerActive) | |
1376 { | |
1377 XtRemoveTimeOut (w->sb.timerId); | |
1378 w->sb.timerActive = False; | |
1474 } | 1379 } |
1475 } | 1380 } |
1476 | 1381 |
1477 static void | 1382 static void |
1478 Redisplay (Widget widget, XEvent *event, Region region) | 1383 Redisplay (Widget widget, XEvent *event, Region region) |
1482 DBUG (fprintf (stderr, "Redisplay = %08lx\n", w)); | 1387 DBUG (fprintf (stderr, "Redisplay = %08lx\n", w)); |
1483 | 1388 |
1484 if (XtIsRealized (widget)) | 1389 if (XtIsRealized (widget)) |
1485 { | 1390 { |
1486 if (w->sb.fullRedrawNext) | 1391 if (w->sb.fullRedrawNext) |
1487 { | 1392 redraw_everything (w, NULL, True); |
1488 redraw_everything (w, NULL, True); | |
1489 } | |
1490 else | 1393 else |
1491 { | 1394 redraw_everything (w, region, False); |
1492 redraw_everything (w, region, False); | |
1493 } | |
1494 w->sb.fullRedrawNext = False; | 1395 w->sb.fullRedrawNext = False; |
1495 } | 1396 } |
1496 } | 1397 } |
1497 | 1398 |
1498 static Boolean | 1399 static Boolean |
1540 w->sb.bottomShadowPixmap); | 1441 w->sb.bottomShadowPixmap); |
1541 do_redisplay = True; | 1442 do_redisplay = True; |
1542 } | 1443 } |
1543 | 1444 |
1544 if (cur->sb.orientation != w->sb.orientation) | 1445 if (cur->sb.orientation != w->sb.orientation) |
1545 { | 1446 do_redisplay = True; |
1546 do_redisplay = True; | |
1547 } | |
1548 | 1447 |
1549 | 1448 |
1550 if (cur->sb.minimum != w->sb.minimum || | 1449 if (cur->sb.minimum != w->sb.minimum || |
1551 cur->sb.maximum != w->sb.maximum || | 1450 cur->sb.maximum != w->sb.maximum || |
1552 cur->sb.sliderSize != w->sb.sliderSize || | 1451 cur->sb.sliderSize != w->sb.sliderSize || |
1556 { | 1455 { |
1557 verify_values (w); | 1456 verify_values (w); |
1558 if (XtIsRealized ((Widget) w)) | 1457 if (XtIsRealized ((Widget) w)) |
1559 { | 1458 { |
1560 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); | 1459 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); |
1561 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1460 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
1562 } | 1461 } |
1563 } | 1462 } |
1564 | 1463 |
1565 if (w->sb.shadowThickness > 5) w->sb.shadowThickness = 5; | 1464 if (w->sb.shadowThickness > 5) w->sb.shadowThickness = 5; |
1566 | 1465 |
1585 void | 1484 void |
1586 XlwScrollBarSetValues (Widget widget, int value, int sliderSize, | 1485 XlwScrollBarSetValues (Widget widget, int value, int sliderSize, |
1587 int increment, int pageIncrement, Boolean notify) | 1486 int increment, int pageIncrement, Boolean notify) |
1588 { | 1487 { |
1589 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1488 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
1590 int last_value; | |
1591 | 1489 |
1592 if (w && XtClass ((Widget) w) == xlwScrollBarWidgetClass && | 1490 if (w && XtClass ((Widget) w) == xlwScrollBarWidgetClass && |
1593 (w->sb.value != value || | 1491 (w->sb.value != value || |
1594 w->sb.sliderSize != sliderSize || | 1492 w->sb.sliderSize != sliderSize || |
1595 w->sb.increment != increment || | 1493 w->sb.increment != increment || |
1596 w->sb.pageIncrement != pageIncrement)) | 1494 w->sb.pageIncrement != pageIncrement)) |
1597 { | 1495 { |
1496 int last_value = w->sb.value; | |
1497 | |
1598 w->sb.value = value; | 1498 w->sb.value = value; |
1599 w->sb.sliderSize = sliderSize; | 1499 w->sb.sliderSize = sliderSize; |
1600 w->sb.increment = increment; | 1500 w->sb.increment = increment; |
1601 w->sb.pageIncrement = pageIncrement; | 1501 w->sb.pageIncrement = pageIncrement; |
1602 | 1502 |
1603 verify_values (w); | 1503 verify_values (w); |
1604 | 1504 |
1605 if (XtIsRealized (widget)) | 1505 if (XtIsRealized (widget)) |
1606 { | 1506 { |
1607 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); | 1507 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); |
1608 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1508 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
1609 | |
1610 last_value = w->sb.value; | |
1611 w->sb.value = value_from_pixel (w, w->sb.above); | |
1612 verify_values (w); | |
1613 | 1509 |
1614 if (w->sb.value != last_value && notify) | 1510 if (w->sb.value != last_value && notify) |
1615 { | 1511 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, 0, NULL); |
1616 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, 0, NULL); | 1512 } |
1617 } | 1513 } |
1618 } | 1514 } |
1619 } | 1515 |
1620 } | 1516 /*-------------------------- Action Functions ---------------------------*/ |
1621 | |
1622 /************************************************************************ | |
1623 ** | |
1624 ** Action functions | |
1625 ** | |
1626 */ | |
1627 | 1517 |
1628 static void | 1518 static void |
1629 timer (XtPointer data, XtIntervalId *id) | 1519 timer (XtPointer data, XtIntervalId *id) |
1630 { | 1520 { |
1631 XlwScrollBarWidget w = (XlwScrollBarWidget) data; | 1521 XlwScrollBarWidget w = (XlwScrollBarWidget) data; |
1632 int reason, last_value; | |
1633 | |
1634 w->sb.timerActive = False; | 1522 w->sb.timerActive = False; |
1635 | 1523 |
1636 if (w->sb.armed != ARM_NONE) | 1524 if (w->sb.armed != ARM_NONE) |
1637 { | 1525 { |
1638 last_value = w->sb.value; | 1526 int last_value = w->sb.value; |
1639 reason = XmCR_NONE; | 1527 int reason = XmCR_NONE; |
1640 | 1528 |
1641 switch (w->sb.armed) | 1529 switch (w->sb.armed) |
1642 { | 1530 { |
1643 case ARM_PAGEUP: | 1531 case ARM_PAGEUP: |
1644 w->sb.value = safe_subtract (w->sb.value, w->sb.pageIncrement); | 1532 decrement_value (w, w->sb.pageIncrement); |
1645 reason = XmCR_PAGE_DECREMENT; | 1533 reason = XmCR_PAGE_DECREMENT; |
1646 break; | 1534 break; |
1647 case ARM_PAGEDOWN: | 1535 case ARM_PAGEDOWN: |
1648 w->sb.value = safe_add (w->sb.value, w->sb.pageIncrement); | 1536 increment_value (w, w->sb.pageIncrement); |
1649 reason = XmCR_PAGE_INCREMENT; | 1537 reason = XmCR_PAGE_INCREMENT; |
1650 break; | 1538 break; |
1651 case ARM_UP: | 1539 case ARM_UP: |
1652 w->sb.value = safe_subtract (w->sb.value, w->sb.increment); | 1540 decrement_value (w, w->sb.increment); |
1653 reason = XmCR_DECREMENT; | 1541 reason = XmCR_DECREMENT; |
1654 break; | 1542 break; |
1655 case ARM_DOWN: | 1543 case ARM_DOWN: |
1656 w->sb.value = safe_add (w->sb.value, w->sb.increment); | 1544 increment_value (w, w->sb.increment); |
1657 reason = XmCR_INCREMENT; | 1545 reason = XmCR_INCREMENT; |
1658 break; | 1546 break; |
1659 } | 1547 } |
1660 | 1548 |
1661 verify_values (w); | 1549 verify_values (w); |
1662 | 1550 |
1663 if (last_value != w->sb.value) | 1551 if (last_value != w->sb.value) |
1664 { | 1552 { |
1665 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); | 1553 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); |
1666 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1554 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
1667 | 1555 |
1668 call_callbacks (w, reason, w->sb.value, 0, NULL); | 1556 call_callbacks (w, reason, w->sb.value, 0, NULL); |
1669 | 1557 |
1670 w->sb.timerId = | 1558 w->sb.timerId = |
1671 XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget) w), | 1559 XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget) w), |
1674 w->sb.timerActive = True; | 1562 w->sb.timerActive = True; |
1675 } | 1563 } |
1676 } | 1564 } |
1677 } | 1565 } |
1678 | 1566 |
1679 static int | 1567 static button_where |
1680 what_button (XlwScrollBarWidget w, int mouse_x, int mouse_y) | 1568 what_button (XlwScrollBarWidget w, int mouse_x, int mouse_y) |
1681 { | 1569 { |
1682 int x, y, width, height, arrow_height_top, arrow_height_bottom; | 1570 int width = widget_w (w); |
1683 int where; | 1571 int height = widget_h (w); |
1684 | 1572 int arrow_height = arrow_h (w); |
1685 x = widget_x (w); | 1573 |
1686 y = widget_y (w); | 1574 mouse_x -= widget_x (w); |
1687 width = widget_w (w); | 1575 mouse_y -= widget_y (w); |
1688 height = widget_h (w); | 1576 |
1689 | 1577 if (mouse_x < 0 || mouse_x >= width || |
1690 #if 0 | 1578 mouse_y < 0 || mouse_y >= height) |
1691 arrow_height = w->sb.showArrows ? arrow_h (w) : 0; | 1579 return BUTTON_NONE; |
1692 #endif | 1580 |
1693 if (w->sb.showArrows) | 1581 if (w->sb.showArrows) |
1694 { | 1582 { |
1583 if (mouse_y >= (height -= arrow_height)) | |
1584 return BUTTON_DOWN_ARROW; | |
1585 | |
1695 if (arrow_same_end (w)) | 1586 if (arrow_same_end (w)) |
1696 { | 1587 { |
1697 arrow_height_top = 0; | 1588 if (mouse_y >= (height -= arrow_height)) |
1698 arrow_height_bottom = 2 * arrow_h (w); | 1589 return BUTTON_UP_ARROW; |
1699 } | 1590 } |
1700 else | 1591 else |
1701 { | 1592 if ( (mouse_y -= arrow_height) < 0) |
1702 arrow_height_top = arrow_height_bottom = arrow_h (w); | 1593 return BUTTON_UP_ARROW; |
1703 } | 1594 } |
1704 } | 1595 |
1705 else | 1596 if ( (mouse_y -= w->sb.above) < 0) |
1706 { | 1597 return BUTTON_TROUGH_ABOVE; |
1707 arrow_height_top = arrow_height_bottom = 0; | 1598 |
1708 } | 1599 if ( (mouse_y -= w->sb.ss) < 0) |
1709 | 1600 return BUTTON_SLIDER; |
1710 where = BUTTON_NONE; | 1601 |
1711 | 1602 return BUTTON_TROUGH_BELOW; |
1712 if (mouse_x > x && mouse_x < (x + width)) | 1603 } |
1713 { | |
1714 if (mouse_y > (y + arrow_height_top) && | |
1715 mouse_y < (y + height - arrow_height_bottom)) | |
1716 { | |
1717 if (mouse_y < (y + w->sb.above + arrow_height_top)) | |
1718 { | |
1719 where = BUTTON_TROUGH_ABOVE; | |
1720 } | |
1721 else if (mouse_y > (y + w->sb.above + w->sb.ss + arrow_height_top)) | |
1722 { | |
1723 where = BUTTON_TROUGH_BELOW; | |
1724 } | |
1725 else | |
1726 { | |
1727 where = BUTTON_KNOB; | |
1728 } | |
1729 } | |
1730 else if (arrow_same_end (w)) | |
1731 { | |
1732 if (mouse_y > (y + height - arrow_height_bottom + 1) && | |
1733 mouse_y < (y + height)) | |
1734 { | |
1735 if (mouse_y < (y + height - arrow_height_bottom/2)) | |
1736 { | |
1737 where = BUTTON_UP_ARROW; | |
1738 } | |
1739 else | |
1740 { | |
1741 where = BUTTON_DOWN_ARROW; | |
1742 } | |
1743 } | |
1744 } | |
1745 else | |
1746 { | |
1747 if (mouse_y > y && mouse_y < (y + arrow_height_top)) | |
1748 { | |
1749 where = BUTTON_UP_ARROW; | |
1750 } | |
1751 else if (mouse_y > (y + height - arrow_height_bottom + 1) && | |
1752 mouse_y < (y + height)) | |
1753 { | |
1754 where = BUTTON_DOWN_ARROW; | |
1755 } | |
1756 } | |
1757 } | |
1758 #if 0 | |
1759 if (mouse_x > x && mouse_x < (x + width)) | |
1760 { | |
1761 if (mouse_y > (y + arrow_height) && mouse_y < (y + height - arrow_height)) | |
1762 { | |
1763 if (mouse_y < (y+w->sb.above+arrow_height)) | |
1764 { | |
1765 where = BUTTON_TROUGH_ABOVE; | |
1766 } | |
1767 else if (mouse_y > (y + w->sb.above + w->sb.ss + arrow_height)) | |
1768 { | |
1769 where = BUTTON_TROUGH_BELOW; | |
1770 } | |
1771 else | |
1772 { | |
1773 where = BUTTON_KNOB; | |
1774 } | |
1775 } | |
1776 else if (mouse_y > y && mouse_y < (y + arrow_height)) | |
1777 { | |
1778 where = BUTTON_UP_ARROW; | |
1779 } | |
1780 else if (mouse_y > (y + height - arrow_height + 1) && | |
1781 mouse_y < (y + height)) | |
1782 { | |
1783 where = BUTTON_DOWN_ARROW; | |
1784 } | |
1785 } | |
1786 #endif | |
1787 return where; | |
1788 } | |
1789 | |
1790 #define FORCED_SCROLL_NONE 0 | |
1791 #define FORCED_SCROLL_DOWNRIGHT 1 | |
1792 #define FORCED_SCROLL_UPLEFT 2 | |
1793 | |
1794 int forced_scroll_flag = FORCED_SCROLL_NONE; | |
1795 | 1604 |
1796 static void | 1605 static void |
1797 PageDownOrRight (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) | 1606 PageDownOrRight (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) |
1798 { | 1607 { |
1799 forced_scroll_flag = FORCED_SCROLL_DOWNRIGHT; | 1608 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
1609 w->sb.forced_scroll = FORCED_SCROLL_DOWNRIGHT; | |
1800 Select (widget, event, parms, num_parms); | 1610 Select (widget, event, parms, num_parms); |
1801 forced_scroll_flag = FORCED_SCROLL_NONE; | 1611 w->sb.forced_scroll = FORCED_SCROLL_NONE; |
1802 } | 1612 } |
1803 | 1613 |
1804 static void | 1614 static void |
1805 PageUpOrLeft (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) | 1615 PageUpOrLeft (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) |
1806 { | 1616 { |
1807 forced_scroll_flag = FORCED_SCROLL_UPLEFT; | 1617 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
1618 w->sb.forced_scroll = FORCED_SCROLL_UPLEFT; | |
1808 Select (widget, event, parms, num_parms); | 1619 Select (widget, event, parms, num_parms); |
1809 forced_scroll_flag = FORCED_SCROLL_NONE; | 1620 w->sb.forced_scroll = FORCED_SCROLL_NONE; |
1810 } | 1621 } |
1811 | 1622 |
1812 static void | 1623 static void |
1813 Select (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) | 1624 Select (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) |
1814 { | 1625 { |
1815 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1626 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
1816 int mouse_x, mouse_y; | 1627 button_where sb_button; |
1817 int reason, last_value; | 1628 |
1818 int sb_button; | 1629 int mouse_x = event_x (w, event); |
1819 | 1630 int mouse_y = event_y (w, event); |
1820 DBUG (fprintf (stderr, "Select:\n")); | 1631 |
1821 | 1632 int last_value = w->sb.savedValue = w->sb.value; |
1822 mouse_x = event_x (w, event); | 1633 int reason = XmCR_NONE; |
1823 mouse_y = event_y (w, event); | |
1824 | |
1825 w->sb.savedValue = w->sb.value; | |
1826 | |
1827 last_value = w->sb.value; | |
1828 reason = XmCR_NONE; | |
1829 | 1634 |
1830 XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync, | 1635 XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync, |
1831 event->xbutton.time); | 1636 event->xbutton.time); |
1832 | 1637 |
1833 sb_button = what_button (w, mouse_x, mouse_y); | 1638 sb_button = what_button (w, mouse_x, mouse_y); |
1834 | 1639 |
1835 if (forced_scroll_flag != FORCED_SCROLL_NONE) | 1640 if (w->sb.forced_scroll != FORCED_SCROLL_NONE) |
1836 { | 1641 { |
1837 switch (sb_button) | 1642 switch (sb_button) |
1838 { | 1643 { |
1839 case BUTTON_TROUGH_ABOVE: | 1644 case BUTTON_TROUGH_ABOVE: |
1840 case BUTTON_TROUGH_BELOW: | 1645 case BUTTON_TROUGH_BELOW: |
1841 case BUTTON_KNOB: | 1646 case BUTTON_SLIDER: |
1842 sb_button= BUTTON_NONE; /* cause next switch to fall through */ | 1647 sb_button= BUTTON_NONE; /* cause next switch to fall through */ |
1843 if (forced_scroll_flag == FORCED_SCROLL_UPLEFT) | 1648 if (w->sb.forced_scroll == FORCED_SCROLL_UPLEFT) |
1844 { | 1649 { |
1845 w->sb.value = safe_subtract (w->sb.value, w->sb.pageIncrement); | 1650 decrement_value (w, w->sb.pageIncrement); |
1846 w->sb.armed = ARM_PAGEUP; | 1651 w->sb.armed = ARM_PAGEUP; |
1847 reason = XmCR_PAGE_DECREMENT; | 1652 reason = XmCR_PAGE_DECREMENT; |
1848 break; | 1653 break; |
1849 } | 1654 } |
1850 else if (forced_scroll_flag == FORCED_SCROLL_DOWNRIGHT) | 1655 else if (w->sb.forced_scroll == FORCED_SCROLL_DOWNRIGHT) |
1851 { | 1656 { |
1852 w->sb.value = safe_add (w->sb.value, w->sb.pageIncrement); | 1657 increment_value (w, w->sb.pageIncrement); |
1853 w->sb.armed = ARM_PAGEDOWN; | 1658 w->sb.armed = ARM_PAGEDOWN; |
1854 reason = XmCR_PAGE_INCREMENT; | 1659 reason = XmCR_PAGE_INCREMENT; |
1855 break; | 1660 break; |
1856 } | 1661 } |
1857 abort(); | 1662 abort(); |
1859 } | 1664 } |
1860 | 1665 |
1861 switch (sb_button) | 1666 switch (sb_button) |
1862 { | 1667 { |
1863 case BUTTON_TROUGH_ABOVE: | 1668 case BUTTON_TROUGH_ABOVE: |
1864 w->sb.value = safe_subtract (w->sb.value, w->sb.pageIncrement); | 1669 decrement_value (w, w->sb.pageIncrement); |
1865 w->sb.armed = ARM_PAGEUP; | 1670 w->sb.armed = ARM_PAGEUP; |
1866 reason = XmCR_PAGE_DECREMENT; | 1671 reason = XmCR_PAGE_DECREMENT; |
1867 break; | 1672 break; |
1868 case BUTTON_TROUGH_BELOW: | 1673 case BUTTON_TROUGH_BELOW: |
1869 w->sb.value = safe_add (w->sb.value, w->sb.pageIncrement); | 1674 increment_value (w, w->sb.pageIncrement); |
1870 w->sb.armed = ARM_PAGEDOWN; | 1675 w->sb.armed = ARM_PAGEDOWN; |
1871 reason = XmCR_PAGE_INCREMENT; | 1676 reason = XmCR_PAGE_INCREMENT; |
1872 break; | 1677 break; |
1873 case BUTTON_KNOB: | 1678 case BUTTON_SLIDER: |
1874 w->sb.lastY = mouse_y; | 1679 w->sb.lastY = mouse_y; |
1875 w->sb.armed = ARM_KNOB; | 1680 w->sb.armed = ARM_SLIDER; |
1876 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1681 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
1877 break; | 1682 break; |
1878 case BUTTON_UP_ARROW: | 1683 case BUTTON_UP_ARROW: |
1879 if (event->xbutton.state & ControlMask) | 1684 if (event->xbutton.state & ControlMask) |
1880 { | 1685 { |
1881 w->sb.value = INT_MIN; | 1686 w->sb.value = w->sb.minimum; |
1882 w->sb.armed = ARM_UP; | |
1883 reason = XmCR_TO_TOP; | 1687 reason = XmCR_TO_TOP; |
1884 } | 1688 } |
1885 else | 1689 else |
1886 { | 1690 { |
1887 w->sb.value = safe_subtract (w->sb.value, w->sb.increment); | 1691 decrement_value (w, w->sb.increment); |
1888 w->sb.armed = ARM_UP; | |
1889 reason = XmCR_DECREMENT; | 1692 reason = XmCR_DECREMENT; |
1890 } | 1693 } |
1694 w->sb.armed = ARM_UP; | |
1891 redraw_up_arrow (w, True, False); | 1695 redraw_up_arrow (w, True, False); |
1892 break; | 1696 break; |
1893 case BUTTON_DOWN_ARROW: | 1697 case BUTTON_DOWN_ARROW: |
1894 if (event->xbutton.state & ControlMask) | 1698 if (event->xbutton.state & ControlMask) |
1895 { | 1699 { |
1896 w->sb.value = INT_MAX; | 1700 w->sb.value = w->sb.maximum; |
1897 w->sb.armed = ARM_DOWN; | |
1898 reason = XmCR_TO_BOTTOM; | 1701 reason = XmCR_TO_BOTTOM; |
1899 } | 1702 } |
1900 else | 1703 else |
1901 { | 1704 { |
1902 w->sb.value = safe_add (w->sb.value, w->sb.increment); | 1705 increment_value (w, w->sb.increment); |
1903 w->sb.armed = ARM_DOWN; | |
1904 reason = XmCR_INCREMENT; | 1706 reason = XmCR_INCREMENT; |
1905 } | 1707 } |
1708 w->sb.armed = ARM_DOWN; | |
1906 redraw_down_arrow (w, True, False); | 1709 redraw_down_arrow (w, True, False); |
1907 break; | 1710 break; |
1908 } | 1711 } |
1909 | 1712 |
1910 verify_values (w); | 1713 verify_values (w); |
1911 | 1714 |
1912 if (last_value != w->sb.value) | 1715 if (last_value != w->sb.value) |
1913 { | 1716 { |
1914 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); | 1717 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); |
1915 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1718 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
1916 | 1719 |
1917 call_callbacks (w, reason, w->sb.value, mouse_y, event); | 1720 call_callbacks (w, reason, w->sb.value, mouse_y, event); |
1918 | 1721 |
1919 if (w->sb.timerActive) | 1722 if (w->sb.timerActive) |
1920 XtRemoveTimeOut (w->sb.timerId); | 1723 XtRemoveTimeOut (w->sb.timerId); |
1931 | 1734 |
1932 static void | 1735 static void |
1933 Drag (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) | 1736 Drag (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) |
1934 { | 1737 { |
1935 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1738 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
1936 int diff; | 1739 |
1937 int height, mouse_y; | 1740 if (w->sb.armed == ARM_SLIDER) |
1938 int last_value, last_above; | 1741 { |
1939 | 1742 int mouse_y = event_y (w, event); |
1940 DBUG (fprintf (stderr, "Drag:\n")); | 1743 int diff = mouse_y - w->sb.lastY; |
1941 | 1744 |
1942 if (w->sb.armed == ARM_KNOB) | 1745 if (diff < -(w->sb.above)) /* up */ |
1943 { | 1746 { |
1944 height = widget_h (w); | 1747 mouse_y -= (diff + w->sb.above); |
1945 if (w->sb.showArrows) height -= (2 * arrow_h (w)); | 1748 diff = -(w->sb.above); |
1946 | 1749 } |
1947 mouse_y = event_y (w, event); | 1750 else if (diff > w->sb.below) /* down */ |
1948 | 1751 { |
1949 diff = mouse_y - w->sb.lastY; | 1752 mouse_y -= (diff - w->sb.below); |
1950 | 1753 diff = w->sb.below; |
1951 last_above = w->sb.above; | 1754 } |
1952 last_value = w->sb.value; | 1755 |
1953 | 1756 if (diff) |
1954 if (diff < 0) | 1757 { |
1955 { | 1758 w->sb.above += diff; |
1956 /* up */ | |
1957 w->sb.above -= (-diff); | |
1958 if (w->sb.above < 0) | |
1959 { | |
1960 mouse_y = (mouse_y - w->sb.above); | |
1961 w->sb.above = 0; | |
1962 diff = 0; | |
1963 w->sb.below = height - w->sb.ss; | |
1964 } | |
1965 w->sb.below -= diff; | 1759 w->sb.below -= diff; |
1966 CHECK (w); | 1760 |
1967 } | 1761 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
1968 else if (diff > 0) | |
1969 { | |
1970 /* down */ | |
1971 w->sb.above += diff; | |
1972 if (w->sb.above + w->sb.ss > height) | |
1973 { | |
1974 mouse_y = height + (mouse_y - (w->sb.above + w->sb.ss)); | |
1975 w->sb.above = height - w->sb.ss; | |
1976 diff = 0; | |
1977 w->sb.below = 0; | |
1978 } | |
1979 w->sb.below -= diff; | |
1980 CHECK (w); | |
1981 } | |
1982 | |
1983 if (last_above != w->sb.above) | |
1984 { | |
1985 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | |
1986 | 1762 |
1987 w->sb.lastY = mouse_y; | 1763 w->sb.lastY = mouse_y; |
1988 | 1764 |
1989 w->sb.value = value_from_pixel (w, w->sb.above); | 1765 w->sb.value = value_from_pixel (w, w->sb.above); |
1990 verify_values (w); | 1766 verify_values (w); |
1991 CHECK (w); | 1767 CHECK (w); |
1992 | 1768 |
1993 if (w->sb.value != last_value) | 1769 call_callbacks (w, XmCR_DRAG, w->sb.value, event_y (w, event), event); |
1994 call_callbacks (w, XmCR_DRAG, w->sb.value, event_y (w, event), event); | |
1995 } | 1770 } |
1996 } | 1771 } |
1997 CHECK (w); | 1772 CHECK (w); |
1998 } | 1773 } |
1999 | 1774 |
2000 static void | 1775 static void |
2001 Release (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) | 1776 Release (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) |
2002 { | 1777 { |
2003 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1778 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
2004 | 1779 |
2005 DBUG (fprintf (stderr, "EndDrag:\n")); | |
2006 | |
2007 switch (w->sb.armed) | 1780 switch (w->sb.armed) |
2008 { | 1781 { |
2009 case ARM_KNOB: | 1782 case ARM_SLIDER: |
2010 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, event_y (w, event), event); | 1783 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, event_y (w, event), event); |
2011 w->sb.armed = ARM_NONE; | 1784 w->sb.armed = ARM_NONE; |
2012 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1785 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
2013 break; | 1786 break; |
2014 case ARM_UP: | 1787 case ARM_UP: |
2015 redraw_up_arrow (w, False, False); | 1788 redraw_up_arrow (w, False, False); |
2016 break; | 1789 break; |
2017 case ARM_DOWN: | 1790 case ARM_DOWN: |
2026 | 1799 |
2027 static void | 1800 static void |
2028 Jump (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) | 1801 Jump (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) |
2029 { | 1802 { |
2030 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1803 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
2031 int x, y, width, height, mouse_x, mouse_y; | 1804 int last_value; |
2032 int arrow_height; | 1805 |
2033 int last_above, last_value; | 1806 int mouse_x = event_x (w, event); |
2034 | 1807 int mouse_y = event_y (w, event); |
2035 DBUG (fprintf (stderr, "Jump:\n")); | 1808 |
2036 | 1809 int scroll_region_y = widget_y (w); |
2037 x = widget_x (w); | 1810 int scroll_region_h = widget_h (w); |
2038 y = widget_y (w); | |
2039 width = widget_w (w); | |
2040 height = widget_h (w); | |
2041 | 1811 |
2042 mouse_x = event_x (w, event); | 1812 if (w->sb.showArrows) |
2043 mouse_y = event_y (w, event); | 1813 { |
2044 | 1814 int arrow_height = arrow_h (w); |
2045 arrow_height = w->sb.showArrows ? arrow_h (w) : 0; | 1815 scroll_region_h -= 2 * arrow_height; |
1816 if (!arrow_same_end (w)) | |
1817 scroll_region_y += arrow_height; | |
1818 } | |
2046 | 1819 |
2047 XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync, | 1820 XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync, |
2048 event->xbutton.time); | 1821 event->xbutton.time); |
2049 | 1822 |
2050 switch (what_button (w, mouse_x, mouse_y)) | 1823 switch (what_button (w, mouse_x, mouse_y)) |
2051 { | 1824 { |
2052 case BUTTON_TROUGH_ABOVE: | 1825 case BUTTON_TROUGH_ABOVE: |
2053 case BUTTON_TROUGH_BELOW: | 1826 case BUTTON_TROUGH_BELOW: |
2054 case BUTTON_KNOB: | 1827 case BUTTON_SLIDER: |
2055 w->sb.savedValue = w->sb.value; | 1828 w->sb.savedValue = w->sb.value; |
2056 | 1829 |
2057 height -= (2*arrow_height); | |
2058 y += arrow_height; | |
2059 | |
2060 last_above = w->sb.above; | |
2061 last_value = w->sb.value; | 1830 last_value = w->sb.value; |
2062 | 1831 |
2063 w->sb.armed = ARM_KNOB; | 1832 w->sb.above = mouse_y - (w->sb.ss / 2) - scroll_region_y; |
2064 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | |
2065 | |
2066 w->sb.above = mouse_y - (w->sb.ss / 2) - arrow_height; | |
2067 if (w->sb.above < 0) | 1833 if (w->sb.above < 0) |
2068 { | 1834 w->sb.above = 0; |
2069 w->sb.above = 0; | 1835 else if (w->sb.above + w->sb.ss > scroll_region_h) |
2070 } | 1836 w->sb.above = scroll_region_h - w->sb.ss; |
2071 else if (w->sb.above + w->sb.ss > height) | 1837 |
2072 { | 1838 w->sb.below = scroll_region_h - w->sb.ss - w->sb.above; |
2073 w->sb.above = height - w->sb.ss; | 1839 |
2074 } | 1840 w->sb.armed = ARM_SLIDER; |
2075 w->sb.below = (height - (w->sb.ss + w->sb.above)); | 1841 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
2076 | 1842 |
2077 if (last_above != w->sb.above) | 1843 w->sb.value = value_from_pixel (w, w->sb.above); |
2078 { | 1844 verify_values (w); |
2079 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1845 CHECK (w); |
2080 | 1846 |
2081 w->sb.value = value_from_pixel (w, w->sb.above); | 1847 w->sb.lastY = mouse_y; |
2082 verify_values (w); | 1848 |
2083 CHECK (w); | 1849 if (w->sb.value != last_value) |
2084 | 1850 call_callbacks (w, XmCR_DRAG, w->sb.value, mouse_y, event); |
2085 w->sb.lastY = mouse_y; | 1851 |
2086 w->sb.lastY = w->sb.above + arrow_height + (w->sb.ss / 2); | |
2087 | |
2088 if (w->sb.value != last_value) | |
2089 { | |
2090 call_callbacks (w, XmCR_DRAG, w->sb.value, event_y (w, event), event); | |
2091 } | |
2092 } | |
2093 break; | 1852 break; |
2094 } | 1853 } |
2095 CHECK (w); | 1854 CHECK (w); |
2096 } | 1855 } |
2097 | 1856 |
2098 static void | 1857 static void |
2099 Abort (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) | 1858 Abort (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) |
2100 { | 1859 { |
2101 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; | 1860 XlwScrollBarWidget w = (XlwScrollBarWidget) widget; |
2102 | 1861 |
2103 DBUG (fprintf (stderr, "Abort:\n")); | |
2104 | |
2105 if (w->sb.armed != ARM_NONE) | 1862 if (w->sb.armed != ARM_NONE) |
2106 { | 1863 { |
2107 if (w->sb.value != w->sb.savedValue) | 1864 if (w->sb.value != w->sb.savedValue) |
2108 { | 1865 { |
2109 w->sb.value = w->sb.savedValue; | 1866 w->sb.value = w->sb.savedValue; |
2110 | 1867 |
2111 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); | 1868 seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); |
2112 draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); | 1869 draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); |
2113 | 1870 |
2114 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, | 1871 call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, |
2115 event_y (w, event), event); | 1872 event_y (w, event), event); |
2116 } | 1873 } |
2117 | 1874 |