longt@valentine.ICS.UCI.EDU ("LONG T.") (06/29/91)
Hi, I've been trying to figure out how to synchronize the scrolling of two or more text widgets with just one scroll bar (whether vertically or horizontally). Is there an elegant way of doing this? Any help will be greatly appreciated. Regards, Longreen Taylor UC Irvine Dept. of Info and Computer Science Internet: longt@valentine.ics.uci.edu
nasg@ils.nwu.edu (Andersen New Age Systems Group) (06/30/91)
In article <9106290014.aa24008@PARIS.ICS.UCI.EDU> longt@valentine.ICS.UCI.EDU ("LONG T.") writes: > >Hi, > >I've been trying to figure out how to synchronize the scrolling of >two or more text widgets with just one scroll bar (whether vertically or >horizontally). > >Is there an elegant way of doing this? > >Any help will be greatly appreciated. > >Regards, > >Longreen Taylor >UC Irvine >Dept. of Info and Computer Science >Internet: longt@valentine.ics.uci.edu This is definitely not the slickest approach of getting syncronized scrolling, but it works. I use it to keep labels used as column headings to scroll along with the data in columns. This creates a kind of "title area", to use spreadsheet lingo. Here is the code. Suppose you have a data area (with data organized into columns) which is an XmScrolledText widget, called data_sw. Suppose that the title area is also a scrolled are called title_sw. -------------------- cut here ------------------------------ /* * setup_syncro_scroll_single * * This function sets up the syncronized scrolling in a SINGLE direction * for a pair of scrolled window areas. Whether to syncronize horizontally * or vertically is determined by the orientation parameter. * * orientation is either XmNhorizontalScrollBar or XmNverticalScrollBar. * data_sw's scrollbar will control title_sw's scrollbar. */ setup_syncro_scroll_single( data_sw, title_sw, orientation ) Widget data_sw; Widget title_sw; String orientation; { Arg args[2]; Widget sb, sb_move_me; if (!data_sw || !title_sw) { /* at least one of the scrolled windows given is null */ printf("setup_syncro_scroll: given null widget\n"); return(-1); } XtSetArg( args[0], orientation, &sb); XtGetValues( data_sw, args, 1 ); if (!sb) { printf("data area's %s scrollbar not found\n", orientation); return(-1); } XtSetArg( args[0], orientation, &sb_move_me); XtGetValues( title_sw, args, 1 ); if (!sb_move_me) { printf("title area's %s scrollbar not found\n", orientation); return(-1); } /* both scrollbars found */ add_sb_callbacks( sb, sb_move_me ); return(0); } add_sb_callbacks( sb, to_be_moved_sb ) Widget sb, to_be_moved_sb; { extern void ScrollCB(); XtAddCallback(sb, XmNdecrementCallback, ScrollCB, to_be_moved_sb ); XtAddCallback(sb, XmNdragCallback, ScrollCB, to_be_moved_sb ); XtAddCallback(sb, XmNincrementCallback, ScrollCB, to_be_moved_sb ); XtAddCallback(sb, XmNpageDecrementCallback, ScrollCB, to_be_moved_sb ); XtAddCallback(sb, XmNpageIncrementCallback, ScrollCB, to_be_moved_sb ); XtAddCallback(sb, XmNtoBottomCallback, ScrollCB, to_be_moved_sb ); XtAddCallback(sb, XmNtoTopCallback, ScrollCB, to_be_moved_sb ); XtAddCallback(sb, XmNvalueChangedCallback, ScrollCB, to_be_moved_sb ); return(0); } void ScrollCB( sb, to_be_moved_sb, data ) Widget sb; Widget to_be_moved_sb; XmAnyCallbackStruct *data; { int value; int slider_size; int increment; int page_increment; XmScrollBarGetValues( sb, &value, &slider_size, &increment, &page_increment ); XmScrollBarSetValues( to_be_moved_sb, value, slider_size, increment, page_increment ); } -------------------------- code ends here -------------------------- As you can see, the whole key is to call XmScrollBarGetValues() on the scrollbar being moved and set the slave scrollbar's values with XmScrollBarSetValues. Be sure that the two areas being managed are the same width/height! (otherwise you will get LOTS of toolkit warning messages) Gary Henry Andersen Consulting nasg@anaxagoras.ils.nwu.edu