changed to match the processing direction. This resource can have the following values:
XmTOP_LEFT
XmTOP_RIGHT
XmBOTTOM_LEFT
XmBOTTOM_RIGHT
10.3.3 Callback Routines
The callback routines associated with the ScrollBar are its only links into the internal mechanisms that actually scroll
the data. You can use these callback routines in various contexts, depending on what you want to accomplish. For
example, you can monitor scrolling in an automatic or semi−automatic ScrolledWindow, such as a ScrolledText or
ScrolledList object. These two activities are identical when it comes to the implementation of what we are about to
describe. You can also implement application−defined scrolling, which requires intimate knowledge of the internals of
the object being scrolled.
There are different parts of a ScrollBar that the user can manipulate to cause a scrolling action. In fact, each part of the
ScrollBar has a separate callback routine associated with it. These callback routines are used both to monitor
automatic (or semi−automatic) scrolling and to implement application−defined scrolling. As with all Motif callbacks,
the callback routines take the form of an XtCallbackProc. All of the ScrollBar callbacks pass a structure of type
XmScrollBarCallbackStruct for the third parameter. This structure takes the following form:
typedef struct {
int reason;
XEvent *event;
int value;
int pixel;
} XmScrollBarCallbackStruct;
The reason field specifies the scrolling action performed by the user. Each callback has a corresponding reason that
indicates the action. lists the callback name, reason, and scrolling action for each ScrollBar callback resource. tab(@),
linesize(2); l | l | l lp9fCW | lp9fCW | lw(1.7i). Resource Name@Reason@Action
_
XmNincrementCallback@XmCR_INCREMENT@T{ Top or right directional arrow clicked T}
XmNdecrementCallback@XmCR_DECREMENT@T{ Bottom or left directional arrow clicked T}
XmNpageIncrementCallback@XmCR_PAGE_INCREMENT@T{ Area above or right of slider clicked T}
XmNpageDecrementCallback@XmCR_PAGE_DECREMENT@T{ Area below or left of slider clicked T}
XmNtoTopCallback@XmCR_TO_TOP@T{ Top or right directional arrow CTRL−clicked T}
XmNtoBottomCallback@XmCR_TO_BOTTOM@T{ Bottom or left directional arrow CTRL−clicked T}
XmNdragCallback@XmCR_DRAG@T{ Slider dragged T}
XmNvalueChangedCallback@XmCR_VALUE_CHANGED@T{ Value changed (see explanation) T}
_ The scrolling action that invokes the various increment and decrement callbacks depends on the value of the
XmNprocessingDirection resource; the table shows the actions for a left−to−right environment. The
XmNvalueChangedCallback is invoked when the user releases the mouse button after dragging the slider. The
callback is also invoked for any of the other scrolling actions if the corresponding callback resource is not set, with the
exception of the XmNdragCallback. This feature is convenient for cases where you are handling your own
scrolling and you are not concerned with the type of scrolling the user invoked.
The value field of the callback structure indicates the new position of the ScrollBar. This value can range from
XmNminimum to XmNmaximum. The pixel field indicates the x or y coordinate of the mouse location relative to the
origin of the ScrollBar for the XmNtoTopCallback, XmNtoBottomCallback, and XmNdragCallback
routines. The origin is the top of a vertical ScrollBar or the left side of a horizontal ScrollBar, regardless of the value
10 ScrolledWindows and ScrollBars 10.3.3 Callback Routines
266
of XmNprocessingDirection.
the source code demonstrates how a callback routine can be hooked up to each of the callback resources to allow you
to monitor the scrolling in a List widget more precisely. For Text and List widgets, you really should not be using the
callback routines to change the default scrolling behavior. XtSetLanguageProc() is only available in X11R5;
there is no corresponding function in X11R4.
/* monitor_sb.c −− demonstrate the ScrollBar callback routines by
* monitoring the ScrollBar for a ScrolledList. Functionally, this
* program does nothing. However, by tinkering with the Scrolled
* List and watching the output from the ScrollBar's callback routine,
* you'll see some interesting behavioral patterns. By interacting
* with the *List* widget to cause scrolling, the ScrollBar's callback
* routine is never called. Thus, monitoring the scrolling actions
* of a ScrollBar should not be used to keep tabs on exactly when
* the ScrollBar's value changes!
*/
#include <Xm/List.h>
/* print the interesting resource values of a scrollbar */
void
scroll_action(scrollbar, client_data, call_data)
Widget scrollbar;
XtPointer client_data;
XtPointer call_data;
{
XmScrollBarCallbackStruct *cbs =
(XmScrollBarCallbackStruct *) call_data;
printf ("cbs−>reason: %s, cbs−>value = %d, cbs−>pixel = %d0,
cbs−>reason == XmCR_DRAG? "drag" :
cbs−>reason == XmCR_VALUE_CHANGED? "value changed" :
cbs−>reason == XmCR_INCREMENT? "increment" :
cbs−>reason == XmCR_DECREMENT? "decrement" :
cbs−>reason == XmCR_PAGE_INCREMENT? "page increment" :
cbs−>reason == XmCR_PAGE_DECREMENT? "page decrement" :
cbs−>reason == XmCR_TO_TOP? "top" :
cbs−>reason == XmCR_TO_BOTTOM? "bottom" : "unknown",
cbs−>value, cbs−>pixel);
}
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, list_w, sb;
XtAppContext app;
char *items = "choice0, choice1, choice2, choice3, choice4, choice5, choice6, choice7, choice8, choice9, choice10, choice11, choice12, choice13, choice14";
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtAppInitialize(&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL, 0);
list_w = XmCreateScrolledList (toplevel, "list_w", NULL, 0);
XtVaSetValues (list_w,
/* Rather than convert the entire list of items into an array
* of compound strings, let's just let Motif's type converter
* do it for us and save lots of effort (altho not much time).
*/
10 ScrolledWindows and ScrollBars 10.3.3 Callback Routines
267
XtVaTypedArg, XmNitems, XmRString, items, strlen (items)+1,
XmNitemCount, 15,
XmNvisibleItemCount, 5,
NULL);
XtManageChild (list_w);
/* get the scrollbar from ScrolledWindow associated with Text widget */
XtVaGetValues (XtParent (list_w), XmNverticalScrollBar, &sb, NULL);
XtAddCallback (sb, XmNvalueChangedCallback, scroll_action, NULL);
XtAddCallback (sb, XmNdragCallback, scroll_action, NULL);
XtAddCallback (sb, XmNincrementCallback, scroll_action, NULL);
XtAddCallback (sb, XmNdecrementCallback, scroll_action, NULL);
XtAddCallback (sb, XmNpageIncrementCallback, scroll_action, NULL);
XtAddCallback (sb, XmNpageDecrementCallback, scroll_action, NULL);
XtAddCallback (sb, XmNtoTopCallback, scroll_action, NULL);
XtAddCallback (sb, XmNtoBottomCallback, scroll_action, NULL);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
The program displays a simple ScrolledList that contains 15 entries, as shown in the figure.
Output of monitor_sb.c
The entries in the List are not important; the way that the ScrollBar reacts to the user's interaction is what is
interesting. The following output shows what happens when the user scrolls the List:
cbs−>reason: increment, cbs−>value = 1, cbs−>pixel = 0
cbs−>reason: page increment, cbs−>value = 5, cbs−>pixel = 0
cbs−>reason: drag, cbs−>value = 6, cbs−>pixel = 46
cbs−>reason: drag, cbs−>value = 7, cbs−>pixel = 50
cbs−>reason: value changed, cbs−>value = 7, cbs−>pixel = 50
cbs−>reason: decrement, cbs−>value = 6, cbs−>pixel = 0
cbs−>reason: top, cbs−>value = 0, cbs−>pixel = 11
If you use the keyboard to select elements or scroll around in the list, you'll notice that the callbacks for the ScrollBar
are not invoked because the List widget is taking all of the keyboard events from the ScrollBar. Like any other widget,
the ScrollBar can receive keyboard events, and it even has translations to map certain key sequences to scrolling
actions. However, the List widget sets XmNtraversalOn to False for the ScrollBar, so that the List can process
its own keyboard actions, some of which scroll the window. The Text widget does the same thing with its ScrollBars.
As a result, there is a limit to what you can accomplish by monitoring ScrollBar actions on semi−automatic scrolling
objects like List and Text widgets.
10 ScrolledWindows and ScrollBars 10.3.3 Callback Routines
268
Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.