From: crowley@fiveup.cs.unm.edu (Charlie Crowley)
Newsgroups: comp.lang.tcl
Subject: Re: scrollbar styles
Date: 10 Sep 92 23:37:56 GMT
Article-I.D.: fiveup.BuDyyw.86z
Organization: Computer Science Department, University of New Mexico

In article <1992Sep10.150818.4308@terminator.cc.umich.edu> normanb@citi.umich.edu writes:
>Has anyone come up with a way for Tk scrollbars to behave in a style similar
>to Athena scrollbars?  I am especially interested in the Athena features
>of:
>
>    Button 1 or 3 to move up or down, respectively,
>    Amount of page to scroll dependent on where cursor is located
>	in the scrollbar,
>    Middle button to move to arbitrary location in document, without
>	having to explicitly grab the slider.
>
>Maybe it's just familiarity from longer use, but I find the Athena
>behaviour more convenient and richer than the up and down arrows
>at each end of the Tk scrollbars.

I got used to that style working for Xerox and still like it.  The Motif
style is based on the Macintosh style of scrolling that was determined
by the fact that they decided on a one button mouse.

The main thing I like about this style of scrolling is the "line to top"
behavior which allows fast and exact positioning in the window.  I use
it to get the top of the procedure to the top of the window.

It is fairly easy to get the Tk scroll bars to act that way.  The tcl
code to do so follows.  A couple of notes:

1. Button1ScrollsDown determines which way is up.  Make it false or just
eliminate it to get Athena like behavior.  My mental model is to rotate
the mouse to 3 o'clock so I use it but the Athena mental model is to
rotate the mouse to 9 o'clock.

2. The continuous scrolling is commented out because it does not work.
Maybe someone can tell me what I am doing wrong.  I worked on it for
a while but then decided I had other things to do.  If you do fix it
you might want to change the delay constants of 350 (to start) and
50 (to repeat) ms.

3. Replace the XXX in the binding to the parent of the scrollbar and
listbox (or whatevery you are scrolling).

bind XXX.scroll <ButtonPress-1>   "Scroll 1 XXX.list %y"
bind XXX.scroll <ButtonRelease-1> "StopScroll"
bind XXX.scroll <Leave>           "StopScroll"
bind XXX.scroll <ButtonPress-2>   "Scroll 2 XXX.list %y"
bind XXX.scroll <ButtonPress-3>   "Scroll 3 XXX.list %y"
bind XXX.scroll <ButtonRelease-3> "StopScroll"
bind XXX.scroll <B2-Motion>       "Scroll 2 XXX.list %y"

proc Scroll {how list y} {
	global ContinuousScrolling
	if $Button1ScrollsDown {
		if {$how==1} {
			set how 3
		} else {
			if {$how==3} {
				set how 1
			}
		}
	}
	if {$how==1} {
		set nearest [$list nearest $y]
		set top [$list nearest 0]
		set up [expr $top-$nearest]
		if {$up==0} { set up -1 }
		set new_top [expr $top+$up]
		if {$new_top<0} {set new_top 0}
		$list yview $new_top
###		set ContinuousScrolling 1
###		after 350 ScrollAgain $list $up
	} else {
		if {$how==2} {
			set high [winfo height $list]
			set size [$list size]
			set new_top [expr ($y*$size)/$high]
			$list yview $new_top
		} else {
			set top [$list nearest 0]
			set new_top [$list nearest $y]
			if {$top==$new_top} { incr new_top }
			$list yview $new_top
###			set ContinuousScrolling 1
###			set down [expr $new_top-$top]
###			after 350 ScrollAgain $list $down
		}
	}
}

proc ScrollAgain {list incr} {
	global ContinuousScrolling
	if !ContinuousScrolling { return }
	set top [$list nearest 0]
	set new_top [expr $top+$incr]
	if {$new_top<0} {set new_top 0}
	$list yview $new_top
	after 50 ScrollAgain $list $incr
}

proc StopScroll {} {
	global ContinuousScrolling
	set ContinuousScrolling 0
}

Charlie Crowley
Univ. of New Mexico Cs Dept.
-- 
Computer Science Dept.   +-----------------+ (505) 277-5446, (msgs) 277-3112
University of New Mexico | Charlie Crowley | INTERNET: crowley@unmvax.unm.edu
Albuquerque, NM 87131    +-----------------+
Newsgroups: comp.lang.tcl