Mercurial > hg > xemacs-beta
diff lwlib/xlwscrollbar.c @ 102:a145efe76779 r20-1b3
Import from CVS: tag r20-1b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:15:49 +0200 |
parents | 1ce6082ce73f |
children | 6b37e6ddd302 |
line wrap: on
line diff
--- a/lwlib/xlwscrollbar.c Mon Aug 13 09:15:13 2007 +0200 +++ b/lwlib/xlwscrollbar.c Mon Aug 13 09:15:49 2007 +0200 @@ -1,5 +1,6 @@ /* Implements a lightweight scrollbar widget. Copyright (C) 1992, 1993, 1994 Lucid, Inc. + Copyright (C) 1997 Sun Microsystems, Inc. This file is part of the Lucid Widget Library. @@ -19,6 +20,7 @@ Boston, MA 02111-1307, USA. */ /* Created by Douglas Keller <dkeller@vnet.ibm.com> */ +/* Lots of hacking by Martin Buchholz */ /* * Athena-style scrollbar button bindings added on Sun Dec 24 22:03:57 1995 @@ -61,7 +63,7 @@ * XmNtoBottomCallback * XmNdragCallback * - * XmNknobStyle - values can be: "plain" or "dimple" + * XmNsliderStyle - values can be: "plain" or "dimple" * XmNarrowPosition - values can be: "opposite" or "same" * */ @@ -86,33 +88,23 @@ #define SS_MIN 8 -#define ARROW_UP 0 -#define ARROW_DOWN 1 -#define ARROW_LEFT 2 -#define ARROW_RIGHT 3 - -#define ARM_NONE 0 -#define ARM_KNOB 1 -#define ARM_UP 2 -#define ARM_DOWN 3 -#define ARM_PAGEUP 4 -#define ARM_PAGEDOWN 5 +typedef enum +{ + BUTTON_NONE, + BUTTON_SLIDER, + BUTTON_UP_ARROW, + BUTTON_DOWN_ARROW, + BUTTON_TROUGH_ABOVE, + BUTTON_TROUGH_BELOW +} button_where; -#define BUTTON_NONE 0 -#define BUTTON_KNOB 1 -#define BUTTON_UP_ARROW 2 -#define BUTTON_DOWN_ARROW 3 -#define BUTTON_TROUGH_ABOVE 4 -#define BUTTON_TROUGH_BELOW 5 +typedef enum +{ + SLIDER_PLAIN, + SLIDER_DIMPLE +} SliderStyle; -#define KNOB_PLAIN 0 -#define KNOB_DIMPLE 1 - -/************************************************************************ -** -** Resources -** -*/ +/*-------------------------- Resources ----------------------------------*/ #define offset(field) XtOffset(XlwScrollBarWidget, field) static XtResource resources[] = { @@ -189,33 +181,23 @@ { XmNdragCallback, XmCDragCallback, XtRCallback, sizeof(XtPointer), offset(sb.dragCBL), XtRCallback, NULL}, + /* "knob" is obsolete; use "slider" instead. */ + { XmNsliderStyle, XmCSliderStyle, XtRString, sizeof(char *), + offset(sb.sliderStyle), XtRImmediate, NULL}, { XmNknobStyle, XmCKnobStyle, XtRString, sizeof(char *), - offset(sb.knobStyle), XtRImmediate, NULL}, + offset(sb.sliderStyle), XtRImmediate, NULL}, { XmNarrowPosition, XmCArrowPosition, XtRString, sizeof(char *), offset(sb.arrowPosition), XtRImmediate, NULL}, }; -/************************************************************************ -** -** Prototypes -** -*/ +/*-------------------------- Prototypes ---------------------------------*/ -/* -** Actions -*/ -static void Select(Widget w, XEvent *event, String *parms, Cardinal *num_parms); -static void PageUpOrLeft(Widget w, XEvent *event, String *parms, Cardinal *num_parms); -static void PageDownOrRight(Widget w, XEvent *event, String *parms, Cardinal *num_parms); -static void Drag(Widget w, XEvent *event, String *parms, Cardinal *num_parms); -static void Release(Widget w, XEvent *event, String *parms, Cardinal *num_parms); -static void Jump(Widget w, XEvent *event, String *parms, Cardinal *num_parms); -static void Abort(Widget w, XEvent *event, String *parms, Cardinal *num_parms); +/* Actions */ +typedef void Action(Widget w, XEvent *event, String *parms, Cardinal *num_parms); +static Action Select, PageUpOrLeft, PageDownOrRight, Drag, Release, Jump, Abort; -/* -** Methods -*/ +/* Methods */ static void Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num_args); static Boolean SetValues(Widget current, Widget request, Widget nw, ArgList args, Cardinal *num_args); static void Destroy(Widget widget); @@ -223,46 +205,32 @@ static void Resize(Widget widget); static void Realize(Widget widget, XtValueMask *valuemask, XSetWindowAttributes *attr); -/* -** Private -*/ - +/* Private */ -/************************************************************************ -** -** Actions Table -** -*/ -static XtActionsRec actions[] = { - {"Select", Select}, - {"PageDownOrRight", PageDownOrRight}, - {"PageUpOrLeft", PageUpOrLeft}, - {"Drag", Drag}, - {"Release", Release}, - {"Jump", Jump}, - {"Abort", Abort}, +/*-------------------------- Actions Table ------------------------------*/ +static XtActionsRec actions[] = +{ + {"Select", Select}, + {"PageDownOrRight", PageDownOrRight}, + {"PageUpOrLeft", PageUpOrLeft}, + {"Drag", Drag}, + {"Release", Release}, + {"Jump", Jump}, + {"Abort", Abort}, }; -/************************************************************************ -** -** Default Translation Table -** -*/ +/*--------------------- Default Translation Table -----------------------*/ static char default_translations[] = - "<Btn1Down>: Select()\n" - "<Btn1Motion>: Drag()\n" - "<Btn1Up>: Release()\n" - "<Btn2Down>: Jump()\n" - "<Btn2Motion>: Drag()\n" - "<Btn2Up>: Release()\n" - "<Key>Delete: Abort()" + "<Btn1Down>: Select()\n" + "<Btn1Motion>: Drag()\n" + "<Btn1Up>: Release()\n" + "<Btn2Down>: Jump()\n" + "<Btn2Motion>: Drag()\n" + "<Btn2Up>: Release()\n" + "<Key>Delete: Abort()" ; -/************************************************************************ -** -** Class record initalization -** -*/ +/*------------------- Class record initialization -----------------------*/ XlwScrollBarClassRec xlwScrollBarClassRec = { /* core_class fields */ { @@ -305,11 +273,7 @@ WidgetClass xlwScrollBarWidgetClass = (WidgetClass) &xlwScrollBarClassRec; -/************************************************************************ -** -** Debug functions -** -*/ +/*-------------------------- Debug Functions ----------------------------*/ #ifdef SHOW_CLEAR static void @@ -329,15 +293,13 @@ static void check(XlwScrollBarWidget w) { - int height; - - height= widget_h (w); - if (w->sb.showArrows) height -= (2 * arrow_h (w)); + int height = widget_h (w); + if (w->sb.showArrows) + height -= (2 * arrow_h (w)); if ((w->sb.above + w->sb.ss + w->sb.below > height) || (w->sb.value < w->sb.minimum) || - (w->sb.value > w->sb.maximum - w->sb.sliderSize) - ) + (w->sb.value > w->sb.maximum - w->sb.sliderSize)) { printf("above=%d ss=%d below=%d height=%d\n", w->sb.above, w->sb.ss, w->sb.below, height); @@ -353,11 +315,7 @@ # define CHECK(w) #endif -/************************************************************************ -** -** Static functions -** -*/ +/*-------------------------- Static functions ---------------------------*/ static void call_callbacks (XlwScrollBarWidget w, int reason, @@ -437,9 +395,8 @@ } } -/* -** Widget sizes minus the shadow and highlight area -*/ +/* Widget sizes minus the shadow and highlight area */ + static int widget_x (XlwScrollBarWidget w) { @@ -455,41 +412,26 @@ static int widget_w (XlwScrollBarWidget w) { - int width, x = w->sb.shadowThickness; - - width = VERT (w) ? w->core.width : w->core.height; - - if (width <= (2 * x)) - return 1; - else - return width - (2 * x); + int x = w->sb.shadowThickness; + int width = (VERT (w) ? w->core.width : w->core.height) - (2 * x); + return width > 1 ? width : 1; } static int widget_h (XlwScrollBarWidget w) { - int height, y = w->sb.shadowThickness; - - height = VERT (w) ? w->core.height : w->core.width; + int y = w->sb.shadowThickness; + int height = (VERT (w) ? w->core.height : w->core.width) - (2 * y); - if (height <= (2 * y)) - return 1; - else - return height - (2 * y); + return height > 1 ? height : 1; } static int arrow_h (XlwScrollBarWidget w) { - int width, height; - - width = widget_w (w); - height= widget_h (w); - - if (width > ((height / 2) - (SS_MIN / 2) - 1)) - return (height / 2) - (SS_MIN / 2) - 1 ; - else - return width; + int width = widget_w (w); + int minimum_size = ((widget_h (w) - SS_MIN) / 2) - 1; + return minimum_size < width ? minimum_size : width; } static int @@ -504,29 +446,29 @@ return VERT (w) ? event->xbutton.y : event->xbutton.x; } -/* -** Safe addition and subtraction -*/ -static int -safe_add (int a, int b) +/* Safe addition and subtraction */ +static void +increment_value (XlwScrollBarWidget w, int diff) { - if (a > 0 && INT_MAX - a < b) return INT_MAX; - else return a + b; + w->sb.value = w->sb.maximum - diff < w->sb.value ? + w->sb.maximum : + w->sb.value + diff; } -static int -safe_subtract (int a, int b) +static void +decrement_value (XlwScrollBarWidget w, int diff) { - if (a < 0 && -(INT_MIN - a) < b) return INT_MIN; - else return a - b; + w->sb.value = w->sb.minimum + diff > w->sb.value ? + w->sb.minimum : + w->sb.value - diff; } -static int -knob_style (XlwScrollBarWidget w) +static SliderStyle +slider_style (XlwScrollBarWidget w) { - return w->sb.knobStyle && w->sb.knobStyle[0] == 'd' ? - KNOB_DIMPLE : - KNOB_PLAIN; + return w->sb.sliderStyle && w->sb.sliderStyle[0] == 'd' ? + SLIDER_DIMPLE : + SLIDER_PLAIN; } static Boolean @@ -535,9 +477,7 @@ return w->sb.arrowPosition && w->sb.arrowPosition[0] == 's' ? True : False; } -/* -** GC and Pixel allocation -*/ +/*-------------------------- GC and Pixel allocation --------------------*/ static GC get_gc (XlwScrollBarWidget w, Pixel fg, Pixel bg, Pixmap pm) { @@ -559,8 +499,8 @@ values.background = bg; values.fill_style = FillOpaqueStippled; values.stipple = pm; - mask = GCForeground | GCBackground | - (pm == None ? 0 : GCStipple | GCFillStyle); + mask = GCForeground | GCBackground | + (pm == None ? 0 : GCStipple | GCFillStyle); return XtGetGC((Widget) w, mask, &values); } @@ -716,7 +656,7 @@ * really in color but just short on color cells -- We want the * following behavior, which has been empirically determined to * work well for all fg/bg combinations in mono: If the trough - * and thumb are BOTH black, then use a white top shadow and a + * and slider are BOTH black, then use a white top shadow and a * grey bottom shadow, otherwise use a grey top shadow and a * black bottom shadow. */ @@ -724,7 +664,7 @@ Pixel white = WhitePixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); Pixel black = BlackPixelOfScreen (DefaultScreenOfDisplay (XtDisplay (w))); - /* Note: core.background_pixel is the color of the thumb ... */ + /* Note: core.background_pixel is the color of the slider ... */ if (w->core.background_pixel == black && w->sb.troughColor == black) @@ -759,9 +699,7 @@ } } -/* -** Draw 3d border -*/ +/*-------------------------- Draw 3D Border -----------------------------*/ static void draw_shadows (Display *dpy, Drawable d, GC shine_gc, GC shadow_gc, int x, int y, int width, int height, int shadowT) @@ -798,20 +736,18 @@ XDrawSegments (dpy, d, shadow_gc, shadow, shadowT * 2); } -/* -** Draw 3d arrows, left, up, down, and right -*/ +/*------------------ Draw 3D Arrows: left, up, down, right --------------*/ static int make_vert_seg (XSegment *seg, int x1, int y1, int x2, int y2, int shadowT) { int i; - for (i=0; i<shadowT; i++) + for (i=0; i<shadowT; i++, seg++) { - seg[i].x1 = x1; - seg[i].y1 = y1 + i; - seg[i].x2 = x2; - seg[i].y2 = y2 + i; + seg->x1 = x1; + seg->y1 = y1++; + seg->x2 = x2; + seg->y2 = y2++; } return shadowT; } @@ -821,12 +757,12 @@ { int i; - for (i=0; i<shadowT; i++) + for (i=0; i<shadowT; i++, seg++) { - seg[i].x1 = x1 + i; - seg[i].y1 = y1; - seg[i].x2 = x2 + i; - seg[i].y2 = y2; + seg->x1 = x1++; + seg->y1 = y1; + seg->x2 = x2++; + seg->y2 = y2; } return shadowT; } @@ -843,18 +779,18 @@ if (shadowT > (width / 2)) shadowT = (width / 2); if (shadowT > (height / 2)) shadowT = (height / 2); - if (shadowT <= 0) shadowT = 0; + if (shadowT < 0) shadowT = 0; /* / */ make_vert_seg (shine, - x, y + height - shadowT - 1, + x, y + height - shadowT - 1, x + mid, y, shadowT); /* _\ */ make_vert_seg (shadow, - x, y + height - shadowT - 1, + x, y + height - shadowT - 1, x + width - 1, y + height - shadowT - 1, shadowT); make_vert_seg (shadow + shadowT, - x + mid, y, + x + mid, y, x + width - 1, y + height - shadowT - 1, shadowT); triangle[0].x = x; @@ -876,21 +812,20 @@ { XSegment shine[10], shadow[10]; XPoint triangle[3]; - int mid; - mid = width / 2; + int mid = width / 2; if (shadowT > (width / 2)) shadowT = (width / 2); if (shadowT > (height / 2)) shadowT = (height / 2); - if (shadowT <= 0) shadowT = 0; + if (shadowT < 0) shadowT = 0; /* / */ make_hor_seg (shine, - x, y + mid, + x, y + mid, x + width - shadowT - 1, y, shadowT); /* \| */ make_hor_seg (shadow, - x, y + mid, + x, y + mid, x + width - shadowT - 1, y + height - 1, shadowT); make_hor_seg (shadow + shadowT, x + width - shadowT - 1, y, @@ -921,19 +856,19 @@ if (shadowT > (width / 2)) shadowT = (width / 2); if (shadowT > (height / 2)) shadowT = (height / 2); - if (shadowT <= 0) shadowT = 0; + if (shadowT < 0) shadowT = 0; /* \- */ make_vert_seg (shine, - x, y, + x, y, x + mid, y + height - shadowT - 1, shadowT); make_vert_seg (shine + shadowT, - x, y, + x, y, x + width - 1, y, shadowT); /* / */ make_vert_seg (shadow, x + width - 1, y, - x + mid, y + height - shadowT - 1, shadowT); + x + mid, y + height - shadowT - 1, shadowT); triangle[0].x = x; triangle[0].y = y; @@ -960,23 +895,23 @@ if (shadowT > (width / 2)) shadowT = (width / 2); if (shadowT > (height / 2)) shadowT = (height / 2); - if (shadowT <= 0) shadowT = 0; + if (shadowT < 0) shadowT = 0; /* |\ */ make_hor_seg (shine, - x, y, + x, y, x + width - shadowT - 1, y + mid, shadowT); make_hor_seg (shine + shadowT, x, y, - x, y + height -1, shadowT); + x, y + height - 1, shadowT); /* / */ make_hor_seg (shadow, - x, y + height -1, + x, y + height - 1, x + width - shadowT - 1, y + mid, shadowT); triangle[0].x = x + 1; triangle[0].y = y + height - 1; - triangle[1].x = x + width - 1; + triangle[1].x = x + width - 1; triangle[1].y = y + mid; triangle[2].x = x + 1; triangle[2].y = y; @@ -995,9 +930,7 @@ XDrawArc (dpy, win, shadow, x, y, width, height, 45*64, -179*64); } -/* -** Scrollbar values -> pixels, pixels -> scrollbar values -*/ +/*------- Scrollbar values -> pixels, pixels -> scrollbar values --------*/ static void seg_pixel_sizes (XlwScrollBarWidget w, int *above_return, @@ -1019,14 +952,14 @@ above = ((height * value + fuz) / total); below = ((height) - (ss + above)); - /* Dont' let knob get smaller than SS_MIN */ + /* Don't let slider get smaller than SS_MIN */ if (ss < SS_MIN) { /* add a percent amount for integer rounding */ float tmp = ((((float) (SS_MIN - ss) * (float) value)) / total) + 0.5; above -= (int) tmp; - ss = SS_MIN; + ss = SS_MIN; below = ((height) - (ss + above)); if (above < 0) @@ -1071,8 +1004,11 @@ if (w->sb.value < w->sb.minimum) w->sb.value = w->sb.minimum; - if (w->sb.value > w->sb.maximum - w->sb.sliderSize) - w->sb.value = w->sb.maximum - w->sb.sliderSize; + if (w->sb.value > w->sb.maximum) + w->sb.value = w->sb.maximum; + + if (w->sb.sliderSize > w->sb.maximum - w->sb.value) + w->sb.sliderSize = w->sb.maximum - w->sb.value; } static int @@ -1081,8 +1017,9 @@ float total, height, fuz; int value, ss; - height= widget_h (w); - if (w->sb.showArrows) height -= (2 * arrow_h (w)); + height = widget_h (w); + if (w->sb.showArrows) + height -= (2 * arrow_h (w)); total = w->sb.maximum - w->sb.minimum; fuz = height / 2; @@ -1114,23 +1051,13 @@ redraw_dimple (XlwScrollBarWidget w, Display *dpy, Window win, int x, int y, int width, int height) { - GC shine, shadow; - int shadowT, size; - - if (KNOB_DIMPLE == knob_style (w)) + if (SLIDER_DIMPLE == slider_style (w)) { - if (w->sb.armed == ARM_KNOB) - { - shine = w->sb.bottomShadowGC; - shadow = w->sb.topShadowGC; - } - else - { - shine = w->sb.topShadowGC; - shadow = w->sb.bottomShadowGC; - } - - shadowT = w->sb.shadowThickness; + int size; + int slider_p = (w->sb.armed == ARM_SLIDER); + GC shine = slider_p ? w->sb.bottomShadowGC : w->sb.topShadowGC; + GC shadow = slider_p ? w->sb.topShadowGC : w->sb.bottomShadowGC; + int shadowT = w->sb.shadowThickness; x += shadowT; y += shadowT; @@ -1153,59 +1080,58 @@ } static void -draw_knob (XlwScrollBarWidget w, int above, int ss, int below) +draw_slider (XlwScrollBarWidget w, int above, int ss, int below) { Display *dpy = XtDisplay ((Widget) w); Window win = XtWindow ((Widget) w); - int x, y, width, height; - int shadowT; - x = widget_x (w); - y = widget_y (w); - width = widget_w (w); - height = widget_h (w); - - shadowT = w->sb.shadowThickness; + int x = widget_x (w); + int y = widget_y (w); + int width = widget_w (w); + int height = widget_h (w); + int shadowT = w->sb.shadowThickness; + int vert_p = VERT (w); if (shadowT > (width / 2)) shadowT = (width / 2); if (shadowT > (height / 2)) shadowT = (height / 2); - if (shadowT <= 0) return; + if (shadowT < 0) shadowT = 0; - if (w->sb.showArrows && !arrow_same_end (w)) y += arrow_h (w); + if (w->sb.showArrows && !arrow_same_end (w)) + y += arrow_h (w); - /* trough above knob */ + /* trough above slider */ if (above > 0) { - if (VERT (w)) + if (vert_p) XClearArea (dpy, win, x, y, width, above, False); else XClearArea (dpy, win, y, x, above, width, False); } - /* knob */ - if (VERT (w)) + /* slider */ + if (vert_p) { draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, x, y + above, width, ss, shadowT); - XFillRectangle (dpy, win, - w->sb.backgroundGC, - x+shadowT, y + above + shadowT, width-2*shadowT, ss-2*shadowT); + XFillRectangle (dpy, win, w->sb.backgroundGC, + x+shadowT, y + above + shadowT, + width-2*shadowT, ss-2*shadowT); redraw_dimple (w, dpy, win, x, y + above, width, ss); } else { draw_shadows (dpy, win, w->sb.topShadowGC, w->sb.bottomShadowGC, y + above, x, ss, width, shadowT); - XFillRectangle (dpy, win, - w->sb.backgroundGC, - y + above + shadowT, x+shadowT, ss-2*shadowT, width-2*shadowT); + XFillRectangle (dpy, win, w->sb.backgroundGC, + y + above + shadowT, x+shadowT, + ss-2*shadowT, width-2*shadowT); redraw_dimple (w, dpy, win, y + above, x, ss, width); } - /* trough below knob */ + /* trough below slider */ if (below > 0) { - if (VERT (w)) + if (vert_p) XClearArea (dpy, win, x, y + above + ss, width, below, False); else XClearArea (dpy, win, y + above + ss, x, below, width, False); @@ -1219,35 +1145,22 @@ { Display *dpy = XtDisplay ((Widget) w); Window win = XtWindow ((Widget) w); - GC bg, shine, shadow; - int x, y, width, height, arrow_height, shadowT; - - x = widget_x (w); - y = widget_y (w); - width = widget_w (w); - height = widget_h (w); - arrow_height = arrow_h (w); - shadowT = w->sb.shadowThickness; - bg = w->sb.backgroundGC; + int x = widget_x (w); + int y = widget_y (w); + int width = widget_w (w); + int height = widget_h (w); + int shadowT = w->sb.shadowThickness; + int arrow_height = arrow_h (w); - if (armed) - { - shine = w->sb.bottomShadowGC; - shadow = w->sb.topShadowGC; - } - else - { - shine = w->sb.topShadowGC; - shadow = w->sb.bottomShadowGC; - } + GC bg = w->sb.backgroundGC; + GC shine = armed ? w->sb.bottomShadowGC : w->sb.topShadowGC; + GC shadow = armed ? w->sb.topShadowGC : w->sb.bottomShadowGC; if (VERT (w)) { if (arrow_same_end (w)) - { - y += height - 2 * arrow_h (w) + 2; - } + y += height - 2 * arrow_height; if (clear_behind) XClearArea (dpy, win, x, y, width, arrow_height + 1, False); draw_arrow_up (dpy, win, bg, shine, shadow, @@ -1257,9 +1170,7 @@ else { if (arrow_same_end (w)) - { - y += height - 2 * arrow_h (w); - } + y += height - 2 * arrow_height; if (clear_behind) XClearArea (dpy, win, y, x, arrow_height + 1, height, False); draw_arrow_left (dpy, win, bg, shine, shadow, @@ -1273,28 +1184,17 @@ { Display *dpy = XtDisplay ((Widget) w); Window win = XtWindow ((Widget) w); - GC bg, shine, shadow; - int x, y, width, height, arrow_height, shadowT; - - x = widget_x (w); - y = widget_y (w); - width = widget_w (w); - height = widget_h (w); - arrow_height = arrow_h (w); - shadowT = w->sb.shadowThickness; - bg = w->sb.backgroundGC; + int x = widget_x (w); + int y = widget_y (w); + int width = widget_w (w); + int height = widget_h (w); + int shadowT = w->sb.shadowThickness; + int arrow_height = arrow_h (w); - if (armed) - { - shine = w->sb.bottomShadowGC; - shadow = w->sb.topShadowGC; - } - else - { - shine = w->sb.topShadowGC; - shadow = w->sb.bottomShadowGC; - } + GC bg = w->sb.backgroundGC; + GC shine = armed ? w->sb.bottomShadowGC : w->sb.topShadowGC; + GC shadow = armed ? w->sb.topShadowGC : w->sb.bottomShadowGC; if (VERT (w)) { @@ -1323,48 +1223,49 @@ { Display *dpy = XtDisplay ((Widget) w); Window win = XtWindow ((Widget) w); - int x, y, width, height, shadowT, tmp; - - x = widget_x (w); - y = widget_y (w); - width = widget_w (w); - height = widget_h (w); - shadowT = w->sb.shadowThickness; if (w->sb.showArrows) { - if (region == NULL || XRectInRegion (region, x, y, width, width)) + if (region == NULL) { - redraw_up_arrow (w, False, behind_arrows); - } - if (VERT (w)) - { - y = y + height - width + 1; + redraw_up_arrow (w, False, behind_arrows); + redraw_down_arrow (w, False, behind_arrows); } else { - tmp = y; - y = x; - x = tmp + height - width + 1; - } - if (region == NULL || XRectInRegion (region, x, y, width, width)) - { - redraw_down_arrow (w, False, behind_arrows); + int x = widget_x (w); + int y = widget_y (w); + int width = widget_w (w); + int height = widget_h (w); + int arrow_height = arrow_h (w); + int ax = x, ay = y; + + if (arrow_same_end (w)) + { + if (VERT (w)) + ay = y + height - arrow_height - arrow_height; + else + ax = x + height - arrow_height - arrow_height; + } + if (XRectInRegion (region, ax, ay, width, width)) + redraw_up_arrow (w, False, behind_arrows); + + if (VERT (w)) + ay = y + height - arrow_height; + else + ax = x + height - arrow_height; + if (XRectInRegion (region, ax, ay, width, width)) + redraw_down_arrow (w, False, behind_arrows); } } - draw_shadows (dpy, win, w->sb.bottomShadowGC, w->sb.topShadowGC, - 0, 0, w->core.width, w->core.height, shadowT); + draw_shadows (dpy, win, w->sb.bottomShadowGC, w->sb.topShadowGC, 0, 0, + w->core.width, w->core.height, w->sb.shadowThickness); - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); - + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); } -/************************************************************************ -** -** Method functions -** -*/ +/*-------------------------- Method Functions ---------------------------*/ static void Initialize (Widget treq, Widget tnew, ArgList args, Cardinal *num_args) @@ -1374,8 +1275,6 @@ Display *dpy = XtDisplay ((Widget) w); Window win = RootWindowOfScreen (DefaultScreenOfDisplay (dpy)); - DBUG (fprintf (stderr, "Initialize\n")); - if (request->core.width == 0) w->core.width += (VERT (w) ? 12 : 25); if (request->core.height == 0) w->core.height += (VERT (w) ? 25 : 12); @@ -1386,6 +1285,7 @@ w->sb.ss = 0; w->sb.below = 0; w->sb.armed = ARM_NONE; + w->sb.forced_scroll = FORCED_SCROLL_NONE; if (w->sb.shadowThickness > 5) w->sb.shadowThickness = 5; @@ -1417,8 +1317,6 @@ XlwScrollBarWidget w = (XlwScrollBarWidget) widget; Display *dpy = XtDisplay ((Widget) w); - DBUG (fprintf (stderr, "Destroy\n")); - XtReleaseGC (widget, w->sb.bottomShadowGC); XtReleaseGC (widget, w->sb.topShadowGC); XtReleaseGC (widget, w->sb.backgroundGC); @@ -1426,7 +1324,10 @@ XFreePixmap (dpy, w->sb.grayPixmap); if (w->sb.timerActive) - XtRemoveTimeOut (w->sb.timerId); + { + XtRemoveTimeOut (w->sb.timerId); + w->sb.timerActive = False; /* Should be a no-op, but you never know */ + } } static void @@ -1437,8 +1338,6 @@ Window win; XSetWindowAttributes win_attr; - DBUG (fprintf (stderr, "Realize\n")); - (*coreClassRec.core_class.realize)(widget, valuemask, attr); win = XtWindow ((Widget) w); @@ -1448,7 +1347,7 @@ XSetWindowBackground (dpy, win, w->sb.troughColor); /* Change bit gravity so widget is not cleared on resize */ - win_attr.bit_gravity = NorthWestGravity; + win_attr.bit_gravity = NorthWestGravity; XChangeWindowAttributes (dpy, win, CWBitGravity , &win_attr); } @@ -1466,11 +1365,17 @@ seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); - /*redraw_everything(w, NULL, True);*/ + /* redraw_everything (w, NULL, True); */ w->sb.fullRedrawNext = True; /* Force expose event */ - XClearArea (dpy, win, widget_x(w), widget_y(w), 1, 1, True); + XClearArea (dpy, win, widget_x (w), widget_y (w), 1, 1, True); + } + + if (w->sb.timerActive) + { + XtRemoveTimeOut (w->sb.timerId); + w->sb.timerActive = False; } } @@ -1484,13 +1389,9 @@ if (XtIsRealized (widget)) { if (w->sb.fullRedrawNext) - { - redraw_everything (w, NULL, True); - } + redraw_everything (w, NULL, True); else - { - redraw_everything (w, region, False); - } + redraw_everything (w, region, False); w->sb.fullRedrawNext = False; } } @@ -1542,9 +1443,7 @@ } if (cur->sb.orientation != w->sb.orientation) - { - do_redisplay = True; - } + do_redisplay = True; if (cur->sb.minimum != w->sb.minimum || @@ -1558,7 +1457,7 @@ if (XtIsRealized ((Widget) w)) { seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); } } @@ -1587,7 +1486,6 @@ int increment, int pageIncrement, Boolean notify) { XlwScrollBarWidget w = (XlwScrollBarWidget) widget; - int last_value; if (w && XtClass ((Widget) w) == xlwScrollBarWidgetClass && (w->sb.value != value || @@ -1595,6 +1493,8 @@ w->sb.increment != increment || w->sb.pageIncrement != pageIncrement)) { + int last_value = w->sb.value; + w->sb.value = value; w->sb.sliderSize = sliderSize; w->sb.increment = increment; @@ -1605,55 +1505,43 @@ if (XtIsRealized (widget)) { seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); - - last_value = w->sb.value; - w->sb.value = value_from_pixel (w, w->sb.above); - verify_values (w); + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); if (w->sb.value != last_value && notify) - { - call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, 0, NULL); - } + call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, 0, NULL); } } } -/************************************************************************ -** -** Action functions -** -*/ +/*-------------------------- Action Functions ---------------------------*/ static void timer (XtPointer data, XtIntervalId *id) { XlwScrollBarWidget w = (XlwScrollBarWidget) data; - int reason, last_value; - w->sb.timerActive = False; if (w->sb.armed != ARM_NONE) { - last_value = w->sb.value; - reason = XmCR_NONE; + int last_value = w->sb.value; + int reason = XmCR_NONE; switch (w->sb.armed) { case ARM_PAGEUP: - w->sb.value = safe_subtract (w->sb.value, w->sb.pageIncrement); + decrement_value (w, w->sb.pageIncrement); reason = XmCR_PAGE_DECREMENT; break; case ARM_PAGEDOWN: - w->sb.value = safe_add (w->sb.value, w->sb.pageIncrement); + increment_value (w, w->sb.pageIncrement); reason = XmCR_PAGE_INCREMENT; break; case ARM_UP: - w->sb.value = safe_subtract (w->sb.value, w->sb.increment); + decrement_value (w, w->sb.increment); reason = XmCR_DECREMENT; break; case ARM_DOWN: - w->sb.value = safe_add (w->sb.value, w->sb.increment); + increment_value (w, w->sb.increment); reason = XmCR_INCREMENT; break; } @@ -1663,7 +1551,7 @@ if (last_value != w->sb.value) { seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); call_callbacks (w, reason, w->sb.value, 0, NULL); @@ -1676,180 +1564,97 @@ } } -static int +static button_where what_button (XlwScrollBarWidget w, int mouse_x, int mouse_y) { - int x, y, width, height, arrow_height_top, arrow_height_bottom; - int where; + int width = widget_w (w); + int height = widget_h (w); + int arrow_height = arrow_h (w); - x = widget_x (w); - y = widget_y (w); - width = widget_w (w); - height = widget_h (w); + mouse_x -= widget_x (w); + mouse_y -= widget_y (w); -#if 0 - arrow_height = w->sb.showArrows ? arrow_h (w) : 0; -#endif + if (mouse_x < 0 || mouse_x >= width || + mouse_y < 0 || mouse_y >= height) + return BUTTON_NONE; + if (w->sb.showArrows) { + if (mouse_y >= (height -= arrow_height)) + return BUTTON_DOWN_ARROW; + if (arrow_same_end (w)) { - arrow_height_top = 0; - arrow_height_bottom = 2 * arrow_h (w); + if (mouse_y >= (height -= arrow_height)) + return BUTTON_UP_ARROW; } else - { - arrow_height_top = arrow_height_bottom = arrow_h (w); - } + if ( (mouse_y -= arrow_height) < 0) + return BUTTON_UP_ARROW; } - else - { - arrow_height_top = arrow_height_bottom = 0; - } - - where = BUTTON_NONE; + + if ( (mouse_y -= w->sb.above) < 0) + return BUTTON_TROUGH_ABOVE; - if (mouse_x > x && mouse_x < (x + width)) - { - if (mouse_y > (y + arrow_height_top) && - mouse_y < (y + height - arrow_height_bottom)) - { - if (mouse_y < (y + w->sb.above + arrow_height_top)) - { - where = BUTTON_TROUGH_ABOVE; - } - else if (mouse_y > (y + w->sb.above + w->sb.ss + arrow_height_top)) - { - where = BUTTON_TROUGH_BELOW; - } - else - { - where = BUTTON_KNOB; - } - } - else if (arrow_same_end (w)) - { - if (mouse_y > (y + height - arrow_height_bottom + 1) && - mouse_y < (y + height)) - { - if (mouse_y < (y + height - arrow_height_bottom/2)) - { - where = BUTTON_UP_ARROW; - } - else - { - where = BUTTON_DOWN_ARROW; - } - } - } - else - { - if (mouse_y > y && mouse_y < (y + arrow_height_top)) - { - where = BUTTON_UP_ARROW; - } - else if (mouse_y > (y + height - arrow_height_bottom + 1) && - mouse_y < (y + height)) - { - where = BUTTON_DOWN_ARROW; - } - } - } -#if 0 - if (mouse_x > x && mouse_x < (x + width)) - { - if (mouse_y > (y + arrow_height) && mouse_y < (y + height - arrow_height)) - { - if (mouse_y < (y+w->sb.above+arrow_height)) - { - where = BUTTON_TROUGH_ABOVE; - } - else if (mouse_y > (y + w->sb.above + w->sb.ss + arrow_height)) - { - where = BUTTON_TROUGH_BELOW; - } - else - { - where = BUTTON_KNOB; - } - } - else if (mouse_y > y && mouse_y < (y + arrow_height)) - { - where = BUTTON_UP_ARROW; - } - else if (mouse_y > (y + height - arrow_height + 1) && - mouse_y < (y + height)) - { - where = BUTTON_DOWN_ARROW; - } - } -#endif - return where; + if ( (mouse_y -= w->sb.ss) < 0) + return BUTTON_SLIDER; + + return BUTTON_TROUGH_BELOW; } -#define FORCED_SCROLL_NONE 0 -#define FORCED_SCROLL_DOWNRIGHT 1 -#define FORCED_SCROLL_UPLEFT 2 - -int forced_scroll_flag = FORCED_SCROLL_NONE; - static void PageDownOrRight (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) { - forced_scroll_flag = FORCED_SCROLL_DOWNRIGHT; + XlwScrollBarWidget w = (XlwScrollBarWidget) widget; + w->sb.forced_scroll = FORCED_SCROLL_DOWNRIGHT; Select (widget, event, parms, num_parms); - forced_scroll_flag = FORCED_SCROLL_NONE; + w->sb.forced_scroll = FORCED_SCROLL_NONE; } static void PageUpOrLeft (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) { - forced_scroll_flag = FORCED_SCROLL_UPLEFT; + XlwScrollBarWidget w = (XlwScrollBarWidget) widget; + w->sb.forced_scroll = FORCED_SCROLL_UPLEFT; Select (widget, event, parms, num_parms); - forced_scroll_flag = FORCED_SCROLL_NONE; + w->sb.forced_scroll = FORCED_SCROLL_NONE; } static void Select (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) { XlwScrollBarWidget w = (XlwScrollBarWidget) widget; - int mouse_x, mouse_y; - int reason, last_value; - int sb_button; - - DBUG (fprintf (stderr, "Select:\n")); + button_where sb_button; - mouse_x = event_x (w, event); - mouse_y = event_y (w, event); + int mouse_x = event_x (w, event); + int mouse_y = event_y (w, event); - w->sb.savedValue = w->sb.value; - - last_value = w->sb.value; - reason = XmCR_NONE; + int last_value = w->sb.savedValue = w->sb.value; + int reason = XmCR_NONE; XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync, event->xbutton.time); sb_button = what_button (w, mouse_x, mouse_y); - if (forced_scroll_flag != FORCED_SCROLL_NONE) + if (w->sb.forced_scroll != FORCED_SCROLL_NONE) { - switch (sb_button) + switch (sb_button) { case BUTTON_TROUGH_ABOVE: case BUTTON_TROUGH_BELOW: - case BUTTON_KNOB: + case BUTTON_SLIDER: sb_button= BUTTON_NONE; /* cause next switch to fall through */ - if (forced_scroll_flag == FORCED_SCROLL_UPLEFT) + if (w->sb.forced_scroll == FORCED_SCROLL_UPLEFT) { - w->sb.value = safe_subtract (w->sb.value, w->sb.pageIncrement); + decrement_value (w, w->sb.pageIncrement); w->sb.armed = ARM_PAGEUP; reason = XmCR_PAGE_DECREMENT; break; } - else if (forced_scroll_flag == FORCED_SCROLL_DOWNRIGHT) + else if (w->sb.forced_scroll == FORCED_SCROLL_DOWNRIGHT) { - w->sb.value = safe_add (w->sb.value, w->sb.pageIncrement); + increment_value (w, w->sb.pageIncrement); w->sb.armed = ARM_PAGEDOWN; reason = XmCR_PAGE_INCREMENT; break; @@ -1861,48 +1666,46 @@ switch (sb_button) { case BUTTON_TROUGH_ABOVE: - w->sb.value = safe_subtract (w->sb.value, w->sb.pageIncrement); + decrement_value (w, w->sb.pageIncrement); w->sb.armed = ARM_PAGEUP; reason = XmCR_PAGE_DECREMENT; break; case BUTTON_TROUGH_BELOW: - w->sb.value = safe_add (w->sb.value, w->sb.pageIncrement); + increment_value (w, w->sb.pageIncrement); w->sb.armed = ARM_PAGEDOWN; reason = XmCR_PAGE_INCREMENT; break; - case BUTTON_KNOB: + case BUTTON_SLIDER: w->sb.lastY = mouse_y; - w->sb.armed = ARM_KNOB; - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); + w->sb.armed = ARM_SLIDER; + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); break; case BUTTON_UP_ARROW: if (event->xbutton.state & ControlMask) { - w->sb.value = INT_MIN; - w->sb.armed = ARM_UP; + w->sb.value = w->sb.minimum; reason = XmCR_TO_TOP; } else { - w->sb.value = safe_subtract (w->sb.value, w->sb.increment); - w->sb.armed = ARM_UP; + decrement_value (w, w->sb.increment); reason = XmCR_DECREMENT; } + w->sb.armed = ARM_UP; redraw_up_arrow (w, True, False); break; case BUTTON_DOWN_ARROW: if (event->xbutton.state & ControlMask) { - w->sb.value = INT_MAX; - w->sb.armed = ARM_DOWN; + w->sb.value = w->sb.maximum; reason = XmCR_TO_BOTTOM; } else { - w->sb.value = safe_add (w->sb.value, w->sb.increment); - w->sb.armed = ARM_DOWN; + increment_value (w, w->sb.increment); reason = XmCR_INCREMENT; } + w->sb.armed = ARM_DOWN; redraw_down_arrow (w, True, False); break; } @@ -1912,7 +1715,7 @@ if (last_value != w->sb.value) { seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); call_callbacks (w, reason, w->sb.value, mouse_y, event); @@ -1933,56 +1736,29 @@ Drag (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) { XlwScrollBarWidget w = (XlwScrollBarWidget) widget; - int diff; - int height, mouse_y; - int last_value, last_above; - DBUG (fprintf (stderr, "Drag:\n")); - - if (w->sb.armed == ARM_KNOB) + if (w->sb.armed == ARM_SLIDER) { - height = widget_h (w); - if (w->sb.showArrows) height -= (2 * arrow_h (w)); - - mouse_y = event_y (w, event); + int mouse_y = event_y (w, event); + int diff = mouse_y - w->sb.lastY; - diff = mouse_y - w->sb.lastY; - - last_above = w->sb.above; - last_value = w->sb.value; - - if (diff < 0) + if (diff < -(w->sb.above)) /* up */ { - /* up */ - w->sb.above -= (-diff); - if (w->sb.above < 0) - { - mouse_y = (mouse_y - w->sb.above); - w->sb.above = 0; - diff = 0; - w->sb.below = height - w->sb.ss; - } - w->sb.below -= diff; - CHECK (w); + mouse_y -= (diff + w->sb.above); + diff = -(w->sb.above); } - else if (diff > 0) + else if (diff > w->sb.below) /* down */ { - /* down */ - w->sb.above += diff; - if (w->sb.above + w->sb.ss > height) - { - mouse_y = height + (mouse_y - (w->sb.above + w->sb.ss)); - w->sb.above = height - w->sb.ss; - diff = 0; - w->sb.below = 0; - } - w->sb.below -= diff; - CHECK (w); + mouse_y -= (diff - w->sb.below); + diff = w->sb.below; } - if (last_above != w->sb.above) + if (diff) { - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); + w->sb.above += diff; + w->sb.below -= diff; + + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); w->sb.lastY = mouse_y; @@ -1990,8 +1766,7 @@ verify_values (w); CHECK (w); - if (w->sb.value != last_value) - call_callbacks (w, XmCR_DRAG, w->sb.value, event_y (w, event), event); + call_callbacks (w, XmCR_DRAG, w->sb.value, event_y (w, event), event); } } CHECK (w); @@ -2002,14 +1777,12 @@ { XlwScrollBarWidget w = (XlwScrollBarWidget) widget; - DBUG (fprintf (stderr, "EndDrag:\n")); - switch (w->sb.armed) { - case ARM_KNOB: + case ARM_SLIDER: call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, event_y (w, event), event); w->sb.armed = ARM_NONE; - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); break; case ARM_UP: redraw_up_arrow (w, False, False); @@ -2028,21 +1801,21 @@ Jump (Widget widget, XEvent *event, String *parms, Cardinal *num_parms) { XlwScrollBarWidget w = (XlwScrollBarWidget) widget; - int x, y, width, height, mouse_x, mouse_y; - int arrow_height; - int last_above, last_value; + int last_value; - DBUG (fprintf (stderr, "Jump:\n")); + int mouse_x = event_x (w, event); + int mouse_y = event_y (w, event); - x = widget_x (w); - y = widget_y (w); - width = widget_w (w); - height = widget_h (w); + int scroll_region_y = widget_y (w); + int scroll_region_h = widget_h (w); - mouse_x = event_x (w, event); - mouse_y = event_y (w, event); - - arrow_height = w->sb.showArrows ? arrow_h (w) : 0; + if (w->sb.showArrows) + { + int arrow_height = arrow_h (w); + scroll_region_h -= 2 * arrow_height; + if (!arrow_same_end (w)) + scroll_region_y += arrow_height; + } XtGrabKeyboard ((Widget) w, False, GrabModeAsync, GrabModeAsync, event->xbutton.time); @@ -2051,45 +1824,31 @@ { case BUTTON_TROUGH_ABOVE: case BUTTON_TROUGH_BELOW: - case BUTTON_KNOB: + case BUTTON_SLIDER: w->sb.savedValue = w->sb.value; - height -= (2*arrow_height); - y += arrow_height; - - last_above = w->sb.above; last_value = w->sb.value; - w->sb.armed = ARM_KNOB; - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); - - w->sb.above = mouse_y - (w->sb.ss / 2) - arrow_height; + w->sb.above = mouse_y - (w->sb.ss / 2) - scroll_region_y; if (w->sb.above < 0) - { - w->sb.above = 0; - } - else if (w->sb.above + w->sb.ss > height) - { - w->sb.above = height - w->sb.ss; - } - w->sb.below = (height - (w->sb.ss + w->sb.above)); + w->sb.above = 0; + else if (w->sb.above + w->sb.ss > scroll_region_h) + w->sb.above = scroll_region_h - w->sb.ss; + + w->sb.below = scroll_region_h - w->sb.ss - w->sb.above; - if (last_above != w->sb.above) - { - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); - - w->sb.value = value_from_pixel (w, w->sb.above); - verify_values (w); - CHECK (w); + w->sb.armed = ARM_SLIDER; + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); - w->sb.lastY = mouse_y; - w->sb.lastY = w->sb.above + arrow_height + (w->sb.ss / 2); + w->sb.value = value_from_pixel (w, w->sb.above); + verify_values (w); + CHECK (w); - if (w->sb.value != last_value) - { - call_callbacks (w, XmCR_DRAG, w->sb.value, event_y (w, event), event); - } - } + w->sb.lastY = mouse_y; + + if (w->sb.value != last_value) + call_callbacks (w, XmCR_DRAG, w->sb.value, mouse_y, event); + break; } CHECK (w); @@ -2100,8 +1859,6 @@ { XlwScrollBarWidget w = (XlwScrollBarWidget) widget; - DBUG (fprintf (stderr, "Abort:\n")); - if (w->sb.armed != ARM_NONE) { if (w->sb.value != w->sb.savedValue) @@ -2109,7 +1866,7 @@ w->sb.value = w->sb.savedValue; seg_pixel_sizes (w, &w->sb.above, &w->sb.ss, &w->sb.below); - draw_knob (w, w->sb.above, w->sb.ss, w->sb.below); + draw_slider (w, w->sb.above, w->sb.ss, w->sb.below); call_callbacks (w, XmCR_VALUE_CHANGED, w->sb.value, event_y (w, event), event);