GridLines

Keith Vetter : 2008-12-30 : I was reading a WPF book trying to understand how to do control layout (and getting frustrated by how complicated it was).

I did see one neat feature that I thought Tk should have: gridlines [1 ]. When turned on, they show dotted lines outlining the grid cells.

So here's my version of GridLines. You can show or hide them via:

  GridLines <grid master>   => show grid lines for <grid master>
  GridLines <grid master> 1 => delete grid lines for <grid master>

proc GridLines {W {delete 0}} {
    set thick 2
    set fgClr black
    set bgClr white
    
    set prefix ".__gridline_[string map {. _} $W]"

    if {$delete} {
        foreach w [info command $prefix*] {
            destroy $w
        }
        return
    }
    
    foreach {. . width height} [grid bbox $W] break
    foreach {cols rows} [grid size $W] break

    set thick2 [expr {$thick/2.0}]
    set lwidth [expr {$thick+1}]

    for {set row 1} {$row < $rows} {incr row} {
        set y [lindex [grid bbox $W 0 $row] 1]
        set w "${prefix}_row_$row"
        destroy $w
        canvas $w -bd 0 -highlightthickness 0 -width $width -height $thick \
            -bg $bgClr
        $w create line 0 $thick2 $width $thick2 -dash 1 -fill $fgClr -width $lwidth
        place $w -in $W -x 0 -y $y
    }
    for {set col 1} {$col < $cols} {incr col} {
        set x [lindex [grid bbox $W $col 0] 0]
        set w "${prefix}_col_$col"
        destroy $w
        canvas $w -bd 0 -highlightthickness 0 -width $thick -height $height \
            -bg $bgClr
        $w create line $thick2 0 $thick2 $height -dash 1 -fill $fgClr -width $lwidth
        place $w -in $W -x $x -y 0
    }
}
################################################################
#
# Demo code
#
set cells {
    0,0,1,1,blue 0,1,1,1,red 0,2,1,1,green 0,3,1,1,cyan 0,4,1,1,navy
    1,0,1,1,red 1,1,2,1,green 1,2,1,1,cyan 1,3,1,2,yellow 2,0,3,1,blue
    2,2,1,2,navy 2,4,2,1,magenta 3,1,2,3,orange 4,4,1,1,cyan
}
proc ToggleGridLines {W} {
    GridLines $W [expr {! $::S(show)}]
}

set W .top
checkbutton .show -text "Show Grid Lines" -variable ::S(show) \
    -command [list ToggleGridLines $W]
pack [frame $W] -side top
pack .show -side top -pady 5

set W2 [expr {$W eq "." ? "" : $W}]
foreach cell $cells {
    foreach {row col rs cs clr} [split $cell ","] break
    set w $W2.$cell
    label $w -bg $clr -bd 0 -relief solid 
    grid $w -row $row -column $col -rowspan $rs -columnspan $cs -sticky news
}
grid columnconfig $W all -minsize 60
grid rowconfig $W all -minsize 60

foreach {cols rows} [grid size $W] break
for {set col 0} {$col < $cols} {incr col} {
    grid columnconfigure $W $col -minsize [expr {20 + 30*$col}]
}
for {set row 0} {$row < $rows} {incr row} {
    grid rowconfigure $W $row -minsize [expr {20 + 30*$row}]
}
return