File: scroll.tcl

package info (click to toggle)
moodss 5.0-2
  • links: PTS
  • area: main
  • in suites: slink
  • size: 1,104 kB
  • ctags: 430
  • sloc: tcl: 12,266; sh: 59; makefile: 43
file content (103 lines) | stat: -rw-r--r-- 4,725 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
set rcsId {$Id: scroll.tcl,v 1.9 1998/10/04 14:57:52 jfontain Exp $}

# generic scroll widget with automatic scrollbars for scrolling widgets with the common tk scroll interface

class scroll {

    proc scroll {this scrollableClass parentPath args} composite {[new frame $parentPath] $args} {
        # scrollable class widget must accept the -[xy]scrollcommand options and [xy]view commands, such as canvas, text, table, ...
        set path $widget::($this,path)
        composite::manage $this [new $scrollableClass $path] scrolled\
            [new scrollbar $path -orient horizontal] horizontal [new scrollbar $path] vertical [new frame $path] filler

        widget::configure $composite::($this,scrolled)\
            -xscrollcommand "scroll::update $this 1 0" -yscrollcommand "scroll::update $this 0 1"
        widget::configure $composite::($this,horizontal) -command "$composite::($this,scrolled,path) xview"
        widget::configure $composite::($this,vertical) -command "$composite::($this,scrolled,path) yview"

        grid propagate $widget::($this,path) 0                  ;# turn off propagation so that setting width and height is possible

        grid $composite::($this,scrolled,path) -sticky nsew
        grid rowconfigure $path 0 -weight 1
        grid columnconfigure $path 0 -weight 1

        set scroll::($this,0,1,path) $composite::($this,vertical,path)
        set scroll::($this,1,0,path) $composite::($this,horizontal,path)

        composite::complete $this
    }

    proc ~scroll {this} {}

    proc options {this} {
        return [list\
            [list -automatic automatic Automatic 1 1]\
            [list\
                -scrollbarborderwidth scrollbarBorderWidth ScrollbarBorderWidth\
                $widget::(default,ScrollbarBorderWidth) $widget::(default,ScrollbarBorderWidth)\
            ]\
            [list\
                -scrollbarelementborderwidth scrollbarElementBorderWidth ScrollbarElementBorderWidth\
                $widget::(default,ScrollbarElementBorderWidth) $widget::(default,ScrollbarElementBorderWidth)\
            ]\
            [list\
                -scrollbarwidth scrollbarWidth ScrollbarWidth $widget::(default,ScrollbarWidth) $widget::(default,ScrollbarWidth)\
            ]\
            [list -height height Height $widget::(default,CanvasHeight)]\
            [list -horizontal horizontal Horizontal 1 1]\
            [list -vertical vertical Vertical 1 1]\
            [list -width width Width $widget::(default,CanvasWidth)]\
        ]
    }

    foreach option {-automatic -horizontal -vertical} {
        proc set$option {this value} "
            if {\$composite::(\$this,complete)} {
                error {option $option cannot be set dynamically}
            }
        "
    }

   foreach option {borderwidth elementborderwidth width} {
        proc set-scrollbar$option {this value} "
            \$composite::(\$this,vertical,path) configure -$option \$value
            \$composite::(\$this,horizontal,path) configure -$option \$value
        "
    }

    proc set-height {this value} {
        $widget::($this,path) configure -height $value
    }

    proc set-width {this value} {
        $widget::($this,path) configure -width $value
    }

    proc update {this row column first last} {
        set path $scroll::($this,$row,$column,path)
        foreach {previousFirst previousLast} [$path get] {}
        if {($first!=$previousFirst)||($last!=$previousLast)} {                                        ;# update only when necessary
            $path set $first $last
        }
        set visible [llength [grid info $path]]
        if {!$composite::($this,-automatic)||(($last-$first)<1)} {
            if {!$visible} {                                             ;# map both scrollbars at the same time to avoid vibrations
                if {$composite::($this,-vertical)} {
                    grid $composite::($this,vertical,path) -row 0 -column 1 -sticky nsew
                }
                if {$composite::($this,-horizontal)} {
                    grid $composite::($this,horizontal,path) -row 1 -column 0 -sticky nsew
                }
                grid $composite::($this,filler,path) -sticky nsew -column 1 -row 1
            }
        } else {
            foreach {first last} [$scroll::($this,$column,$row,path) get] {}                        ;# look at other scrollbar range
            if {$visible&&(($last-$first)>=1)} {                       ;# unmap both scrollbars at the same time to avoid vibrations
                grid remove $scroll::($this,0,1,path)
                grid remove $scroll::($this,1,0,path)
                grid remove $composite::($this,filler,path)
            }
        }
    }

}