#By George Peter Staplin
#This is public-domain software. You may use it however you
#want; with or without giving me credit.
#When I get some spare time I will add error handling to the
#config instance command, and the initial flags.
namespace eval ctable {
variable firstX
}
proc ctable::drawSlider:setInitialPosition x {
variable firstX
set firstX $x
}
proc ctable::dragSlider {sep frame1 x} {
variable firstX
set win [winfo parent $sep]
set diff [expr {$x - $firstX}]
set xUnits [expr {1.0 / [winfo width $win]}]
set haveSecondFrame 0
set frame2 [expr {$frame1 + 1}]
array set arF0 [place info $win.f$frame1]
array set arS0 [place info $win.sep$frame1]
if {[winfo exists $win.f$frame2] == 1} {
array set arF1 [place info $win.f$frame2]
set haveSecondFrame 1
}
set xdiff [expr {$diff * $xUnits}]
place $win.f$frame1 -relwidth [expr {$arF0(-relwidth) + $xdiff}]
place $win.sep$frame1 -relx [expr {$arS0(-relx) + $xdiff}]
if {$haveSecondFrame == 1} {
place $win.f$frame2 -relx [expr {$arF1(-relx) + $xdiff}]
place $win.f$frame2 -relwidth [expr {$arF1(-relwidth) - $xdiff}]
}
set firstX $x
return
}
proc ctable {win args} {
frame $win
set cmdArgs(-columns) 5
set cmdArgs(-rows) 5
array set cmdArgs $args
set relxPortion [expr {1.0 / $cmdArgs(-columns)}]
set relx 0
for {set i 0} {$i < $cmdArgs(-columns)} {incr i} {
place [frame $win.f$i] -relx $relx -relwidth $relxPortion
pack [entry $win.f$i.e0 -bg gray70 -relief raised] \
-side top -fill x -padx 6 -ipadx 4
for {set rowIndex 1} {$rowIndex <= $cmdArgs(-rows)} {incr rowIndex} {
pack [entry $win.f$i.e$rowIndex] -side top -fill x -padx 6
}
set relx [expr {$relx + $relxPortion}]
#puts $relx
}
set relx $relxPortion
for {set sepIndex 0} {$sepIndex < ($cmdArgs(-columns) - 1)} {incr sepIndex} {
place [frame $win.sep$sepIndex -bg gray70 -width 8 \
-cursor sb_h_double_arrow -relief raised -bd 1] -relx $relx \
-x -4 -relheight 1.0
set relx [expr {$relx + $relxPortion}]
bind $win.sep$sepIndex <Button-1> "ctable::drawSlider:setInitialPosition %X"
bind $win.sep$sepIndex <B1-Motion> "ctable::dragSlider %W $sepIndex %X"
}
set mapCmd {}
if {[info exists cmdArgs(-height)] == 1} {
append mapCmd "%W configure -height $cmdArgs(-height); "
} else {
append mapCmd "%W configure -height \[winfo height %W.f0\]; "
}
if {[info exists cmdArgs(-width)] == 1} {
append mapCmd "%W configure -width $cmdArgs(-width)"
} else {
append mapCmd "%W configure -width \[expr {$cmdArgs(-columns) * 100}\]"
}
update idletasks
bind $win <Map> $mapCmd
rename $win _ctable$win
proc $win {cmd args} {
set self [lindex [info level 0] 0]
set actWin _ctable$self
if {$cmd == "config"} {
set cmd configure
}
switch -- $cmd {
configure {
eval $actWin config $args
}
insert {
if {[llength $args] != 3} {
return -code error {invalid number of arguments: use .instance insert column row data}
}
set column [lindex $args 0]
set row [lindex $args 1]
set data [list [lindex $args 2]]
eval $self.f$column.e$row insert 0 $data
}
}
}
return $win
}Test Code
#!/usr/local/bin/wish8.3
source ./ctable.tcl
proc main {} {
pack [ctable .t -columns 4 -rows 5] -side top -fill both
#column 0 row 0
.t insert 0 0 {First Name}
.t insert 1 0 {Last Name}
.t insert 2 0 Job
.t insert 3 0 {Primary Key}
set i 1
foreach fname {Angelica Henry Richard John Jane} {
.t insert 0 $i $fname
incr i
}
set i 1
foreach lname {Smith Fresco Scorso Doe Doe} {
.t insert 1 $i $lname
incr i
}
set i 1
foreach job {Marketing Sales Projections {Information Systems} \
{Sanitation Engineer}} {
.t insert 2 $i $job
incr i
}
for {set i 1} {$i <= 5} {incr i} {
.t insert 3 $i $i
}
}
main
(Image link broken on Sep. 15, 2011)
