.\"remove .ig hn for full docs .de hi .ig eh .. .de eh .. .TH "" 3 "" "Version 3.0" "Free Widget Foundation" .SH NAME XfwfScrollbar .SH DESCRIPTION The scrollbar widget helps the user to view data that is too large to be displayed all at once. They are often used through a ScrolledWindow (see there), where they are put next to and/or below the widget that contains the data. The scrollbar controls which part is visible. By manipulating the scrollbar the user can move (`scroll') the data within the other widget. A scrollbar consists of two arrows placed at each end of a rectangle, either at the top and bottom or at the left and right. The former is called a vertical scrollbar, the latter a horizontal one. A smaller rectangle, called the thumb or slider, is placed within the larger one. It can move up and down (vertical scrollbar) or left/right (horizontal scrollbar). Clicking an arrow moves the data in that direction. Pressing the mouse button on an arrow and holding it, moves the data by small increments as long as the mouse button is down. Dragging the slider moves the data proportionally with the slider, either along with the movement of the mouse, or all at once when the mouse button is released. Pressing the mouse button onthe rectangle outside the slider moves the data in larger increments. The ratio of the slider size to the scroll region size typically corresponds to the relationship between the size of the visible data and the total size of the data. For example, if 10 percent of the data is visible, the slider typically occupies 10 percent of the scroll region. This provides the user with a visual clue to the size of the invisible data. The scrollbar widget can be configured as either horizontal or vertical. It is made up of two XfwfArrow widgets and an XfwfSlider2 widget. Therefore, many of the scrollbar's resources are actually resources for these, nameless, widgets. The scrollbar has the same callback list as the slider. .SS "Public variables" .ps-2 .TS center box; cBsss lB|lB|lB|lB l|l|l|l. XfwfScrollbar Name Class Type Default XtNvertical XtCVertical Boolean True XtNscrollCallback XtCScrollCallback Callback NULL XtNscrollResponse XtCScrollResponse XTCallbackProc scroll_response XtNinitialDelay XtCInitialDelay Cardinal 500 XtNrepeatDelay XtCRepeatDelay Cardinal 50 XtNincrement XtCIncrement Float "0.05" XtNscrollbarForeground XtCScrollbarForeground Pixel copy_background XtNshadow XtCShadow Dimension 2 XtNminsize XtCMinsize Dimension 20 .TE .ps .TP .I "XtNvertical" The orientation of the scrollbar is set with the \fIvertical\fP resource. \fITrue\fP means vertical, \fIFalse\fP horizontal. This resource may only be set during initialization. Any changes via \fIXtVaSetValues\fP result in a warning and are then ignored. .hi .nf Boolean vertical = True .fi .eh .TP .I "XtNscrollCallback" The user can interact with the scrollbar in many ways, but there is only a single callback list: \fIscrollCallback\fP. The callback uses the \fIcall_data\fP parameter to pass a pointer to an \fIXfwfScrollInfo\fP structure: \fIstruct {XfwfSReason reason; XfwfSFlags flags; float vpos, vsize, hpos, hsize;}\fP The \fIflags\fP field is a bitwise combination of \fIXFWF_VPOS\fP, \fIXFWF_HPOS\fP, \fIXFWF_VSIZE\fP and \fIXFWF_HSIZE\fP. The structure contains a field \fIreason\fP, which can have the following values (there exist other values, but they are not used by the scrollbar): \item{-} \fIXfwfSUp\fP: if the user clicked (or holds) the up arrow. \item{-} \fIXfwfSLeft\fP: ditto left arrow. \item{-} \fIXfwfSDown\fP: ditto down arrow. \item{-} \fIXfwfSRight\fP: ditto right arrow. \item{-} \fIXfwfSPageUp\fP: ditto area above thumb. \item{-} \fIXfwfSPageDown\fP: ditto area below thumb. \item{-} \fIXfwfSPageLeft\fP: ditto area left of thumb. \item{-} \fIXfwfSPageRight\fP: ditto area right of thumb. \item{-} \fIXfwfSDrag\fP: if the user drags the thumb. \item{-} \fIXfwfSMove\fP: if the user stops dragging the thumb. The other four fields contain the new position of the thumb, as numbers between 0.0 and 1.0 inclusive. In the case of drag and drop actions, the position and size reflect the thumb's {\em actual} position at the end of the dragging. In the other cases, the position is the {\em suggested} new position. In these latter cases, the callback routine should compute the new position and use a call to the function in the \fIScrollResponse\fP resource (or, more conveniently, to \fIXfwfSetScrollbar\fP) to update the scrollbar. .hi .nf XtCallbackList scrollCallback = NULL .fi .eh .TP .I "XtNscrollResponse" The standard way to update the scrollbar is with a call to the function that is knwon as the \fIscrollResponse\fP function. To get a pointer to that function, you should use \fIXtGetValues\fP or \fIXtVaGetValues\fP on the \fIXtNscrollResponse\fP resource. But from an application it might be easier to use the \fIXfwfSetScrollbar\fP convenience function instead. The \fIscrollResponse\fP routine has the same format as a callback procedure. The first argument is a widget, this argument is ignored. The second argument is \fIXtPointer client_data\fP, it must point to the scrollbar that is to be updated. The third argument is \fIXtPointer call_data\fP, it must be a pointer to an \fIXfwfScrollInfo\fP structure (see above). .hi .nf XtCallbackProc scrollResponse = scroll_response .fi .eh .TP .I "XtNinitialDelay" When the user presses and then holds the mouse button on an arrow or on an area outside the thumb, the scrollbar waits some milliseconds before it starts repeating the callbacks. .hi .nf Cardinal initialDelay = 500 .fi .eh .TP .I "XtNrepeatDelay" Between repeated calls to the callback routines, the scrollbar will wait a few milliseconds. .hi .nf Cardinal repeatDelay = 50 .fi .eh .TP .I "XtNincrement" Some widgets may be simple enough that they can scroll a fixed amount whenever the user clicks on one of the arrow buttons. If that is the case, they can let the scrollbar compute the new position. It will be passed in the \fIXfwfScrollInfo\fP structure as the suggested new position. Any receiver is free to ignore the suggestion, however. The default is to add or subtract 0.05. .hi .nf float increment = "0.05" .fi .eh .TP .I "XtNscrollbarForeground" The color of the arrow and the thumb also determines the color of the 3D shadow, at least if \fIshadowScheme\fP is set to \fIXfwfAuto\fP, as it is by default. The default value is determined dynamically, it is copied from the \fIbackground\fP resource. .hi .nf Pixel scrollbarForeground = copy_background .fi .eh .TP .I "XtNshadow" The width of the arrow's and thumb's shadow is by default 2 pixels. .hi .nf Dimension shadow = 2 .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 "XtNframeWidth" The slider and the two arrows frame will be forced to 0 pixels. The only frame is that of the whole scrollbar. 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. 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 \fIXfwfSetScrollbar\fP convenience function can be used to set the position and size of a scrollbar. The two arguments must be between 0.0 and 1.0 (inclusive). .nf XfwfSetScrollbar( $, double pos, double size) .fi .hi { if (! XtIsSubclass($, xfwfScrollbarWidgetClass)) XtError("XfwfSetScrollbar called with incorrect widget type"); if (pos < 0.0 || pos > 1.0 || size < 0.0 || size > 1.0) XtError("XfwfSetScrollbar called with incorrect arguments"); if ($vertical) { XfwfResizeThumb($slider, 1.0, size); XfwfMoveThumb($slider, 0.0, pos); } else { XfwfResizeThumb($slider, size, 1.0); XfwfMoveThumb($slider, pos, 0.0); } } .eh .hi .SS "Actions" .TP .I "Scroll The following action is not used by default, but it is defined here, because someone might want to bind it to keys. For example, the subclasses \fIXfwfVScrollbar\fP and \fIXfwfHScrollbar\fP do that. .hi .nf void Scroll($, XEvent* event, String* params, Cardinal* num_params) { XfwfScrollInfo info; XfwfGetThumb($slider, info); info.reason = XfwfCvtStringToScrollReason(params[0]); switch (info.reason) { case XfwfSUp: info.flags = XFWF_VPOS; info.vpos = max(0.0, info.vpos - $increment); break; case XfwfSDown: info.flags = XFWF_VPOS; info.vpos = min(1.0, info.vpos + $increment); break; case XfwfSLeft: info.flags = XFWF_HPOS; info.hpos = max(0.0, info.hpos - $increment); break; case XfwfSRight: info.flags = XFWF_HPOS; info.hpos = min(1.0, info.hpos + $increment); break; case XfwfSPageUp: info.flags = XFWF_VPOS; info.vpos = max(0.0, info.vpos - info.vsize); break; case XfwfSPageDown: info.flags = XFWF_VPOS; info.vpos = min(1.0, info.vpos + info.vsize); break; case XfwfSPageLeft: info.flags = XFWF_HPOS; info.hpos = max(0.0, info.hpos - info.hsize); break; case XfwfSPageRight: info.flags = XFWF_HPOS; info.hpos = min(1.0, info.hpos + info.hsize); break; case XfwfSTop: info.flags = XFWF_VPOS; info.vpos = 0.0; break; case XfwfSBottom: info.flags = XFWF_VPOS; info.vpos = 1.0; break; case XfwfSLeftSide: info.flags = XFWF_HPOS; info.hpos = 0.0; break; case XfwfSRightSide: info.flags = XFWF_HPOS; info.hpos = 1.0; break; default: break; /* Not understood */ } XtCallCallbackList($, $scrollCallback, info); } .fi .eh .hi .hi .SH "Importss" .nf .B incl .fi .nf .B incl .fi .nf .B incl .fi .hi .hi .SS "Private variables" The three children of the scrollbar are stored in private variables. .nf Widget arrow1 .fi .nf Widget arrow2 .fi .nf Widget slider .fi During the \fIinitialize\fP method, the variable \fIinitializing\fP will be \fITrue\fP, so that \fIinsert_child\fP can check whether a child should be inserted or not. .nf Boolean initializing .fi The \fIscrollResponse\fP function of the Slider2 that implements the thumb is stored in a private variable. .nf XtCallbackProc slider_scroll .fi .hi .hi .SS "Methods" The \fIinitialize\fP method creates the three widgets that make up the scrollbar: two arrows and a slider. It sets the resources of these widgets and redirects the callbacks. .nf initialize(Widget request, $, ArgList args, Cardinal * num_args) { Position x, y, xa2, xslider, ya2, yslider; Dimension w, h, wa, ha, wslider, hslider; $initializing = True; $compute_inside($, x, y, w, h); if ($vertical) { ha = wa = wslider = w; xa2 = xslider = x; hslider = (h - 2*ha > 0) ? h - 2*ha : 10; yslider = y + ha; ya2 = yslider + hslider; } else { wa = ha = hslider = h; ya2 = yslider = y; wslider = (w - 2*wa > 0) ? w - 2*wa : 10; xslider = x + wa; xa2 = xslider + wslider; } $arrow1 = XtVaCreateManagedWidget ("_arrow1", xfwfArrowWidgetClass, $, XtNx, x, XtNy, y, XtNwidth, wa, XtNheight, ha, XtNframeWidth, 0, XtNforeground, $scrollbarForeground, XtNinitialDelay, $initialDelay, XtNrepeatDelay, $repeatDelay, XtNtraversalOn, False, XtNhighlightThickness, 0, XtNdirection, $vertical?XfwfTop:XfwfLeft, XtNouterOffset, 0, XtNborderWidth, 0, NULL); XtAddCallback($arrow1, XtNcallback, up, $); $arrow2 = XtVaCreateManagedWidget ("_arrow2", xfwfArrowWidgetClass, $, XtNx, xa2, XtNy, ya2, XtNwidth, wa, XtNheight, ha, XtNframeWidth, 0, XtNforeground, $scrollbarForeground, XtNinitialDelay, $initialDelay, XtNrepeatDelay, $repeatDelay, XtNtraversalOn, False, XtNhighlightThickness, 0, XtNdirection, $vertical?XfwfBottom:XfwfRight, XtNouterOffset, 0, XtNborderWidth, 0, NULL); XtAddCallback($arrow2, XtNcallback, down, $); $slider = XtVaCreateManagedWidget ("_slider", xfwfSlider2WidgetClass, $, XtNx, xslider, XtNy, yslider, XtNwidth, wslider, XtNheight, hslider, XtNthumbColor, $scrollbarForeground, XtNframeWidth, 0, XtNinitialDelay, $initialDelay, XtNrepeatDelay, $repeatDelay, XtNtraversalOn, False, XtNhighlightThickness, 0, XtNouterOffset, 0, XtNborderWidth, 0, NULL); XtAddCallback($slider, XtNscrollCallback, thumbscroll, $); XtVaGetValues($slider, XtNscrollResponse, $slider_scroll, NULL); $initializing = False; } .fi When the scrollbar is resized, the children must be resized also. .nf resize($) { Position x, y, xa2, xslider, ya2, yslider; Dimension w, h, wa, ha, wslider, hslider; $compute_inside($, x, y, w, h); if ($vertical) { wa = wslider = w; xa2 = xslider = x; ha = 2 * (wa + 1)/3; hslider = (h - 2*ha > 0) ? h - 2*ha : 10; yslider = y + ha; ya2 = yslider + hslider; } else { ha = hslider = h; ya2 = yslider = y; wa = 2 * (ha + 1)/3; wslider = (w - 2*wa > 0) ? w - 2*wa : 10; xslider = x + wa; xa2 = xslider + wslider; } XtConfigureWidget($arrow1, x, y, wa, ha, 0); XtConfigureWidget($arrow2, xa2, ya2, wa, ha, 0); XtConfigureWidget($slider, xslider, yslider, wslider, hslider, 0); } .fi \fIinsert_child\fP is redefined here only to be able to give a warning when a child is inserted beyond the three that are created in the \fIinitialize\fP method. .nf insert_child(Widget child) { if ($initializing) #insert_child(child); else { char s[500]; (void)sprintf(s, "Cannot add children to a scrollbar (\\"%s\\"->\\"%s\\")", XtName(child), XtName($)); XtWarning(s); } } .fi The \fIset_values\fP method passes resource values on to the three children. .nf Boolean set_values(Widget old, Widget request, $, ArgList args, Cardinal * num_args) { if ($old$vertical != $vertical) { XtWarning("Cannot change the \\"vertical\\" resource of a scrollbar\\n"); $vertical = $old$vertical; } if ($old$scrollbarForeground != $scrollbarForeground) { XtVaSetValues($slider, XtNthumbColor, $scrollbarForeground, NULL); XtVaSetValues($arrow1, XtNforeground, $scrollbarForeground, NULL); XtVaSetValues($arrow2, XtNforeground, $scrollbarForeground, NULL); } if ($old$shadow != $shadow) { XtVaSetValues($slider, XtNthumbFrameWidth, $shadow, NULL); XtVaSetValues($arrow1, XtNarrowShadow, $shadow, NULL); XtVaSetValues($arrow2, XtNarrowShadow, $shadow, NULL); } if ($old$minsize != $minsize) { XtVaSetValues($slider, XtNminsize, $minsize, NULL); } return False; } .fi The \fIscroll_response\fP method is accessed via the \fIscrollResponse\fP resource. It is passed the scrollbar itself as the \fIclient_data\fP argument and a pointer to an \fIXfwfScrollInfo\fP record as \fIcall_data\fP. The scrollbar passes on the call to the Slider2 widget that is managing the thumb. .nf scroll_response(Widget wdg, XtPointer client_data, XtPointer call_data) { Widget $ = (Widget) client_data; $slider_scroll(wdg, $slider, call_data); } .fi .hi .hi .SH "Utilities" .nf char rcsid[] = "$Header: Scrollbar.w,v 1.1 92/11/02 14:08:00 bert Exp $" .fi The \fIup\fP routine is a callback for the first arrow. It invokes the scrollbar's callback. .nf up(Widget arrow, XtPointer client_data, XtPointer call_data) { Widget $ = (Widget) client_data; XfwfScrollInfo info; XfwfGetThumb($slider, info); if ($vertical) { info.reason = XfwfSUp; info.flags = XFWF_VPOS; info.vpos = max(0.0, info.vpos - $increment); } else { info.reason = XfwfSLeft; info.flags = XFWF_HPOS; info.hpos = max(0.0, info.hpos - $increment); } XtCallCallbackList($, $scrollCallback, info); } .fi The \fIdown\fP routine is the callback for the second arrow. It invokes the scrollbar's callback. .nf down(Widget arrow, XtPointer client_data, XtPointer call_data) { Widget $ = (Widget) client_data; XfwfScrollInfo info; XfwfGetThumb($slider, info); if ($vertical) { info.reason = XfwfSDown; info.flags = XFWF_VPOS; info.vpos = min(1.0, info.vpos + $increment); } else { info.reason = XfwfSRight; info.flags = XFWF_HPOS; info.hpos = min(1.0, info.hpos + $increment); } XtCallCallbackList($, $scrollCallback, info); } .fi The \fIthumbscroll\fP routine is the callback for the scroll callback of the slider. It invokes the scrollbar's \fIscrollCallback\fP, after making sure that only appropriate position information is passed. (The Slider2 might pass horizontal position where only vertical position is relevant, and vice versa.) .nf thumbscroll(Widget w, XtPointer client_data, XtPointer call_data) { Widget $ = (Widget) client_data; XfwfScrollInfo *info = (XfwfScrollInfo*) call_data; if ($vertical) info->flags = XFWF_VPOS; else info->flags = XFWF_HPOS; XtCallCallbackList($, $scrollCallback, info); } .fi The \fIcopy_background\fP routine is resource default procedure. It is called to initialize the default value of the \fIforeground\fP resource. .nf copy_background($, int offset, XrmValue * value) { value->addr = (XtPointer) $background_pixel; } .fi .hi