📄 tree.tcl
字号:
} else { set bmp [file join $::BWIDGET::LIBRARY "images" "plus.xbm"] } $path.c create bitmap $x0 $y0 \ -bitmap @$bmp \ -background [$path.c cget -background] \ -foreground [Widget::getoption $path -linesfill] \ -tags "cross c:$node" -anchor c } if { [set win [Widget::getoption $path.$node -window]] != "" } { $path.c create window $x1 $y0 -window $win -anchor w \ -tags "TreeItemSentinal win i:$node" } elseif { [set img [Widget::getoption $path.$node -image]] != "" } { $path.c create image $x1 $y0 -image $img -anchor w \ -tags "TreeItemSentinal img i:$node" } return $y1}# ----------------------------------------------------------------------------# Command Tree::_draw_subnodes# ----------------------------------------------------------------------------proc Tree::_draw_subnodes { path nodes x0 y0 deltax deltay padx showlines } { set y1 $y0 foreach node $nodes { set yp $y1 set y1 [_draw_node $path $node $x0 [expr {$y1+$deltay}] $deltax $deltay $padx $showlines] } if { $showlines && [llength $nodes] } { set id [$path.c create line $x0 $y0 $x0 [expr {$yp+$deltay}] \ -fill [Widget::getoption $path -linesfill] \ -stipple [Widget::getoption $path -linestipple] \ -tags line] $path.c lower $id } return $y1}# ----------------------------------------------------------------------------# Command Tree::_update_nodes# ----------------------------------------------------------------------------proc Tree::_update_nodes { path } { global env variable $path upvar 0 $path data set deltax [Widget::getoption $path -deltax] set padx [Widget::getoption $path -padx] foreach {node flag} $data(upd,nodes) { set idn [$path.c find withtag "n:$node"] if { $idn == "" } { continue } set c [$path.c coords $idn] set x0 [expr {[lindex $c 0]-$padx}] set y0 [lindex $c 1] if { $flag & 48 } { # -window or -image modified set win [Widget::getoption $path.$node -window] set img [Widget::getoption $path.$node -image] set idi [$path.c find withtag i:$node] set type [lindex [$path.c gettags $idi] 1] if { [string length $win] } { if { ![string compare $type "win"] } { $path.c itemconfigure $idi -window $win } else { $path.c delete $idi $path.c create window $x0 $y0 -window $win -anchor w \ -tags "TreeItemSentinal win i:$node" } } elseif { [string length $img] } { if { ![string compare $type "img"] } { $path.c itemconfigure $idi -image $img } else { $path.c delete $idi $path.c create image $x0 $y0 -image $img -anchor w \ -tags "TreeItemSentinal img i:$node" } } else { $path.c delete $idi } } if { $flag & 8 } { # -drawcross modified set len [expr {[llength $data($node)] > 1}] set dc [Widget::getoption $path.$node -drawcross] set exp [Widget::getoption $path.$node -open] set idc [$path.c find withtag c:$node] if { [string compare $dc "never"] && ($len || ![string compare $dc "allways"]) } { if { $exp } { set bmp [file join $::BWIDGET::LIBRARY "images" "minus.xbm"] } else { set bmp [file join $::BWIDGET::LIBRARY "images" "plus.xbm"] } if { $idc == "" } { $path.c create bitmap [expr {$x0-$deltax-5}] $y0 \ -bitmap @$bmp \ -background [$path.c cget -background] \ -foreground [Widget::getoption $path -linesfill] \ -tags "cross c:$node" -anchor c } else { $path.c itemconfigure $idc -bitmap @$bmp } } else { $path.c delete $idc } } if { $flag & 7 } { # -font, -text or -fill modified $path.c itemconfigure $idn \ -text [Widget::getoption $path.$node -text] \ -fill [Widget::getoption $path.$node -fill] \ -font [Widget::getoption $path.$node -font] } }}# ----------------------------------------------------------------------------# Command Tree::_draw_tree# ----------------------------------------------------------------------------proc Tree::_draw_tree { path } { variable $path upvar 0 $path data $path.c delete all set cursor [$path.c cget -cursor] $path.c configure -cursor watch _draw_subnodes $path [lrange $data(root) 1 end] 8 \ [expr {-[Widget::getoption $path -deltay]/2}] \ [Widget::getoption $path -deltax] \ [Widget::getoption $path -deltay] \ [Widget::getoption $path -padx] \ [Widget::getoption $path -showlines] $path.c configure -cursor $cursor}# ----------------------------------------------------------------------------# Command Tree::_redraw_tree# ----------------------------------------------------------------------------proc Tree::_redraw_tree { path } { variable $path upvar 0 $path data if { [Widget::getoption $path -redraw] } { if { $data(upd,level) == 2 } { _update_nodes $path } elseif { $data(upd,level) == 3 } { _draw_tree $path } _redraw_selection $path _update_scrollregion $path set data(upd,nodes) {} set data(upd,level) 0 set data(upd,afterid) "" }}# ----------------------------------------------------------------------------# Command Tree::_redraw_selection# ----------------------------------------------------------------------------proc Tree::_redraw_selection { path } { variable $path upvar 0 $path data set selbg [Widget::getoption $path -selectbackground] set selfg [Widget::getoption $path -selectforeground] set fill [Widget::getoption $path -selectfill] if {$fill} { set scroll [$path.c cget -scrollregion] if {[llength $scroll]} { set xmax [expr {[lindex $scroll 2]-1}] } else { set xmax [winfo width $path] } } foreach id [$path.c find withtag sel] { set node [Tree::_get_node_name $path $id 1] $path.c itemconfigure "n:$node" -fill [Widget::getoption $path.$node -fill] } $path.c delete sel foreach node $data(selnodes) { set bbox [$path.c bbox "n:$node"] if { [llength $bbox] } { if {$fill} { set bbox [list 0 [lindex $bbox 1] $xmax [lindex $bbox 3]] } set id [eval $path.c create rectangle $bbox \ -fill $selbg -outline $selbg -tags [list "sel s:$node"]] $path.c itemconfigure "n:$node" -fill $selfg $path.c lower $id } }}# ----------------------------------------------------------------------------# Command Tree::_redraw_idle# ----------------------------------------------------------------------------proc Tree::_redraw_idle { path level } { variable $path upvar 0 $path data if { [Widget::getoption $path -redraw] && $data(upd,afterid) == "" } { set data(upd,afterid) [after idle Tree::_redraw_tree $path] } if { $level > $data(upd,level) } { set data(upd,level) $level } return ""}# ----------------------------------------------------------------------------# Command Tree::_init_drag_cmd# ----------------------------------------------------------------------------proc Tree::_init_drag_cmd { path X Y top } { set path [winfo parent $path] set ltags [$path.c gettags current] set item [lindex $ltags 1] if { ![string compare $item "node"] || ![string compare $item "img"] || ![string compare $item "win"] } { set node [Tree::_get_node_name $path current 2] if { [set cmd [Widget::getoption $path -draginitcmd]] != "" } { return [uplevel \#0 $cmd [list $path $node $top]] } if { [set type [Widget::getoption $path -dragtype]] == "" } { set type "TREE_NODE" } if { [set img [Widget::getoption $path.$node -image]] != "" } { pack [label $top.l -image $img -padx 0 -pady 0] } return [list $type {copy move link} $node] } return {}}# ----------------------------------------------------------------------------# Command Tree::_drop_cmd# ----------------------------------------------------------------------------proc Tree::_drop_cmd { path source X Y op type dnddata } { set path [winfo parent $path] variable $path upvar 0 $path data $path.c delete drop if { [string length $data(dnd,afterid)] } { after cancel $data(dnd,afterid) set data(dnd,afterid) "" } set data(dnd,scroll) "" if { [llength $data(dnd,node)] } { if { [set cmd [Widget::getoption $path -dropcmd]] != "" } { return [uplevel \#0 $cmd [list $path $source $data(dnd,node) $op $type $dnddata]] } } return 0}# ----------------------------------------------------------------------------# Command Tree::_over_cmd# ----------------------------------------------------------------------------proc Tree::_over_cmd { path source event X Y op type dnddata } { set path [winfo parent $path] variable $path upvar 0 $path data if { ![string compare $event "leave"] } { # we leave the window tree $path.c delete drop if { [string length $data(dnd,afterid)] } { after cancel $data(dnd,afterid) set data(dnd,afterid) "" } set data(dnd,scroll) "" return 0 } if { ![string compare $event "enter"] } { # we enter the window tree - dnd data initialization set mode [Widget::getoption $path -dropovermode] set data(dnd,mode) 0 foreach c {w p n} { set data(dnd,mode) [expr {($data(dnd,mode) << 1) | ([string first $c $mode] != -1)}] } set bbox [$path.c bbox all] if { [llength $bbox] } { set data(dnd,xs) [lindex $bbox 2] set data(dnd,empty) 0 } else { set data(dnd,xs) 0 set data(dnd,empty) 1 } set data(dnd,node) {} } set x [expr {$X-[winfo rootx $path]}] set y [expr {$Y-[winfo rooty $path]}] $path.c delete drop set data(dnd,node) {} # test for auto-scroll unless mode is widget only if { $data(dnd,mode) != 4 && [_auto_scroll $path $x $y] != "" } { return 2 } if { $data(dnd,mode) & 4 } { # dropovermode includes widget set target [list widget] set vmode 4 } else { set target [list ""] set vmode 0 } if { ($data(dnd,mode) & 2) && $data(dnd,empty) } { # dropovermode includes position and tree is empty lappend target [list root 0] set vmode [expr {$vmode | 2}] } set xc [$path.c canvasx $x] set xs $data(dnd,xs) if { $xc <= $xs } { set yc [$path.c canvasy $y] set dy [$path.c cget -yscrollincrement] set line [expr {int($yc/$dy)}] set xi 0 set yi [expr {$line*$dy}] set ys [expr {$yi+$dy}] set found 0 foreach id [$path.c find overlapping $xi $yi $xs $ys] { set ltags [$path.c gettags $id] set item [lindex $ltags 1] if { ![string compare $item "node"] || ![string compare $item "img"] || ![string compare $item "win"] } { # item is the label or image/window of the node set node [Tree::_get_node_name $path $id 2] set found 1 break } } if {$found} { set xi [expr {[lindex [$path.c coords n:$node] 0]-[Widget::getoption $path -padx]-1}] if { $data(dnd,mode) & 1 } { # dropovermode includes node lappend target $node set vmode [expr {$vmode | 1}] } else { lappend target "" } if { $data(dnd,mode) & 2 } { # dropovermode includes position if { $yc >= $yi+$dy/2 } { # position is after $node if { [Widget::getoption $path.$node -open] && [llength $data($node)] > 1 } { # $node is open and have subnodes # drop position is 0 in children of $node set parent $node set index 0 set xli [expr {$xi-5}] } else { # $node is not open and doesn't have subnodes # drop position is after $node in children of parent of $node set parent [lindex $data($node) 0]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -