diff options
Diffstat (limited to 'vendor/x11iraf/obm/ObmW/Slider2.man')
-rw-r--r-- | vendor/x11iraf/obm/ObmW/Slider2.man | 1068 |
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 |