# scroll.tcl
#
# ****************************************************************************
# Copyright (c) 2001 Digi International Inc., All Rights Reserved
# 
# This software contains proprietary and confidential information of Digi
# International Inc.  By accepting transfer of this copy, Recipient agrees
# to retain this software in confidence, to prevent disclosure to others,
# and to make no use of this software other than that for which it was
# delivered.  This is an unpublished copyrighted work of Digi International
# Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
# prohibited.
# 
# Restricted Rights Legend
#
# Use, duplication, or disclosure by the Government is subject to
# restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
# Technical Data and Computer Software clause at DFARS 252.227-7031 or
# subparagraphs (c)(1) and (2) of the Commercial Computer Software -
# Restricted Rights at 48 CFR 52.227-19, as applicable.
#
# Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
#
# ***************************************************************************

## This widget implements a frame with a vertical scrollbar that can be
## placed in a toplevel widget with other frames.  Widgets can be added
## and removed from the scrolled frame at run time and the toplevel
## will dynamically resize. The frame will begin to scroll a preset max 
## height is reached. The trick is to pass the height of the other
## frames so that the toplevel can be correctly resized when widgets are
## added and removed from the scrolled frame.
## This is accomplished using a windowed frame in a canvas.  The main proc
## returns the names of the outer frame and the inner frame.  Pack (grid etc.)
## the outer frame but put widgets in the inner frame.
## KNOWN BUG:
## On Windows it works fine.  But on UNIXes the toplevel will shrink a little if 
## the user moves the toplevel.  After that happens, it will only get correctly 
## resized if the scrollbar is moved or if a widget is added/removed.  I think 
## it is because the window manager is unaware of the menu or titlebar height. 
package provide Tools 1.0
namespace eval Scroll {
proc scrolledframe {w heightOtherFrameName heightMaxName} {

	set frameOuter [frame $w.f ]
	set scrollY [scrollbar $frameOuter.yscroll -command [list $frameOuter.c yview] -orient vertical]
	set c [canvas $frameOuter.c -yscrollcommand [list $frameOuter.yscroll set] ]

	pack $scrollY -side right -fill y
	pack $c -side left -expand true -fill both 
	set frameInner [frame $c.fc ]
	$c create window 0 0 -anchor nw -window $frameInner
	set scrollbarWidth [winfo reqwidth $scrollY]   
	bind $frameInner <Configure> "[list Scroll::resize $w $frameInner $c $scrollbarWidth $heightOtherFrameName $heightMaxName]"
    
    return [list $frameOuter $frameInner]
}

proc resize {w frameInner c scrollbarWidth heightOtherFrameName heightMaxName} {
	# Get the value of the global variables
	upvar #0 $heightOtherFrameName heightOtherFrame
	upvar #0 $heightMaxName heightMax
	set width [expr {[winfo reqwidth $frameInner] + $scrollbarWidth}]
	set height [winfo reqheight $frameInner]
	set winWidth [winfo reqwidth $w]
	if {$width > $winWidth} {
		set winWidth $width
	}	
	if {[expr {$height + $heightOtherFrame}] > $heightMax} {
		set winHeight $heightMax
	} else {
		set winHeight [expr {$height + $heightOtherFrame}]		
	}
	$c configure -scrollregion "0 0 $width $height"
	if { [winfo width $w] == $winWidth && [winfo height $w] == $winHeight } {
		## The new size needed is the same as the current size, do nothing
	} else {
		wm geometry $w "$winWidth\x$winHeight"
	}
    return
}


} ;# end namespace Scroll