You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

466 lines
10 KiB

# -*- mode: TCL; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*-
#
# $Id: SWidget.tcl,v 1.5 2002/01/24 09:13:58 idiscovery Exp $
#
# SWidget.tcl --
#
# tixScrolledWidget: virtual base class. Do not instantiate
# This is the core class for all scrolled widgets.
#
# Copyright (c) 1993-1999 Ioi Kim Lam.
# Copyright (c) 2000-2001 Tix Project Group.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
tixWidgetClass tixScrolledWidget {
-virtual true
-classname TixScrolledWidget
-superclass tixPrimitive
-method {
}
-flag {
-scrollbar -scrollbarspace
}
-configspec {
{-scrollbar scrollbar Scrollbar both}
{-scrollbarspace scrollbarSpace ScrollbarSpace {both}}
{-sizebox sizeBox SizeBox 0}
}
}
proc tixScrolledWidget:InitWidgetRec {w} {
upvar #0 $w data
tixChainMethod $w InitWidgetRec
set data(x,first) 0
set data(x,last) 0
set data(y,first) 0
set data(y,last) 0
set data(lastSpec) ""
set data(lastMW) ""
set data(lastMH) ""
set data(lastScbW) ""
set data(lastScbH) ""
set data(repack) 0
set data(counter) 0
set data(vsbPadY) 0
set data(hsbPadX) 0
}
proc tixScrolledWidget:SetBindings {w} {
upvar #0 $w data
tixChainMethod $w SetBindings
tixManageGeometry $data(pw:client) "tixScrolledWidget:ClientGeomProc $w"
bind $data(pw:client) <Configure> \
[list tixScrolledWidget:ClientGeomProc $w "" $data(pw:client)]
tixManageGeometry $data(w:hsb) "tixScrolledWidget:ClientGeomProc $w"
bind $data(w:hsb) <Configure> \
[list tixScrolledWidget:ClientGeomProc $w "" $data(w:hsb)]
tixManageGeometry $data(w:vsb) "tixScrolledWidget:ClientGeomProc $w"
bind $data(w:vsb) <Configure> \
[list tixScrolledWidget:ClientGeomProc $w "" $data(w:vsb)]
bind $w <Configure> "tixScrolledWidget:MasterGeomProc $w"
tixWidgetDoWhenIdle tixScrolledWidget:Repack $w
set data(repack) 1
}
proc tixScrolledWidget:config-scrollbar {w value} {
upvar #0 $w data
global tcl_platform
if {[lindex $value 0] == "auto"} {
foreach xspec [lrange $value 1 end] {
case $xspec {
{+x -x +y -y} {}
default {
error "bad -scrollbar value \"$value\""
}
}
}
} else {
case $value in {
{none x y both} {}
default {
error "bad -scrollbar value \"$value\""
}
}
}
if {$data(-sizebox) && $tcl_platform(platform) == "windows"} {
set data(-scrollbar) both
}
if {$data(repack) == 0} {
set data(repack) 1
tixWidgetDoWhenIdle tixScrolledWidget:Repack $w
}
}
proc tixScrolledWidget:config-scrollbarspace {w value} {
upvar #0 $w data
if {$data(repack) == 0} {
set data(repack) 1
tixWidgetDoWhenIdle tixScrolledWidget:Repack $w
}
}
proc tixScrolledWidget:config-sizebox {w value} {
error "unimplemented"
}
#----------------------------------------------------------------------
#
# Scrollbar calculations
#
#----------------------------------------------------------------------
proc tixScrolledWidget:ClientGeomProc {w type client} {
upvar #0 $w data
if {$data(repack) == 0} {
set data(repack) 1
tixWidgetDoWhenIdle tixScrolledWidget:Repack $w
}
}
proc tixScrolledWidget:MasterGeomProc {w} {
upvar #0 $w data
if {$data(repack) == 0} {
set data(repack) 1
tixWidgetDoWhenIdle tixScrolledWidget:Repack $w
}
}
proc tixScrolledWidget:Configure {w} {
if {![winfo exists $w]} {
return
}
upvar #0 $w data
if {$data(repack) == 0} {
set data(repack) 1
tixWidgetDoWhenIdle tixScrolledWidget:Repack $w
}
}
proc tixScrolledWidget:ScrollCmd {w scrollbar axis first last} {
upvar #0 $w data
$scrollbar set $first $last
}
# Show or hide the scrollbars as required.
#
# spec: 00 = need none
# spec: 01 = need y
# spec: 10 = need x
# spec: 11 = need xy
#
proc tixScrolledWidget:Repack {w} {
tixCallMethod $w RepackHook
}
proc tixScrolledWidget:RepackHook {w} {
upvar #0 $w data
global tcl_platform
if {![winfo exists $w]} {
# This was generated by the <Destroy> event
#
return
}
set client $data(pw:client)
# Calculate the size of the master
#
set mreqw [winfo reqwidth $w]
set mreqh [winfo reqheight $w]
set creqw [winfo reqwidth $client]
set creqh [winfo reqheight $client]
set scbW [winfo reqwidth $w.vsb]
set scbH [winfo reqheight $w.hsb]
case $data(-scrollbarspace) {
"x" {
incr creqh $scbH
}
"y" {
incr creqw $scbW
}
"both" {
incr creqw $scbW
incr creqh $scbH
}
}
if {$data(-width) != 0} {
set creqw $data(-width)
}
if {$data(-height) != 0} {
set creqh $data(-height)
}
if {$mreqw != $creqw || $mreqh != $creqh } {
if {![info exists data(counter)]} {
set data(counter) 0
}
if {$data(counter) < 50} {
incr data(counter)
tixGeometryRequest $w $creqw $creqh
tixWidgetDoWhenIdle tixScrolledWidget:Repack $w
set data(repack) 1
return
}
}
set data(counter) 0
set mw [winfo width $w]
set mh [winfo height $w]
set cw [expr $mw - $scbW]
set ch [expr $mh - $scbH]
set scbx [expr $mw - $scbW]
set scby [expr $mh - $scbH]
# Check the validity of the sizes: if window was not mapped then
# sizes will be below 1x1
if {$cw < 1} {
set cw 1
}
if {$ch < 1} {
set ch 1
}
if {$scbx < 1} {
set scbx 1
}
if {$scby < 1} {
set scby 1
}
if {[lindex $data(-scrollbar) 0] == "auto"} {
# Find out how we are going to pack the scrollbars
#
set spec [tixScrolledWidget:CheckScrollbars $w $scbW $scbH]
foreach xspec [lrange $data(-scrollbar) 1 end] {
case $xspec {
+x {
set spec [expr $spec | 10]
}
-x {
set spec [expr $spec & 01]
}
+y {
set spec [expr $spec | 01]
}
-y {
set spec [expr $spec & 10]
}
}
}
if {$spec == 0} {
set spec 00
}
if {$spec == 1} {
set spec 01
}
} else {
case $data(-scrollbar) in {
none {
set spec 00
}
x {
set spec 10
}
y {
set spec 01
}
both {
set spec 11
}
}
}
if {$data(lastSpec)==$spec && $data(lastMW)==$mw && $data(lastMH)==$mh} {
if {$data(lastScbW) == $scbW && $data(lastScbH) == $scbH} {
tixCallMethod $w PlaceWindow
set data(repack) 0
return
}
}
set vsbH [expr $mh - $data(vsbPadY)]
set hsbW [expr $mw - $data(hsbPadX)]
if {$vsbH < 1} {
set vsbH 1
}
if {$hsbW < 1} {
set hsbW 1
}
case $spec in {
"00" {
tixMoveResizeWindow $client 0 0 $mw $mh
tixMapWindow $client
tixUnmapWindow $data(w:hsb)
tixUnmapWindow $data(w:vsb)
}
"01" {
tixMoveResizeWindow $client 0 0 $cw $mh
tixMoveResizeWindow $data(w:vsb) $scbx $data(vsbPadY) $scbW $vsbH
tixMapWindow $client
tixUnmapWindow $data(w:hsb)
tixMapWindow $data(w:vsb)
}
"10" {
tixMoveResizeWindow $client 0 0 $mw $ch
tixMoveResizeWindow $data(w:hsb) $data(hsbPadX) $scby $hsbW $scbH
tixMapWindow $client
tixMapWindow $data(w:hsb)
tixUnmapWindow $data(w:vsb)
}
"11" {
set vsbH [expr $ch - $data(vsbPadY)]
set hsbW [expr $cw - $data(hsbPadX)]
if {$vsbH < 1} {
set vsbH 1
}
if {$hsbW < 1} {
set hsbW 1
}
tixMoveResizeWindow $client 0 0 $cw $ch
tixMoveResizeWindow $data(w:vsb) $scbx $data(vsbPadY) $scbW $vsbH
tixMoveResizeWindow $data(w:hsb) $data(hsbPadX) $scby $hsbW $scbH
if {$data(-sizebox) && $tcl_platform(platform) == "windows"} {
tixMoveResizeWindow $data(w:sizebox) $scbx $scby $scbW $scbH
}
tixMapWindow $client
tixMapWindow $data(w:hsb)
tixMapWindow $data(w:vsb)
if {$data(-sizebox) && $tcl_platform(platform) == "windows"} {
tixMapWindow $data(w:sizebox)
}
}
}
set data(lastSpec) $spec
set data(lastMW) $mw
set data(lastMH) $mh
set data(lastScbW) $scbW
set data(lastScbH) $scbH
tixCallMethod $w PlaceWindow
set data(repack) 0
}
proc tixScrolledWidget:PlaceWindow {w} {
# virtual base function
}
#
# Helper function
#
proc tixScrolledWidget:NeedScrollbar {w axis} {
upvar #0 $w data
if {$data($axis,first) > 0.0} {
return 1
}
if {$data($axis,last) < 1.0} {
return 1
}
return 0
}
# Return whether H and V needs scrollbars in a list of two booleans
#
#
proc tixScrolledWidget:CheckScrollbars {w scbW scbH} {
upvar #0 $w data
set mW [winfo width $w]
set mH [winfo height $w]
set info [tixCallMethod $w GeometryInfo $mW $mH]
if {$info != ""} {
set xSpec [lindex $info 0]
set ySpec [lindex $info 1]
set data(x,first) [lindex $xSpec 0]
set data(x,last) [lindex $xSpec 1]
set data(y,first) [lindex $ySpec 0]
set data(y,last) [lindex $ySpec 1]
}
set needX [tixScrolledWidget:NeedScrollbar $w x]
set needY [tixScrolledWidget:NeedScrollbar $w y]
if {[winfo ismapped $w]==0} {
return "$needX$needY"
}
if {$needX && $needY} {
return 11
}
if {$needX == 0 && $needY == 0} {
return 00
}
if {$needX} {
set mH [expr $mH - $scbH]
}
if {$needY} {
set mW [expr $mW - $scbW]
}
set info [tixCallMethod $w GeometryInfo $mW $mH]
if {$info != ""} {
set xSpec [lindex $info 0]
set ySpec [lindex $info 1]
set data(x,first) [lindex $xSpec 0]
set data(x,last) [lindex $xSpec 1]
set data(y,first) [lindex $ySpec 0]
set data(y,last) [lindex $ySpec 1]
}
set needX [tixScrolledWidget:NeedScrollbar $w x]
set needY [tixScrolledWidget:NeedScrollbar $w y]
return "$needX$needY"
}