📄 tree.tcl
字号:
set result [concat $result $nodes] set st [concat $st $nodes] } } return $result}# ----------------------------------------------------------------------------# Command Tree::see# ----------------------------------------------------------------------------proc Tree::see { path node } { variable $path upvar 0 $path data if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } { after cancel $data(upd,afterid) _redraw_tree $path } set idn [$path.c find withtag n:$node] if { $idn != "" } { Tree::_see $path $idn right Tree::_see $path $idn left }}# ----------------------------------------------------------------------------# Command Tree::opentree# ----------------------------------------------------------------------------# JDC: added option recursiveproc Tree::opentree { path node {recursive 1} } { variable $path upvar 0 $path data if { ![string compare $node "root"] || ![info exists data($node)] } { return -code error "node \"$node\" does not exist" } _recexpand $path $node 1 $recursive [Widget::getoption $path -opencmd] _redraw_idle $path 3}# ----------------------------------------------------------------------------# Command Tree::closetree# ----------------------------------------------------------------------------proc Tree::closetree { path node {recursive 1} } { variable $path upvar 0 $path data if { ![string compare $node "root"] || ![info exists data($node)] } { return -code error "node \"$node\" does not exist" } _recexpand $path $node 0 $recursive [Widget::getoption $path -closecmd] _redraw_idle $path 3}# ----------------------------------------------------------------------------# Command Tree::edit# ----------------------------------------------------------------------------proc Tree::edit { path node text {verifycmd ""} {clickres 0} {select 1}} { variable _edit variable $path upvar 0 $path data if { [Widget::getoption $path -redraw] && $data(upd,afterid) != "" } { after cancel $data(upd,afterid) _redraw_tree $path } set idn [$path.c find withtag n:$node] if { $idn != "" } { Tree::_see $path $idn right Tree::_see $path $idn left set oldfg [$path.c itemcget $idn -fill] set sbg [Widget::getoption $path -selectbackground] set coords [$path.c coords $idn] set x [lindex $coords 0] set y [lindex $coords 1] set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}] set w [expr {[winfo width $path] - 2*$bd}] set wmax [expr {[$path.c canvasx $w]-$x}] set _edit(text) $text set _edit(wait) 0 $path.c itemconfigure $idn -fill [Widget::getoption $path -background] $path.c itemconfigure s:$node -fill {} -outline {} set frame [frame $path.edit \ -relief flat -borderwidth 0 -highlightthickness 0 \ -background [Widget::getoption $path -background]] set ent [entry $frame.edit \ -width 0 \ -relief solid \ -borderwidth 1 \ -highlightthickness 0 \ -foreground [Widget::getoption $path.$node -fill] \ -background [Widget::getoption $path -background] \ -selectforeground [Widget::getoption $path -selectforeground] \ -selectbackground $sbg \ -font [Widget::getoption $path.$node -font] \ -textvariable Tree::_edit(text)] pack $ent -ipadx 8 -anchor w set idw [$path.c create window $x $y -window $frame -anchor w] trace variable Tree::_edit(text) w "Tree::_update_edit_size $path $ent $idw $wmax" tkwait visibility $ent grab $frame BWidget::focus set $ent _update_edit_size $path $ent $idw $wmax update if { $select } { $ent selection range 0 end $ent icursor end $ent xview end } bindtags $ent [list $ent Entry] bind $ent <Escape> {set Tree::_edit(wait) 0} bind $ent <Return> {set Tree::_edit(wait) 1} if { $clickres == 0 || $clickres == 1 } { bind $frame <Button> "set Tree::_edit(wait) $clickres" } set ok 0 while { !$ok } { tkwait variable Tree::_edit(wait) if { !$_edit(wait) || $verifycmd == "" || [uplevel \#0 $verifycmd [list $_edit(text)]] } { set ok 1 } } trace vdelete Tree::_edit(text) w "Tree::_update_edit_size $path $ent $idw $wmax" grab release $frame BWidget::focus release $ent destroy $frame $path.c delete $idw $path.c itemconfigure $idn -fill $oldfg $path.c itemconfigure s:$node -fill $sbg -outline $sbg if { $_edit(wait) } { return $_edit(text) } } return ""}# ----------------------------------------------------------------------------# Command Tree::xview# ----------------------------------------------------------------------------proc Tree::xview { path args } { return [eval $path.c xview $args]}# ----------------------------------------------------------------------------# Command Tree::yview# ----------------------------------------------------------------------------proc Tree::yview { path args } { return [eval $path.c yview $args]}# ----------------------------------------------------------------------------# Command Tree::_update_edit_size# ----------------------------------------------------------------------------proc Tree::_update_edit_size { path entry idw wmax args } { set entw [winfo reqwidth $entry] if { $entw+8 >= $wmax } { $path.c itemconfigure $idw -width $wmax } else { $path.c itemconfigure $idw -width 0 }}# ----------------------------------------------------------------------------# Command Tree::_destroy# ----------------------------------------------------------------------------proc Tree::_destroy { path } { variable $path upvar 0 $path data if { $data(upd,afterid) != "" } { after cancel $data(upd,afterid) } if { $data(dnd,afterid) != "" } { after cancel $data(dnd,afterid) } _subdelete $path [lrange $data(root) 1 end] Widget::destroy $path unset data rename $path {}}# ----------------------------------------------------------------------------# Command Tree::_see# ----------------------------------------------------------------------------proc Tree::_see { path idn side } { set bbox [$path.c bbox $idn] set scrl [$path.c cget -scrollregion] set ymax [lindex $scrl 3] set dy [$path.c cget -yscrollincrement] set yv [$path yview] set yv0 [expr {round([lindex $yv 0]*$ymax/$dy)}] set yv1 [expr {round([lindex $yv 1]*$ymax/$dy)}] set y [expr {int([lindex [$path.c coords $idn] 1]/$dy)}] if { $y < $yv0 } { $path.c yview scroll [expr {$y-$yv0}] units } elseif { $y >= $yv1 } { $path.c yview scroll [expr {$y-$yv1+1}] units } set xmax [lindex $scrl 2] set dx [$path.c cget -xscrollincrement] set xv [$path xview] if { ![string compare $side "right"] } { set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}] set x1 [expr {int([lindex $bbox 2]/$dx)}] if { $x1 >= $xv1 } { $path.c xview scroll [expr {$x1-$xv1+1}] units } } else { set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}] set x0 [expr {int([lindex $bbox 0]/$dx)}] if { $x0 < $xv0 } { $path.c xview scroll [expr {$x0-$xv0}] units } }}# ----------------------------------------------------------------------------# Command Tree::_recexpand# ----------------------------------------------------------------------------# JDC : added option recursiveproc Tree::_recexpand { path node expand recursive cmd } { variable $path upvar 0 $path data if { [Widget::getoption $path.$node -open] != $expand } { Widget::setoption $path.$node -open $expand if { $cmd != "" } { uplevel \#0 $cmd $node } } if { $recursive } { foreach subnode [lrange $data($node) 1 end] { _recexpand $path $subnode $expand $recursive $cmd } }}# ----------------------------------------------------------------------------# Command Tree::_subdelete# ----------------------------------------------------------------------------proc Tree::_subdelete { path lnodes } { variable $path upvar 0 $path data while { [llength $lnodes] } { set lsubnodes [list] foreach node $lnodes { foreach subnode [lrange $data($node) 1 end] { lappend lsubnodes $subnode } unset data($node) if { [set win [Widget::getoption $path.$node -window]] != "" } { destroy $win } Widget::destroy $path.$node } set lnodes $lsubnodes }}# ----------------------------------------------------------------------------# Command Tree::_update_scrollregion# ----------------------------------------------------------------------------proc Tree::_update_scrollregion { path } { set bd [expr {2*([$path.c cget -borderwidth]+[$path.c cget -highlightthickness])}] set w [expr {[winfo width $path] - $bd}] set h [expr {[winfo height $path] - $bd}] set xinc [$path.c cget -xscrollincrement] set yinc [$path.c cget -yscrollincrement] set bbox [$path.c bbox node] if { [llength $bbox] } { set xs [lindex $bbox 2] set ys [lindex $bbox 3] if { $w < $xs } { set w [expr {int($xs)}] if { [set r [expr {$w % $xinc}]] } { set w [expr {$w+$xinc-$r}] } } if { $h < $ys } { set h [expr {int($ys)}] if { [set r [expr {$h % $yinc}]] } { set h [expr {$h+$yinc-$r}] } } } $path.c configure -scrollregion [list 0 0 $w $h] if {[Widget::getoption $path -selectfill]} { _redraw_selection $path }}# ----------------------------------------------------------------------------# Command Tree::_cross_event# ----------------------------------------------------------------------------proc Tree::_cross_event { path } { variable $path upvar 0 $path data set node [Tree::_get_node_name $path current 1] if { [Widget::getoption $path.$node -open] } { Tree::itemconfigure $path $node -open 0 if { [set cmd [Widget::getoption $path -closecmd]] != "" } { uplevel \#0 $cmd $node } } else { Tree::itemconfigure $path $node -open 1 if { [set cmd [Widget::getoption $path -opencmd]] != "" } { uplevel \#0 $cmd $node } }}# ----------------------------------------------------------------------------# Command Tree::_draw_node# ----------------------------------------------------------------------------proc Tree::_draw_node { path node x0 y0 deltax deltay padx showlines } { global env variable $path upvar 0 $path data set x1 [expr {$x0+$deltax+5}] set y1 $y0 if { $showlines } { $path.c create line $x0 $y0 $x1 $y0 \ -fill [Widget::getoption $path -linesfill] \ -stipple [Widget::getoption $path -linestipple] \ -tags line } $path.c create text [expr {$x1+$padx}] $y0 \ -text [Widget::getoption $path.$node -text] \ -fill [Widget::getoption $path.$node -fill] \ -font [Widget::getoption $path.$node -font] \ -anchor w \ -tags "TreeItemSentinal node n:$node" set len [expr {[llength $data($node)] > 1}] set dc [Widget::getoption $path.$node -drawcross] set exp [Widget::getoption $path.$node -open] if { $len && $exp } { set y1 [_draw_subnodes $path [lrange $data($node) 1 end] \ [expr {$x0+$deltax}] $y0 $deltax $deltay $padx $showlines] } if { [string compare $dc "never"] && ($len || ![string compare $dc "allways"]) } { if { $exp } { set bmp [file join $::BWIDGET::LIBRARY "images" "minus.xbm"]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -