aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/obm/ObmW/Slider2.man
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/x11iraf/obm/ObmW/Slider2.man')
-rw-r--r--vendor/x11iraf/obm/ObmW/Slider2.man1068
1 files changed, 1068 insertions, 0 deletions
diff --git a/vendor/x11iraf/obm/ObmW/Slider2.man b/vendor/x11iraf/obm/ObmW/Slider2.man
new file mode 100644
index 00000000..399250bb
--- /dev/null
+++ b/vendor/x11iraf/obm/ObmW/Slider2.man
@@ -0,0 +1,1068 @@
+.\"remove .ig hn for full docs
+.de hi
+.ig eh
+..
+.de eh
+..
+.TH "" 3 "" "Version 3.0" "Free Widget Foundation"
+.SH NAME
+XfwfSlider2
+.SH DESCRIPTION
+A Slider2 widget consists of a rectangular area in which a `thumb' can be
+moved about. A Slider2 is typically used to pan or scroll another window; as
+such is can replace two scrollbars. The thumb can be dragged with the mouse,
+or the mouse can be clicked next to the thumb, to move it in the direction of
+the mouse. The thumb may contain one or more lines of text, although there
+is usually no room for more than one or two words.
+
+The widget has three callbacks. The thumb position and size are not
+controled by resources, but by calling a function.
+
+.SS "Public variables"
+
+.ps-2
+.TS
+center box;
+cBsss
+lB|lB|lB|lB
+l|l|l|l.
+XfwfSlider2
+Name Class Type Default
+XtNthumbColor XtCThumbColor Pixel XtDefaultBackground
+XtNthumbPixmap XtCThumbPixmap Pixmap NULL
+XtNminsize XtCMinsize Dimension 20
+XtNthumbFrameWidth XtCThumbFrameWidth Dimension 2
+XtNthumbFrameType XtCThumbFrameType FrameType XfwfRaised
+XtNscrollCallback XtCScrollCallback Callback NULL
+XtNscrollResponse XtCScrollResponse XTCallbackProc scroll_response
+
+.TE
+.ps
+
+.TP
+.I "XtNthumbColor"
+The color of the thumb is by default set to the default background
+color of the display, but it can be changed with the \fIthumbColor\fP
+resource. It is also possible to tile the thumb with a pixmap, see
+below.
+
+
+
+.hi
+
+.nf
+Pixel thumbColor = <String>XtDefaultBackground
+.fi
+
+.eh
+
+.TP
+.I "XtNthumbPixmap"
+Instead of a color, the thumb can also be tiled with a pixmap.
+However, there is currently no converter from string to pixmap, so
+this resource can only be set from the application, not from resource
+files.
+
+If both \fIthumbColor\fP and \fIthumbPixmap\fP are set, the pixmap takes
+precedence.
+
+
+
+.hi
+
+.nf
+Pixmap thumbPixmap = NULL
+.fi
+
+.eh
+
+.TP
+.I "XtNminsize"
+The minimum size of the thumb is by default 20 pixels. It can be set
+with the \fIminsize\fP resource.
+
+
+
+.hi
+
+.nf
+Dimension minsize = 20
+.fi
+
+.eh
+
+.TP
+.I "XtNthumbFrameWidth"
+The width of the frame around the thumb is independent of the frame
+around the whole widget. It can be set with \fIthumbFrameWidth\fP.
+
+
+
+.hi
+
+.nf
+Dimension thumbFrameWidth = 2
+.fi
+
+.eh
+
+.TP
+.I "XtNthumbFrameType"
+The style of the frame around the thumb is set with
+\fIthumbFrameType\fP. By default, it is \fIXfwfRaised\fP. Note that there are no
+resources to control the shadow scheme of the thumb independently from
+that of the outer frame. That means that the resources \fIshadowScheme\fP,
+\fItopShadowColor\fP, \fItopShadowStipple\fP, etc, also influence the frame of the
+thumb.
+
+
+
+.hi
+
+.nf
+FrameType thumbFrameType = XfwfRaised
+.fi
+
+.eh
+
+.TP
+.I "XtNscrollCallback"
+The routines on the callback list are called whenever the user
+manipulates the slider and also when the Slider2 receives a call on
+its \fIscrollResponse\fP function with a reason other than \fIXfwfSNotify\fP.
+
+The \fIcall_data\fP parameter of the callback routines is a pointer
+to an \fIXfwfScrollInfo\fP structure, which looks like this: \fItypedef
+struct _XfwfScrollInfo { XfwfSReason reason; XfwfSFlags flags; float
+vpos, vsize, hpos, hsize;} XfwfScrollInfo\fP.
+
+
+
+.hi
+
+.nf
+<Callback> XtCallbackList scrollCallback = NULL
+.fi
+
+.eh
+
+.TP
+.I "XtNscrollResponse"
+The Slider2 widget provides has a method for dealing with scroll
+requests from the application or from other widgets. A pointer to that
+function can be retrieved with \fIXtGetValues\fP as the resource
+\fIXtNscrollResponse\fP. This resource can only be queried, not set.
+
+
+
+.hi
+
+.nf
+XtCallbackProc scrollResponse = scroll_response
+.fi
+
+.eh
+
+.TP
+.I "XtNframeWidth"
+The default frame width is changed from 0 to 2.
+
+
+
+.hi
+
+.nf
+ frameWidth = 2
+.fi
+
+.eh
+
+.TP
+.I "XtNframeType"
+The default frame type is now \fIXfwfSunken\fP.
+
+
+
+.hi
+
+.nf
+ frameType = XfwfSunken
+.fi
+
+.eh
+
+.ps-2
+.TS
+center box;
+cBsss
+lB|lB|lB|lB
+l|l|l|l.
+XfwfLabel
+Name Class Type Default
+XtNlabel XtCLabel String NULL
+XtNtablist XtCTablist String NULL
+XtNfont XtCFont FontStruct XtDefaultFont
+XtNforeground XtCForeground Pixel XtDefaultForeground
+XtNalignment XtCAlignment Alignment 0
+XtNtopMargin XtCTopMargin Dimension 2
+XtNbottomMargin XtCBottomMargin Dimension 2
+XtNleftMargin XtCLeftMargin Dimension 2
+XtNrightMargin XtCRightMargin Dimension 2
+XtNshrinkToFit XtCShrinkToFit Boolean False
+XtNrvStart XtCRvStart Int 0
+XtNrvLength XtCRvLength Int 0
+
+.TE
+.ps
+
+.ps-2
+.TS
+center box;
+cBsss
+lB|lB|lB|lB
+l|l|l|l.
+XfwfBoard
+Name Class Type Default
+XtNabs_x XtCAbs_x Position 0
+XtNrel_x XtCRel_x Float "0.0"
+XtNabs_y XtCAbs_y Position 0
+XtNrel_y XtCRel_y Float "0.0"
+XtNabs_width XtCAbs_width Position 0
+XtNrel_width XtCRel_width Float "1.0"
+XtNabs_height XtCAbs_height Position 0
+XtNrel_height XtCRel_height Float "1.0"
+XtNhunit XtCHunit Float "1.0"
+XtNvunit XtCVunit Float "1.0"
+XtNlocation XtCLocation String NULL
+
+.TE
+.ps
+
+.ps-2
+.TS
+center box;
+cBsss
+lB|lB|lB|lB
+l|l|l|l.
+XfwfFrame
+Name Class Type Default
+XtNcursor XtCCursor Cursor None
+XtNframeType XtCFrameType FrameType XfwfRaised
+XtNframeWidth XtCFrameWidth Dimension 0
+XtNouterOffset XtCOuterOffset Dimension 0
+XtNinnerOffset XtCInnerOffset Dimension 0
+XtNshadowScheme XtCShadowScheme ShadowScheme XfwfAuto
+XtNtopShadowColor XtCTopShadowColor Pixel compute_topcolor
+XtNbottomShadowColor XtCBottomShadowColor Pixel compute_bottomcolor
+XtNtopShadowStipple XtCTopShadowStipple Bitmap NULL
+XtNbottomShadowStipple XtCBottomShadowStipple Bitmap NULL
+
+.TE
+.ps
+
+.ps-2
+.TS
+center box;
+cBsss
+lB|lB|lB|lB
+l|l|l|l.
+XfwfCommon
+Name Class Type Default
+XtNtraversalOn XtCTraversalOn Boolean True
+XtNhighlightThickness XtCHighlightThickness Dimension 2
+XtNhighlightColor XtCHighlightColor Pixel XtDefaultForeground
+XtNhighlightPixmap XtCHighlightPixmap Pixmap None
+XtNnextTop XtCNextTop Callback NULL
+XtNuserData XtCUserData Pointer NULL
+
+.TE
+.ps
+
+.ps-2
+.TS
+center box;
+cBsss
+lB|lB|lB|lB
+l|l|l|l.
+Composite
+Name Class Type Default
+XtNchildren XtCChildren WidgetList NULL
+insertPosition XtCInsertPosition XTOrderProc NULL
+numChildren XtCNumChildren Cardinal 0
+
+.TE
+.ps
+
+.ps-2
+.TS
+center box;
+cBsss
+lB|lB|lB|lB
+l|l|l|l.
+Core
+Name Class Type Default
+XtNx XtCX Position 0
+XtNy XtCY Position 0
+XtNwidth XtCWidth Dimension 0
+XtNheight XtCHeight Dimension 0
+borderWidth XtCBorderWidth Dimension 0
+XtNcolormap XtCColormap Colormap NULL
+XtNdepth XtCDepth Int 0
+destroyCallback XtCDestroyCallback XTCallbackList NULL
+XtNsensitive XtCSensitive Boolean True
+XtNtm XtCTm XTTMRec NULL
+ancestorSensitive XtCAncestorSensitive Boolean False
+accelerators XtCAccelerators XTTranslations NULL
+borderColor XtCBorderColor Pixel 0
+borderPixmap XtCBorderPixmap Pixmap NULL
+background XtCBackground Pixel 0
+backgroundPixmap XtCBackgroundPixmap Pixmap NULL
+mappedWhenManaged XtCMappedWhenManaged Boolean True
+XtNscreen XtCScreen Screen * NULL
+
+.TE
+.ps
+
+.SS "Exports"
+
+The \fIscroll.h\fP header file is needed for the \fIXfwfScrollInfo\fP
+structure.
+
+.nf
+
+.B incl
+ <Xfwf/scroll.h>
+.fi
+
+The current size and position of the thumb can be queried with the
+function \fIgetThumb\fP. It fills the \fIinfo\fP argument with the current values.
+
+.nf
+XfwfGetThumb( $, XfwfScrollInfo * info)
+.fi
+
+.hi
+{
+ if (! XtIsSubclass($, xfwfSlider2WidgetClass))
+ XtError("XfwfGetThumb called with incorrect widget type");
+ info->reason = XfwfSNotify;
+ info->flags = XFWF_VPOS | XFWF_VSIZE | XFWF_HPOS | XFWF_HSIZE;
+ info->vpos = $thumb_y;
+ info->vsize = $thumb_ht;
+ info->hpos = $thumb_x;
+ info->hsize = $thumb_wd;
+}
+.eh
+
+To change the position of the thumb, a call to \fImoveThumb\fP can be
+used. The arguments must be two numbers between 0 and 1. The thumb
+is moved with \fIXCopyArea\fP.
+
+This is a convenience function. The standard interface is through the
+\fIscrollResponse\fP resource. In the Slider2 widget, that resource is
+connected to the \fIscroll_response\fP method.
+
+.nf
+XfwfMoveThumb( $, double x, double y)
+.fi
+
+.hi
+{
+ XfwfScrollInfo info;
+
+ if (! XtIsSubclass($, xfwfSlider2WidgetClass))
+ XtError("XfwfMoveThumb called with incorrect widget type");
+ if (x < 0.0 || x > 1.0 || y < 0.0 || y > 1.0)
+ XtError("XfwfMoveThumb called with incorrect arguments");
+
+ info.flags = XFWF_VPOS | XFWF_HPOS;
+ info.reason = XfwfSNotify;
+ info.vpos = y;
+ info.hpos = x;
+ $scroll_response(NULL, $, info);
+}
+.eh
+
+Resizing the thumb is done with \fIresizeThumb\fP. The two arguments
+must be between 0 and 1.
+
+This is a convenience function. The standard interface is through the
+\fIscrollResponse\fP resource. In the Slider2 widget, that resource is
+connected to the \fIscroll_response\fP method.
+
+.nf
+XfwfResizeThumb( $, double wd, double ht)
+.fi
+
+.hi
+{
+ XfwfScrollInfo info;
+
+ if (! XtIsSubclass($, xfwfSlider2WidgetClass))
+ XtError("XfwfResizeThumb called with incorrect widget type");
+ if (wd < 0.0 || wd > 1.0 || ht < 0.0 || ht > 1.0)
+ XtError("XfwfResizeThumb called with incorrect arguments");
+
+ info.reason = XfwfSNotify;
+ info.flags = XFWF_VSIZE | XFWF_HSIZE;
+ info.vsize = ht;
+ info.hsize = wd;
+ $scroll_response(NULL, $, info);
+}
+.eh
+
+.SS "Translations"
+
+The \fIstart\fP action should be bound to a mouse button press, because it
+needs the coordinates of the mouse. The \fIdrag\fP action is bound to mouse
+movement and the \fIfinish\fP action is normally bound to a release of the
+mouse button.
+
+.nf
+<Btn1Down>: start()
+.fi
+
+.nf
+<Btn1Motion>: drag()
+.fi
+
+.nf
+<Btn1Up>: finish()
+.fi
+
+.hi
+.SS "Actions"
+
+.TP
+.I "start
+
+The \fIstart\fP action checks the position of the mouse and if it was
+outside the thumb, it calls the \fIscrollCallback\fP. Otherwise, it only
+records the position. Note that the mouse may have been to the left as
+well as below the thumb, causing the callbacks to be called twice.
+
+.hi
+
+.nf
+void start($, XEvent* event, String* params, Cardinal* num_params)
+{
+ Dimension w, h;
+ Position x, y;
+ XfwfScrollInfo info;
+ Boolean outside = False;
+
+ if (event->type != ButtonPress event->type != ButtonRelease
+ event->type != MotionNotify)
+ XtError("The start action must be bound to a mouse event");
+ $compute_thumb($, x, y, w, h);
+ if (event->xbutton.x < x) { /* Left of thumb */
+ info.reason = XfwfSPageLeft;
+ info.flags = XFWF_HPOS; /* Suggest a value: */
+ info.hpos = max(0.0, $thumb_x - $thumb_wd);
+ outside = True;
+ XtCallCallbackList($, $scrollCallback, info);
+ }
+ if (event->xbutton.x >= x + w) { /* Right of thumb */
+ info.reason = XfwfSPageRight;
+ info.flags = XFWF_HPOS; /* Suggest a value: */
+ info.hpos = min(1.0, $thumb_x + $thumb_wd);
+ outside = True;
+ XtCallCallbackList($, $scrollCallback, info);
+ }
+ if (event->xbutton.y < y) { /* Above thumb */
+ info.reason = XfwfSPageUp;
+ info.flags = XFWF_VPOS; /* Suggest a value: */
+ info.vpos = max(0.0, $thumb_y - $thumb_ht);
+ outside = True;
+ XtCallCallbackList($, $scrollCallback, info);
+ }
+ if (event->xbutton.y >= y + h) { /* Below thumb */
+ info.reason = XfwfSPageDown;
+ info.flags = XFWF_VPOS; /* Suggest a value: */
+ info.vpos = min(1.0, $thumb_y + $thumb_ht);
+ outside = True;
+ XtCallCallbackList($, $scrollCallback, info);
+ }
+ if (! outside) { /* Inside the thumb */
+ $drag_in_progress = True;
+ $m_delta_x = x - event->xbutton.x;
+ $m_delta_y = y - event->xbutton.y;
+ }
+}
+.fi
+
+.eh
+
+.TP
+.I "finish
+
+The \fIfinish\fP action does nothing if this is the end of a
+click outside the thumb. The callbacks for this event have already
+been called.
+
+If this is the end of a drag action, we reset the flag
+\fIdrag_in_progress\fP to False and call the drop callbacks.
+
+.hi
+
+.nf
+void finish($, XEvent* event, String* params, Cardinal* num_params)
+{
+ XfwfScrollInfo info;
+
+ if ($drag_in_progress) {
+ $drag_in_progress = False;
+ info.reason = XfwfSMove;
+ info.flags = XFWF_VPOS | XFWF_HPOS;
+ info.hpos = $thumb_x;
+ info.vpos = $thumb_y;
+ XtCallCallbackList($, $scrollCallback, info);
+ }
+}
+.fi
+
+.eh
+
+.TP
+.I "drag
+
+An application that can draw fast enough, may wish to redraw with
+every movement of the thumb, instead of only at the end of the drag
+action. The drag callback is provided for this purpose. It is called
+in the same way as the drop callback, with the current relative
+position of the thumb.
+
+.hi
+
+.nf
+void drag($, XEvent* event, String* params, Cardinal* num_params)
+{
+ XfwfScrollInfo info;
+ Dimension wd, ht, fwd, fht;
+ Position oldx, oldy, newx, newy, fx, fy;
+ float dum1, dum2;
+
+ if (! $drag_in_progress) return;
+ if (event->type != ButtonPress event->type != ButtonRelease
+ event->type != MotionNotify)
+ XtError("The drag action must be bound to a mouse event");
+ $compute_thumb($, oldx, oldy, wd, ht);
+ newx = event->xbutton.x + $m_delta_x;
+ newy = event->xbutton.y + $m_delta_y;
+ $compute_info($, newx, newy, wd, ht, $thumb_x, $thumb_y,dum1,dum2);
+ $move_thumb($, oldx, oldy, wd, ht, newx, newy);
+ info.reason = XfwfSDrag;
+ info.flags = XFWF_VPOS | XFWF_HPOS;
+ info.hpos = $thumb_x;
+ info.vpos = $thumb_y;
+ XtCallCallbackList($, $scrollCallback, info);
+}
+.fi
+
+.eh
+
+.hi
+
+.hi
+.SH "Importss"
+
+.nf
+
+.B incl
+ "stip4.bm"
+.fi
+
+.nf
+
+.B incl
+ <stdio.h>
+.fi
+
+.hi
+
+.hi
+.SS "Private variables"
+
+The position and size of the thumb are controlled by four variables
+that can assume values between 0 and 1. If \fIthumb_x\fP is 0, the thumb
+is located against the left side, if it is 1, the thumb is put against
+the right side.
+
+If \fIthumb_wd\fP is 1, the thumb is as large as possible, if it is 0, it
+will have its minimum width \fIminsize\fP.
+
+.nf
+float thumb_x
+.fi
+
+.nf
+float thumb_y
+.fi
+
+.nf
+float thumb_wd
+.fi
+
+.nf
+float thumb_ht
+.fi
+
+A boolean variable is set to when a draggin action has started, but
+not yet finished.
+
+.nf
+Boolean drag_in_progress
+.fi
+
+During a drag operation, the thumb is kept at a fixed offset from
+the moving mouse. The offset is stored in two local variables.
+
+.nf
+int m_delta_x
+.fi
+
+.nf
+int m_delta_y
+.fi
+
+We also need three more GC's for the thumb and the light and dark
+parts of the thumb's frame.
+
+.nf
+GC thumbgc
+.fi
+
+.nf
+GC thumblightgc
+.fi
+
+.nf
+GC thumbdarkgc
+.fi
+
+.hi
+
+.hi
+.SH "Class variables"
+
+The Core variable \fIcompress_exposure\fP is OR'ed with
+\fIXtExposeGraphicsExpose\fP, in order to get graphics expose events delivered
+to the \fIexpose\fP method.
+
+.nf
+compress_exposure = XtExposeCompressMultiple |XtExposeGraphicsExpose
+.fi
+
+.hi
+
+.hi
+.SS "Methods"
+
+The \fIcompute_thumb\fP method returns the position and size of the
+thumb in pixels.
+
+.nf
+compute_thumb($, Position * x, Position * y, Dimension * width, Dimension * height)
+{
+ Position fx, fy;
+ Dimension fw, fh;
+
+ #compute_inside($, fx, fy, fw, fh);
+ *width = $thumb_wd * fw + 0.5;
+ *height = $thumb_ht * fh + 0.5;
+ if (*width < $minsize) *width = min(fw, $minsize);
+ if (*height < $minsize) *height = min(fh, $minsize);
+ *x = fx + $thumb_x * (fw - *width) + 0.5;
+ *y = fy + $thumb_y * (fh - *height) + 0.5;
+}
+.fi
+
+The \fIcompute_inside\fP method of the Label class returns the area inside the
+frame, but the label of Slider2 widget should appear in the thumb. Therefore
+the \fIcompute_inside\fP method is redefined. This means that the \fIexpose\fP
+method of the Label class can still be used, because it calls this function
+to establish the position of the text.
+
+.nf
+compute_inside($, Position * x, Position * y, Dimension * w, Dimension * h)
+{
+ int tmp;
+
+ $compute_thumb($, x, y, w, h);
+ *x += $thumbFrameWidth;
+ *y += $thumbFrameWidth;
+ tmp = *w - 2 * $thumbFrameWidth; *w = (tmp < 0) ? 0 : tmp;
+ tmp = *h - 2 * $thumbFrameWidth; *h = (tmp < 0) ? 0 : tmp;
+}
+.fi
+
+The \fIexpose\fP method of the superclass is called to draw the outer frame
+and the text inside the thumb. Only the frame of the thumb is drawn here.
+
+.nf
+expose($, XEvent * event, Region region)
+{
+ Position x, y;
+ Dimension wd, ht;
+
+ if (! XtIsRealized($)) return;
+ if (region != NULL) {
+ XSetRegion(XtDisplay($), $thumbgc, region);
+ XSetRegion(XtDisplay($), $thumbdarkgc, region);
+ XSetRegion(XtDisplay($), $thumblightgc, region);
+ }
+ $compute_thumb($, x, y, wd, ht);
+ XFillRectangle(XtDisplay($), XtWindow($), $thumbgc, x, y, wd, ht);
+ XfwfDrawFrame($, x, y, wd, ht, $thumbFrameType, $thumbFrameWidth,
+ $thumblightgc, $thumbdarkgc);
+ if (region != NULL) {
+ XSetClipMask(XtDisplay($), $thumbgc, None);
+ XSetClipMask(XtDisplay($), $thumbdarkgc, None);
+ XSetClipMask(XtDisplay($), $thumblightgc, None);
+ }
+ #expose($, event, region);
+}
+.fi
+
+The \fIinitialize\fP method only needs to set the local variables. The
+\fIgraygc\fP that is inherited from Label has to be defined differently,
+because it now should use the thumb's background, instead of the
+widget's. (It still doesn't work right when the thumb is tiled with a
+pixmap, however.) Likewise, \fIgc\fP and \fIrv_gc\fP must be defined
+differently. The two new GC's are also initialized.
+
+.nf
+initialize(Widget request, $, ArgList args, Cardinal * num_args)
+{
+ $thumb_x = $thumb_y = 0.0;
+ $thumb_wd = $thumb_ht = 1.0;
+ $drag_in_progress = False;
+ create_thumbgc($);
+ create_gc($);
+ create_graygc($);
+ $thumblightgc = NULL; create_thumblightgc($);
+ $thumbdarkgc = NULL; create_thumbdarkgc($);
+}
+.fi
+
+The following routine's name, \fImove_thumb\fP, indicates what it is
+used for, but not what it really does. It doesn't depend on the thumb
+at all, it simply copies a rectangle to another position in the window
+and clears the old rectangle to the background color.
+
+.nf
+move_thumb($, int oldx, int oldy, int wd, int ht, int newx, int newy)
+{
+ int h;
+
+ XCopyArea(XtDisplay($), XtWindow($), XtWindow($),
+ DefaultGCOfScreen(XtScreen($)),
+ oldx, oldy, wd, ht, newx, newy);
+ /* First check if the old and new areas do not overlap */
+ if (newx + wd <= oldx || oldx + wd <= newx
+ || newy + ht <= oldy || oldy + ht <= newy) {
+ XClearArea(XtDisplay($), XtWindow($), oldx, oldy, wd, ht, False);
+ return;
+ } else { /* They do overlap */
+ h = oldy - newy;
+ if (h > 0)
+ XClearArea(XtDisplay($), XtWindow($), oldx, newy + ht, wd,h,False);
+ else if (h < 0)
+ XClearArea(XtDisplay($), XtWindow($), oldx, oldy, wd, -h, False);
+ if (newx < oldx)
+ XClearArea(XtDisplay($), XtWindow($), newx + wd,
+ max(oldy, newy), oldx - newx, ht - abs(h), False);
+ else if (oldx < newx)
+ XClearArea(XtDisplay($), XtWindow($), oldx, max(oldy, newy),
+ newx - oldx, ht - abs(h), False);
+ }
+}
+.fi
+
+The \fIcompute_info\fP method computes the relative position and size of the
+thumb, given its geometry in pixels. Before that, it makes sure the pixel
+values are within the frame and it adapts the values if needed.
+
+.nf
+compute_info($, Position * x, Position * y, Dimension * w, Dimension * h, float * thumb_x, float * thumb_y, float * thumb_wd, float * thumb_ht)
+{
+ Dimension fw, fh;
+ Position fx, fy;
+
+ #compute_inside($, fx, fy, fw, fh);
+ *w = min(fw, max($minsize, *w));
+ *h = min(fh, max($minsize, *h));
+ *x = min(fx + fw - *w, max(fx, *x));
+ *y = min(fy + fh - *h, max(fy, *y));
+ *thumb_wd = ((float) *w)/fw;
+ *thumb_ht = ((float) *h)/fh;
+ *thumb_x = (*w == fw) ? 0.0 : ((float) (*x - fx))/(fw - *w);
+ *thumb_y = (*h == fh) ? 0.0 : ((float) (*y - fy))/(fh - *h);
+}
+.fi
+
+The \fIset_values\fP method changes the GC's when needed.
+A change in \fIminsize\fP doesn't necessarily cause a redraw; only if
+the current thumb size is less than the new minimum does the widget
+needs to be redrawn.
+
+.nf
+Boolean set_values(Widget old, Widget request, $, ArgList args, Cardinal * num_args)
+{
+ Boolean need_redisplay = False;
+ Position x, y;
+ Dimension w, h;
+
+ if ($thumbPixmap != $old$thumbPixmap) {
+ create_thumbgc($);
+ need_redisplay = True;
+ } else if ($thumbColor != $old$thumbColor) {
+ $thumbPixmap = NULL;
+ create_thumbgc($);
+ need_redisplay = True;
+ }
+ if ($thumbFrameWidth != $old$thumbFrameWidth)
+ need_redisplay = True;
+ if ($thumbFrameType != $old$thumbFrameType)
+ need_redisplay = True;
+ if ($minsize != $old$minsize) {
+ compute_thumb(old, x, y, w, h);
+ if (w < $minsize || h < $minsize) need_redisplay = True;
+ }
+ if ($scrollResponse != $old$scrollResponse) {
+ $scrollResponse = $old$scrollResponse;
+ XtWarning("scrollResponse resource may only be queried, not set");
+ }
+ return need_redisplay;
+}
+.fi
+
+The method \fIscroll_response\fP is exported via the \fIscrollResponse\fP
+resource. It has the format of a callback function, so that it can be
+registered as a callback in the \fIscrollCallback\fP list of some other
+widget. The \fIclient_data\fP must be a pointer to the Slider2 widget
+itself, the \fIcall_data\fP is a pointer to an \fIXfwfScrollInfo\fP structure.
+The widget \fIwdg\fP is the widget from whose callback list the function
+is called.
+
+If the size of the thumb changed, the area must be cleared and redrawn
+with \fIexpose\fP, but if only the position changed, the thumb can be
+moved with the \fImove_thumb\fP method, which is much faster.
+
+\fBdef\fP range(x) =
+(0.0 <=(x )(x )<=1.0 )
+
+.nf
+scroll_response(Widget wdg, XtPointer client_data, XtPointer call_data)
+{
+ Widget self = (Widget) client_data;
+ XfwfScrollInfo *inf = (XfwfScrollInfo *)call_data;
+ XfwfScrollInfo new_info;
+ float x, y, w, h;
+ Position newx, newy, oldx, oldy;
+ Dimension newwd, newht, oldwd, oldht, wd, ht;
+ XEvent event;
+ XRectangle rect;
+ Region clip;
+ Display *dpy = XtDisplay($);
+
+ x = (inf->flagsXFWF_HPOS) range(inf->hpos) ? inf->hpos : $thumb_x;
+ y = (inf->flagsXFWF_VPOS) range(inf->vpos) ? inf->vpos : $thumb_y;
+ w = (inf->flagsXFWF_HSIZE) range(inf->hsize) ? inf->hsize : $thumb_wd;
+ h = (inf->flagsXFWF_VSIZE) range(inf->vsize) ? inf->vsize : $thumb_ht;
+
+ if ($thumb_wd != w || $thumb_ht != h) { /* Size changed */
+ if (XtIsRealized($))
+ $compute_thumb($, oldx, oldy, oldwd, oldht);
+ $thumb_wd = w;
+ $thumb_ht = h;
+ $thumb_x = x;
+ $thumb_y = y;
+ if (XtIsRealized($)) {
+ $compute_thumb($, newx, newy, newwd, newht);
+ XClearArea(dpy, XtWindow($), oldx, oldy, oldwd, oldht, False);
+ event.xexpose.x = rect.x = newx;
+ event.xexpose.y = rect.y = newy;
+ event.xexpose.width = rect.width = newwd;
+ event.xexpose.height = rect.height = newht;
+ clip = XCreateRegion();
+ XUnionRectWithRegion(rect, clip, clip);
+ $expose($, event, clip);
+ XDestroyRegion(clip);
+ }
+ } else if ($thumb_x != x || $thumb_y != y) { /* Only position changed */
+ if (XtIsRealized($))
+ $compute_thumb($, oldx, oldy, wd, ht);
+ $thumb_x = x;
+ $thumb_y = y;
+ if (XtIsRealized($)) {
+ $compute_thumb($, newx, newy, wd, ht);
+ $move_thumb($, oldx, oldy, wd, ht, newx, newy);
+ }
+ }
+
+ if (inf->reason != XfwfSNotify) {
+ new_info = *inf;
+ new_info.reason = XfwfSNotify;
+ XtCallCallbackList($, $scrollCallback, new_info);
+ }
+}
+.fi
+
+.hi
+
+.hi
+.SH "Utilities"
+
+The \fIcreate_gc\fP routine creates the GCs for the text.
+
+.nf
+create_gc($)
+{
+ XtGCMask mask;
+ XGCValues values;
+
+ if ($gc != NULL) XtReleaseGC($, $gc);
+ values.background = $thumbColor;
+ values.foreground = $foreground;
+ values.font = $font->fid;
+ mask = GCFont | GCBackground | GCForeground;
+ $gc = XtGetGC($, mask, values);
+
+ if ($rv_gc != NULL) XtReleaseGC($, $rv_gc);
+ values.foreground = $thumbColor;
+ values.background = $foreground;
+ values.font = $font->fid;
+ mask = GCFont | GCBackground | GCForeground;
+ $rv_gc = XtGetGC($, mask, values);
+}
+.fi
+
+The \fIcreate_graygc\fP routine creates the GC that grays the label in
+the thumb.
+
+.nf
+create_graygc($)
+{
+ XtGCMask mask;
+ XGCValues values;
+
+ if ($graygc != NULL) XtReleaseGC($, $graygc);
+ values.foreground = $thumbColor;
+ values.stipple =
+ XCreateBitmapFromData(XtDisplay($),
+ RootWindowOfScreen(XtScreen($)),
+ stip4_bits, stip4_width, stip4_height);
+ values.fill_style = FillStippled;
+ mask = GCForeground | GCStipple | GCFillStyle;
+ $graygc = XtGetGC($, mask, values);
+}
+.fi
+
+\fIcreate_thumbgc\fP creates the GC that draw the background in the
+thumb.
+
+.nf
+create_thumbgc($)
+{
+ XtGCMask mask;
+ XGCValues values;
+
+ if ($thumbgc != NULL) XtReleaseGC($, $thumbgc);
+ if ($thumbPixmap != NULL) {
+ mask = GCTile | GCFillStyle;
+ values.tile = $thumbPixmap;
+ values.fill_style = FillTiled;
+ } else {
+ mask = GCForeground;
+ values.foreground = $thumbColor;
+ }
+ $thumbgc = XtGetGC($, mask, values);
+}
+.fi
+
+The \fIcreate_thumblightgc\fP functions makes the GC for drawing the light
+parts of the thumb's frame.
+
+.nf
+create_thumblightgc($)
+{
+ XtGCMask mask;
+ XGCValues values;
+
+ if ($thumblightgc != NULL) XtReleaseGC($, $thumblightgc);
+ switch ($shadowScheme) {
+ case XfwfColor:
+ mask = GCForeground;
+ values.foreground = $topShadowColor;
+ break;
+ case XfwfStipple:
+ mask = GCFillStyle | GCStipple | GCForeground | GCBackground;
+ values.fill_style = FillOpaqueStippled;
+ values.background = $thumbColor;
+ values.stipple = $topShadowStipple;
+ values.foreground = WhitePixelOfScreen(XtScreen($));
+ break;
+ case XfwfAuto:
+ if (DefaultDepthOfScreen(XtScreen($)) > 4
+ $lighter_color($, $thumbColor, values.foreground)) {
+ mask = GCForeground;
+ } else {
+ mask = GCFillStyle | GCBackground | GCForeground | GCStipple;
+ values.fill_style = FillOpaqueStippled;
+ values.background = $thumbColor;
+ values.foreground = WhitePixelOfScreen(XtScreen($));
+ values.stipple =
+ XCreateBitmapFromData(XtDisplay($),
+ RootWindowOfScreen(XtScreen($)),
+ stip4_bits, stip4_width, stip4_height);
+ }
+ break;
+ }
+ $thumblightgc = XtGetGC($, mask, values);
+}
+.fi
+
+The \fIcreate_thumbdarkgc\fP routines does the same for the dark parts of the
+thumb's frame.
+
+.nf
+create_thumbdarkgc($)
+{
+ XtGCMask mask;
+ XGCValues values;
+
+ if ($thumbdarkgc != NULL) XtReleaseGC($, $thumbdarkgc);
+ switch ($shadowScheme) {
+ case XfwfColor:
+ mask = GCForeground;
+ values.foreground = $bottomShadowColor;
+ break;
+ case XfwfStipple:
+ mask = GCFillStyle | GCStipple | GCForeground | GCBackground;
+ values.fill_style = FillOpaqueStippled;
+ values.stipple = $bottomShadowStipple;
+ values.foreground = BlackPixelOfScreen(XtScreen($));
+ values.background = $thumbColor;
+ break;
+ case XfwfAuto:
+ if (DefaultDepthOfScreen(XtScreen($)) > 4
+ $darker_color($, $thumbColor, values.foreground)) {
+ mask = GCForeground;
+ } else {
+ mask = GCFillStyle | GCBackground | GCForeground | GCStipple;
+ values.fill_style = FillOpaqueStippled;
+ values.background = $thumbColor;
+ values.foreground = WhitePixelOfScreen(XtScreen($));
+ values.stipple =
+ XCreateBitmapFromData(XtDisplay($),
+ RootWindowOfScreen(XtScreen($)),
+ stip4_bits, stip4_width, stip4_height);
+ }
+ break;
+ }
+ $thumbdarkgc = XtGetGC($, mask, values);
+}
+.fi
+
+.hi