A tiny notebook

Richard Suchenwirth 2006-11-29 - I needed a simple notebook for end-users having just basic Tcl/Tk, without BWidget or other extensions. This page documents the small solution I ended up with - you can basically just add or raise pages (see below for deleting pages), but that's all I needed.

WikiDbImage notebook.jpg

Bug: before a user has resized the window, the notebook's size varies according to the content of the current page. This can also be helped by a wm geometry command, as seen in the demo below.


 proc notebook {w args} {
    frame $w
    pack [frame $w.top] -side top -fill x -anchor w
    rename $w _$w
    proc $w {cmd args} { #-- overloaded frame command
        set w [lindex [info level 0] 0]
        switch -- $cmd {
            add     {notebook'add   $w $args}
            raise   {notebook'raise $w $args}
            default {eval [linsert $args 0 _$w $cmd]}
        }
    }
    return $w
 }
 proc notebook'add {w title} {
    set btn [button $w.top.b$title -text $title -command [list $w raise $title]]
    pack $btn -side left -ipadx 5
    set f [frame $w.f$title -relief raised -borderwidth 2]
    pack $f -fill both -expand 1
    $btn invoke
    bind $btn <3> "destroy {$btn}; destroy {$f}" ;# (1)
    return $f
 }
 proc notebook'raise {w title} {
    foreach i [winfo children $w.top] {$i config -borderwidth 0}
    $w.top.b$title config -borderwidth 1
    set frame $w.f$title
    foreach i [winfo children $w] {
        if {![string match *top $i] && $i ne $frame} {pack forget $i}
    }
    pack $frame -fill both -expand 1
 }
#----------------------------------------- test and demo code
 package require Tk
 pack [notebook .n] -fill both -expand 1
 set p1 [.n add Text]
 pack [text $p1.t -wrap word] -fill both -expand 1
 set p2 [.n add Canvas]
 pack [canvas $p2.c -bg yellow] -fill both -expand 1
 set p3 [.n add Options]
 pack [button $p3.1 -text Console -command {console show}]
 .n raise Text
 wm geometry . 400x300

(1): Adding this line adds the capability of deleting a page by just right-clicking on its tab.