Version 0 of SnitTtkNotebook

Updated 2018-02-05 18:37:00 by DDG

Just an extension which can be used like the standard ttk::treeview

  • All options and methods are delegated to ttk::treeview
  • There are the following bindings provided if notebook has focus
    • F2 or right mouse click - rename tab
    • Control-Shift-left move tab to the left
    • Control-Shift-right move tab to the right
    • Control-w delete current tab and destroy its childs
    • Control-t create new tab
  • a createcmd option is added to perform an action after the user creates an new tab

Enter page contents here, upload content using the button above, or click cancel to leave it empty.

package require snit
package provide SnitTtkNotebook 0.1

snit::widget SnitTtkNotebook {
    option -createcmd ""
    option -closecmd ""
    variable nb
    variable nbtext
    variable child
    delegate option * to nb
    delegate method * to nb except add
    constructor {args} {
        $self configurelist $args
        install nb using ttk::notebook $win.nb ;#-side top -width 150 -height 50        
        pack $nb -fill both -expand yes -side top
        bind $nb <KeyPress-F2> [mymethod tabRename %x %y]
        bind $nb <Button-3> [mymethod tabRename %x %y]        
        bind $nb <Control-Shift-Left> [mymethod tabMove left %W]
        bind $nb <Control-Shift-Right> [mymethod tabMove right %W]
        bind $nb <Control-w> [mymethod tabClose %W]        
        bind $nb <Control-t> [mymethod new %W]        
        bind $nb <Enter> [list focus -force $nb]
    }
    method add {page args} {
        $nb add $page {*}$args
        if {$options(-createcmd) ne ""} {
            eval $options(-createcmd) $nb $page
        }
    }
    method new {w} {
        frame $nb.f[llength [$nb tabs]]
        $nb add $nb.f[llength [$nb tabs]] -text "Tab [expr {[llength [$nb tabs]] + 1}]"
    }
    method tabClose {w} {
        set child [$w select]
        set answer [tk_messageBox -title "Question!" -message "Really close tab [$w tab $child -text] ?" -type yesno -icon question]
        if { $answer } {
            $w forget $child
            destroy $child
        } 
    }
    method tabRename {x y} {
        set nbtext ""
        if {![info exists .rename]} {
            toplevel .rename
            wm overrideredirect .rename true
            #wm title .rename "DGApp" ;# for floating on i3
            set x [winfo pointerx .]
            set y [winfo pointery .]
            entry .rename.ent -textvariable [myvar nbtext]
            pack .rename.ent -padx 5 -pady 5
        }
        wm geometry .rename "180x40+$x+$y"
        set tab [$nb select]
        set nbtext [$nb tab $tab -text]
        
        bind .rename.ent <Return> [mymethod doTabRename %W]
        bind .rename.ent <Escape> [list destroy .rename]
        
    }
    method doTabRename {w} {
        set tab [$nb select]
        $nb tab $tab -text $nbtext
        destroy .rename
    }
    method tabMove {dir w} {
        puts move$dir
        set idx [lsearch [$nb tabs] [$nb select]]
        puts $idx
        set current [$nb select]
        if {$dir eq "left"} {
            if {$idx > 0} {
                $nb insert [expr {$idx - 1}]  $current
            }
        } else {
            if {$idx < [expr {[llength [$nb tabs]] -1}]} {
                $nb insert [expr {$idx + 1}] $current
            }
        }
        # how to break automatic switch??
        after 100 [list $nb select $current]
    }
}

if {$argv0 eq [info script]} {
    if {[llength $argv] <= 1 } {
        proc testCreate {w page} {
            puts "$w $page"
        }
        set nb [SnitTtkNotebook .nb -createcmd testCreate]
        frame .nb.f1
        pack [label .nb.f1.l -text "Tab Content 1"]
        pack [text .nb.f1.t] -side top -fill both -expand true
        frame .nb.f2
        pack [label .nb.f2.l -text "Tab Content 2"]
        frame .nb.f3
        pack [label .nb.f3.l -text "Tab Content 3"]
        $nb add .nb.f1 -text "Tab 1"
        $nb add .nb.f2 -text "Tab 2"
        $nb add .nb.f3 -text "Tab 3"                
        pack $nb -side top -fill both -expand yes
    }
}