File: viewport.tcl

package info (click to toggle)
et 80b2-8
  • links: PTS
  • area: main
  • in suites: potato, slink
  • size: 1,068 kB
  • ctags: 1,074
  • sloc: ansic: 10,313; tcl: 2,633; makefile: 179; sh: 19
file content (74 lines) | stat: -rw-r--r-- 2,704 bytes parent folder | download | duplicates (2)
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
#
# This example illustrates how to construct a viewport-like widget using
# a frame and the placer geometry manager.  Five listboxes are constructed
# and placed in a window which is too narrow to hold them all.  A horizontal
# scrollbar allows the listboxes to be moved left or right in their viewport
# window.

# Allow the main window to be resized
wm minsize . 1 1

# Construct the horizontal scrollbar used to scroll the listboxes
scrollbar .hsb -orient horizontal -command HScroll
pack .hsb -side bottom -fill x

# The frame ".f" is the "clipping window".  
frame .f -height 300 -width 600
pack .f -fill both -expand 1

# The frame ".f.f" is the window that gets clipped.  This is the window
# that is moved left and right by the horizontal scrollbar.  The five
# listboxes are all children of this window.
frame .f.f

# Construct the 5 listboxes and fill them with some arbitrary data
set i 1
while {$i<=5} {
  listbox .f.f.lb$i -yscrollcommand ".f.f.sb$i set"
  foreach j {0 1 2 3 4 5 6 7 8 9} {.f.f.lb$i insert end "$i$j"}
  scrollbar .f.f.sb$i -orient vertical -command ".f.f.lb$i yview"
  pack .f.f.lb$i .f.f.sb$i -side left -fill y
  incr i
}

# We have to reset the scrollbar whenever either the clipping window or
# the scrolling window are resized.
bind .f.f <Configure> {HScroll $FirstUnit}
bind .f <Configure> {HScroll $FirstUnit}

# The global variable "FirstUnit" stores and integer which determines where
# the left edge of .f.f is relative to the left edge of .f.  When FirstUnit==0,
# the left edges correspond.  When FirstUnit==1, the left edge of .f.f is
# 10 pixels to the left of the left edge of .f.  And so forth.
set FirstUnit 0

# This function causes the .f.f window to slide left and right within
# the clipping window .f.  It also updates the position of the scrollbar.
#
proc HScroll {x} {
  global FirstUnit

  # totalUnits is an integer proportional to the width of .f.f
  set totalUnits [expr int([winfo reqwidth .f.f]/10)]

  # windowUnits is an integer which is proportional to the amount of
  # .f.f which is actual visible.  If totalUnits is, say, 100, and exactly
  # half of .f.f is visible within .f, then windowUnits will be 50.
  set windowUnits [expr int([winfo width .f]/10)]

  # Limit the range of x so that we don't scroll too far left or right.
  if {$x+$windowUnits>$totalUnits} {
    set x [expr {$totalUnits - $windowUnits}]
  }
  if {$x<0} {
    set x 0
  }
  set FirstUnit $x

  # Adjust the position of the scrollbar thumb
  .hsb set $totalUnits $windowUnits $x [expr $x+$windowUnits]

  # Adjust the position of .f.f within the clipping window .f
  place .f.f -anchor nw -relheight 1 -x [expr -10*$x] -y 0 \
     -width [winfo reqwidth .f.f]
}