JOB 2016-05-01, A TclOO class template to extend tablelist functionality.
Might be useful as a starting point to create a tablelist megawidget with extended functionality.
# ----------------------------------------------------------------------------- # xtablelist_template.tcl --- # ----------------------------------------------------------------------------- # (c) 2016, Johann Oberdorfer - Engineering Support | CAD | Software # johann.oberdorfer [at] gmail.com # www.johann-oberdorfer.eu # ----------------------------------------------------------------------------- # This source file is distributed under the BSD license. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the BSD License for more details. # ----------------------------------------------------------------------------- # Purpose: # A TclOO class template to extend tablelist functionality. # Might be usefull as a starting point. # ----------------------------------------------------------------------------- # TclOO naming conventions: # public methods - starts with lower case declaration names, whereas # private methods - starts with uppercase naming, so we use CamelCase ... # ----------------------------------------------------------------------------- # for development: try to find autoscroll, etc ... set this_file [file normalize [file dirname [info script]]] # where to find required packages... # set auto_path [linsert $auto_path 0 [file join $this_file ".." "contrib" ]] package require Tk package require TclOO package require tablelist_tile package provide xtablelist 0.2 namespace eval xtablelist { variable cnt 0 # this is a tk-like wrapper around my... class so that # object creation works like other tk widgets proc xtablelist {path args} { variable cnt set obj [TablelistClass create tmp${cnt} $path {*}$args] incr cnt # rename oldName newName rename $obj ::$path return $path } } # ----------------------------------------------------------------------------- # widget interface declaration # ----------------------------------------------------------------------------- oo::class create TablelistClass { constructor {path args} { my variable tblwidget my variable widgetOptions # declaration of all additional widget options array set widgetOptions { -xtabheader {} } # incorporate arguments to local widget options array set widgetOptions $args # we use a frame for this specific widget class set f [ttk::frame $path -class Xtablelist] # we must rename the widget command # since it clashes with the object being created set widget ${path}_ rename $path $widget my Build $f my configure {*}$args } destructor { # clean up once the widget get's destroyed set w [namespace tail [self]] catch {bind $w <Destroy> {}} catch {destroy $w} } method cget { {opt "" } } { my variable tblwidget my variable widgetOptions if { [string length $opt] == 0 } { return [array get widgetOptions] } if { [info exists widgetOptions($opt) ] } { return $widgetOptions($opt) } return [$tblwidget cget $opt] } method configure { args } { my variable tblwidget my variable widgetOptions if {[llength $args] == 0} { # return all tablelist options set opt_list [$tblwidget configure] # as well as all custom options foreach xopt [array get widgetOptions] { lappend opt_list $xopt } return $opt_list } elseif {[llength $args] == 1} { # return configuration value for this option set opt $args if { [info exists widgetOptions($opt) ] } { return $widgetOptions($opt) } return [$tblwidget cget $opt] } # error checking if {[expr {[llength $args]%2}] == 1} { return -code error "value for \"[lindex $args end]\" missing" } # process the new configuration options... array set opts $args foreach opt_name [array names opts] { set opt_value $opts($opt_name) # overwrite with new value if { [info exists widgetOptions($opt_name)] } { set widgetOptions($opt_name) $opt_value } # some options need action from the widgets side switch -- $opt_name { -xtabheader { my InitializeTabHeader $opt_value } default { # if the configure option wasn't one of our special one's, # pass control over to the original tablelist widget if {[catch {$tblwidget configure $opt_name $opt_value} result]} { return -code error $result } } } } } method unknown {method args} { my variable tblwidget # if the command wasn't one of our special one's, # pass control over to the original tablelist widget if {[catch {$tblwidget $method {*}$args} result]} { return -code error $result } return $result } } # ----------------------------------------------------------------------------- # public methods # ----------------------------------------------------------------------------- oo::define TablelistClass { method enablemoveover {} { my variable tblwidget # move-over effect: bind [$tblwidget bodypath] <Motion> {+ set t [winfo parent %W] set x [expr {%x + [winfo x %W]}] set y [expr {%y + [winfo y %W]}] # set cell [$t nearestcell $x $y] # puts "Clicked on cell: $cell " # set rownum [lindex [split $cell ","] 0] focus $t $t configure -activestyle frame $t activate "@$x,$y" } bind [$tblwidget bodypath] <Leave> {+ set t [winfo parent %W] $t configure -activestyle none } } } # ----------------------------------------------------------------------------- # private methods # ----------------------------------------------------------------------------- oo::define TablelistClass { method InitializeTabHeader {kword_list} { my variable tblwidget set cols "" set cnt 0 foreach i $kword_list { set descr [lindex $i 0] set visual [lindex $i 1] set orient [lindex $i 2] if {[string length $orient] == 0} { set orient "left" } regsub -all " " $descr "_" descr if {$descr != "..." && [string range $descr end end] != ":"} { set descr "${descr}:" } # could be either a string or an integer: if {$visual == "hidden"} { set width 20 } else { set width $visual } append cols "$width $descr $orient " incr cnt } $tblwidget configure -columns $cols # hide specific columns as indicated with "hidden" in declaration array set cnt 0 foreach i $kword_list { if {[set width [lindex $i 1]] == "hidden"} { $tblwidget columnconfigure $cnt -hide yes } incr cnt } # expand last *visible* column # ---------------------------- set cnt 0 set lastcol 0 # tablelist -columns option are always 3 attributes each... foreach {w col pos} [$tblwidget cget -columns] { if {[$tblwidget columncget $cnt -hide] == 0} {set lastcol $cnt} incr cnt } if {$lastcol > 0} { $tblwidget configure -stretch $lastcol } } method Build {f} { my variable tblwidget ::tablelist::tablelist $f.tlist pack $f.tlist -side top -fill both -expand true set tblwidget $f.tlist } } # ----------------------------------------------------------------------------- # demo code # ----------------------------------------------------------------------------- if {1} { catch {console show} set t [xtablelist::xtablelist .t \ -showseparators yes \ -selectmode single \ -labelcommand "tablelist::sortByColumn"] pack $t -fill both -expand true set header \ {{"hidden_column" "hidden" left} {"Category" 22 left} {"test-column" 16 left} {"Hello\\nWorld" 10 left} {"test" 11 center} {"last\\ncolumn" 10 left}} $t configure \ -xtabheader $header # create some random test data... set data_list {} set cnt 0 while {$cnt < 40} { lappend data_list \ [list $cnt \ [expr {$cnt +1}] [expr {$cnt +2}] \ [expr {$cnt +3}] [expr {$cnt +4}] \ [expr {$cnt +5}]] incr cnt } # --------------------- # object introspection: # --------------------- # puts [winfo class $t] # puts [$t configure] # catch { [$t blabla 1] } msg # puts $msg # return foreach item $data_list { $t insert end $item } # puts [$t cget -xtabheader] # how to access the tablelist widget: # [$t getwidgetpath] configure -columns \ # "12 Test1 left 12 Test2 left" # $t selection clear 0 end # puts [$t curselection] $t enablemoveover }
Category: Playing with TclOO - enjoy.