[comp.windows.x] Need help with XView scrollbars

denault@hale.ifa.hawaii.edu (Tony Denault) (08/09/90)

I need help with dealing with scrollbars in XView. I have a canvas
with scrollbars. I defined the paint window to be the same size as
the canvas subwindow. My redraw procedure determines which portion
of the data needs to be displayed based on some internal parameters. 
My redraw procedure changes the OBJECT_LENGTH, VIEW_LENGTH, ect..,
to match the scrollbars to the drawing.

What I need to know is:

How can I be notified when the user interacts with the scrollbar?
I need to read it's new postion. Update my internal variable and
call my canvas redraw procedure. I don't want XView to scroll my
canvas display. 

Thanks in advance, 
Tony D.
--
/------------------------------------------------------------------------\
| Tony Denault, Institute for Astronomy,  |  denault@hale.ifa.hawaii.edu |
| 2680 Woodlawn Drive, Honolulu, HI 96789 |               (808) 956-6097 |
\------------------------------------------------------------------------/

salzman%gaucho@RAND.ORG (Isaac) (08/09/90)

>bu.edu!rpi!zaphod.mps.ohio-state.edu!samsung!munnari.oz.au!uhccux!hale.ifa.haw
>aii.edu@eddie.mit.edu (Tony Denault) writes:
>

>I need help with dealing with scrollbars in XView....

>What I need to know is:

>How can I be notified when the user interacts with the scrollbar?
>I need to read it's new postion. Update my internal variable and
>call my canvas redraw procedure. I don't want XView to scroll my
>canvas display. 

XView 2.0 (in the OpenWindows 2.0 distribution) includes a good example of
how to get a handle on the scrollbar events of a canvas (it's also in the
updated version of the O'Reilly XView Programming Manual). since it's such
a small file, i'll include it below.

i've written a canvas based text list package where i take complete control
of the scrollbar. it can get tricky at times, and there are some
undocumented side effects. for instance, funny things can happen if you
make the SCROLLBAR_OBJECT_LENGTH smaller than SCROLLBAR_VIEW_LENGTH (like
setting the SCROLLBAR_VIEW_START to something other than what you think it
should be, and not calling your notify_interpose_event_func to let you
know)....

if you (or anyone else) are interested, i'll be glad to mail you a copy of
my canvas text list package. if nothing else it serves as an example of how
to deal with controlling the scrollbar (and how to write a canvas based
package in general)....

--
* Isaac J. Salzman                                            ----     
* The RAND Corporation - Information Sciences Dept.          /o o/  /  
* 1700 Main St., PO Box 2138, Santa Monica, CA 90406-2138    | v |  |  
* AT&T      : +1 213-393-0411 x6421 or x7923 (ISL lab)      _|   |_/   
* Internet  : salzman@rand.org                             / |   |
* UUCP      : !uunet!rand.org!salzman                      | |   |     

----------------------------------------------------------------------------

[$OPENWINHOME/share/src/sun/xview/examples/scrollbar/scrollto.c]

/* scroll_to.c -- demonstrate how to monitor the scrolling
 * requests invoked by the user.  Requests can be monitored,
 * ignored or changed programmatically.  This program creates
 * a canvas window by default or a textsw with the -textsw
 * command line option.  Both contain a scrollbar.
 */
#include <stdio.h>
#include <xview/xview.h>
#include <xview/textsw.h>
#include <xview/canvas.h>
#include <xview/scrollbar.h>

main(argc, argv)
int argc;
char *argv[];
{
    Frame           frame;
    Textsw          textsw;
    Canvas          canvas;
    Scrollbar       sbar;
    Notify_value    monitor_scroll();

    (void) xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);

    frame = xv_create(NULL, FRAME, NULL);

    if (argc > 1 && !strcmp(argv[1], "-textsw")) {
        textsw = xv_create(frame, TEXTSW,
            TEXTSW_FILE_CONTENTS, "/etc/termcap",
            NULL);
        sbar = xv_get(textsw, TEXTSW_SCROLLBAR);
    } else {
        canvas = xv_create(frame, CANVAS,
            CANVAS_WIDTH, 1000,
            CANVAS_HEIGHT, 1000,
            CANVAS_AUTO_SHRINK, FALSE,
            CANVAS_AUTO_EXPAND, FALSE,
            NULL);
        sbar = xv_create(canvas, SCROLLBAR,
            SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
            SCROLLBAR_PIXELS_PER_UNIT, 10,
            NULL);
    }
    notify_interpose_event_func(xv_get(sbar, SCROLLBAR_NOTIFY_CLIENT),
        monitor_scroll, NOTIFY_SAFE);

    xv_main_loop(frame);
}

/*
 * To change the behavior of the scrolling of the canvas, do not pass
 * on the event via notify_next_event_func() when the event type is
 * SCROLLBAR_REQUEST.
 */
Notify_value
monitor_scroll(client, event, sbar, type)
Notify_client     client;
Event            *event;
Scrollbar         sbar;
Notify_event_type type;
{
    int     view_start, last_view_start, pixels_per, is_neg = 0, total;

    if (event_id(event) == SCROLLBAR_REQUEST) {
        view_start = (int)xv_get(sbar, SCROLLBAR_VIEW_START);
        last_view_start = (int)xv_get(sbar, SCROLLBAR_LAST_VIEW_START);
        pixels_per = (int)xv_get(sbar, SCROLLBAR_PIXELS_PER_UNIT);
        if ((total = view_start - last_view_start) < 0)
            total = -total, is_neg = 1;
        printf("scrolled from %d to %d: %d pixels (%d units) %s\n",
            last_view_start, view_start, pixels_per * total, total,
            is_neg? "up" : "down");
    }
    return notify_next_event_func(client, event, sbar, type);
}