📄 listbox.tcl
字号:
$path.c itemconfigure $idw -width 0
}
}
# ----------------------------------------------------------------------------
# Command ListBox::_getoption
# Returns the value of option for node. If empty, returned value is those
# of the ListBox.
# ----------------------------------------------------------------------------
proc ListBox::_getoption { path item option } {
set value [Widget::getoption $path.$item $option]
if {![string length $value]} {
set value [Widget::getoption $path $option]
}
return $value
}
# ----------------------------------------------------------------------------
# Command ListBox::_destroy
# ----------------------------------------------------------------------------
proc ListBox::_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)
}
foreach item $data(items) {
Widget::destroy $path.$item
}
Widget::destroy $path
unset data
}
# ----------------------------------------------------------------------------
# Command ListBox::_see
# ----------------------------------------------------------------------------
proc ListBox::_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.c 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.c xview]
if { [string equal $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 ListBox::_update_scrollregion
# ----------------------------------------------------------------------------
proc ListBox::_update_scrollregion { path } {
set bd [$path.c cget -borderwidth]
set ht [$path.c cget -highlightthickness]
set bd [expr {2*($bd + $ht)}]
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 item win img]
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]
}
proc ListBox::_update_select_fill { path } {
variable $path
upvar 0 $path data
set width [winfo width $path]
foreach item $data(items) {
set bbox [$path.c bbox n:$item]
set bbox [list 0 [lindex $bbox 1] $width [lindex $bbox 3]]
$path.c coords b:$item $bbox
}
_redraw_selection $path
}
# ----------------------------------------------------------------------------
# Command ListBox::_draw_item
# ----------------------------------------------------------------------------
proc ListBox::_draw_item { path item x0 x1 y } {
set indent [Widget::getoption $path.$item -indent]
set selfill [Widget::cget $path -selectfill]
set multi [Widget::cget $path -multicolumn]
set i [$path.c create text [expr {$x1+$indent}] $y \
-text [Widget::getoption $path.$item -text] \
-fill [_getoption $path $item -foreground] \
-font [_getoption $path $item -font] \
-anchor w \
-tags [list item n:$item click]]
if { $selfill && !$multi } {
set bg [Widget::cget $path -background]
set width [winfo width $path.c]
set bbox [$path.c bbox n:$item]
set bbox [list 0 [lindex $bbox 1] $width [lindex $bbox 3]]
set tags [list box b:$item click]
$path.c create rect $bbox -fill $bg -width 0 -tags $tags
$path.c raise $i
}
if { [set win [Widget::getoption $path.$item -window]] != "" } {
$path.c create window [expr {$x0+$indent}] $y \
-window $win -anchor w -tags [list win i:$item]
} elseif { [set img [Widget::getoption $path.$item -image]] != "" } {
$path.c create image [expr {$x0+$indent}] $y \
-image $img -anchor w -tags [list img i:$item]
}
_set_help $path $item
}
# ----------------------------------------------------------------------------
# Command ListBox::_redraw_items
# ----------------------------------------------------------------------------
proc ListBox::_redraw_items { path } {
variable $path
upvar 0 $path data
set cursor [$path.c cget -cursor]
$path.c configure -cursor watch
set dx [Widget::getoption $path -deltax]
set dy [Widget::getoption $path -deltay]
set padx [Widget::getoption $path -padx]
set y0 [expr {$dy/2}]
set x0 4
set x1 [expr {$x0+$padx}]
set nitem 0
set drawn {}
set data(xlist) {}
if { [Widget::cget $path -multicolumn] } {
set nrows $data(nrows)
} else {
set nrows [llength $data(items)]
}
foreach item $data(upd,delete) {
$path.c delete i:$item n:$item s:$item b:$item
}
foreach item $data(items) {
if { [info exists data(upd,create,$item)] } {
_draw_item $path $item $x0 $x1 $y0
unset data(upd,create,$item)
} else {
set indent [Widget::getoption $path.$item -indent]
$path.c coords n:$item [expr {$x1+$indent}] $y0
$path.c coords i:$item [expr {$x0+$indent}] $y0
}
incr y0 $dy
incr nitem
lappend drawn n:$item
if { $nitem == $nrows } {
set y0 [expr {$dy/2}]
set bbox [eval [list $path.c bbox] $drawn]
set drawn {}
set x0 [expr {[lindex $bbox 2]+$dx}]
set x1 [expr {$x0+$padx}]
set nitem 0
lappend data(xlist) [lindex $bbox 2]
}
}
if { $nitem && $nitem < $nrows } {
set bbox [eval [list $path.c bbox] $drawn]
lappend data(xlist) [lindex $bbox 2]
}
set data(upd,delete) {}
$path.c configure -cursor $cursor
}
# ----------------------------------------------------------------------------
# Command ListBox::_redraw_selection
# ----------------------------------------------------------------------------
proc ListBox::_redraw_selection { path } {
variable $path
upvar 0 $path data
set selbg [Widget::getoption $path -selectbackground]
set selfg [Widget::getoption $path -selectforeground]
set selfill [Widget::getoption $path -selectfill]
set multi [Widget::getoption $path -multicolumn]
foreach id [$path.c find withtag sel] {
set item [string range [lindex [$path.c gettags $id] 1] 2 end]
$path.c itemconfigure "n:$item" \
-fill [_getoption $path $item -foreground]
}
$path.c delete sel
foreach item $data(selitems) {
set bbox [$path.c bbox "n:$item"]
if { $selfill && !$multi } {
set bbox2 [$path.c bbox "b:$item"]
set w1 [lindex $bbox 2]
set w2 [lindex $bbox2 2]
if {$w1 < $w2} { set bbox $bbox2 }
}
if { [llength $bbox] } {
set tags [list sel s:$item click]
set id [$path.c create rectangle $bbox \
-fill $selbg -outline $selbg -tags $tags]
$path.c itemconfigure "n:$item" -fill $selfg
$path.c lower $id
$path.c lower b:$item
}
}
}
# ----------------------------------------------------------------------------
# Command ListBox::_redraw_listbox
# ----------------------------------------------------------------------------
proc ListBox::_redraw_listbox { path } {
variable $path
upvar 0 $path data
if { [Widget::getoption $path -redraw] } {
if { $data(upd,level) == 2 } {
_redraw_items $path
}
_redraw_selection $path
_update_scrollregion $path
set data(upd,level) 0
set data(upd,afterid) ""
}
}
# ----------------------------------------------------------------------------
# Command ListBox::_redraw_idle
# ----------------------------------------------------------------------------
proc ListBox::_redraw_idle { path level } {
variable $path
upvar 0 $path data
if { $data(nrows) != -1 } {
# widget is realized
if { [Widget::getoption $path -redraw] && $data(upd,afterid) == "" } {
set data(upd,afterid) [after idle ListBox::_redraw_listbox $path]
}
}
if { $level > $data(upd,level) } {
set data(upd,level) $level
}
return ""
}
# ----------------------------------------------------------------------------
# Command ListBox::_resize
# ----------------------------------------------------------------------------
proc ListBox::_resize { path } {
variable $path
upvar 0 $path data
if { [Widget::getoption $path -multicolumn] } {
set bd [expr {[$path.c cget -borderwidth]+[$path.c cget -highlightthickness]}]
set h [expr {[winfo height $path] - 2*$bd}]
set nrows [expr {$h/[$path.c cget -yscrollincrement]}]
if { $nrows == 0 } {
set nrows 1
}
if { $nrows != $data(nrows) } {
set data(nrows) $nrows
_redraw_idle $path 2
} else {
_update_scrollregion $path
}
} elseif { $data(nrows) == -1 } {
# first Configure event
set data(nrows) 0
ListBox::_redraw_listbox $path
if {[Widget::cget $path -selectfill]} {
_update_select_fill $path
}
} else {
if {[Widget::cget $path -selectfill]} {
_update_select_fill $path
}
_update_scrollregion $path
}
}
# ----------------------------------------------------------------------------
# Command ListBox::_init_drag_cmd
# ----------------------------------------------------------------------------
proc ListBox::_init_drag_cmd { path X Y top } {
set path [winfo parent $path]
set ltags [$path.c gettags current]
set item [lindex $ltags 0]
if { [string equal $item "item"] ||
[string equal $item "img"] ||
[string equal $item "win"] } {
set item [string range [lindex $ltags 1] 2 end]
if { [set cmd [Widget::getoption $path -draginitcmd]] != "" } {
return [uplevel \#0 $cmd [list $path $item $top]]
}
if { [set type [Widget::getoption $path -dragtype]] == "" } {
set type "LISTBOX_ITEM"
}
if { [set img [Widget::getoption $path.$item -image]] != "" } {
pack [label $top.l -image $img -padx 0 -pady 0]
}
return [list $type {copy move link} $item]
}
return {}
}
# ----------------------------------------------------------------------------
# Command ListBox::_drop_cmd
# ----------------------------------------------------------------------------
proc ListBox::_drop_cmd { path source X Y op type dnddata } {
set path [winfo parent $path]
variable $path
upvar 0 $path data
if { [string length $data(dnd,afterid)] } {
after cancel $data(dnd,afterid)
set data(dnd,afterid) ""
}
$path.c delete drop
set data(dnd,scroll) ""
if { [llength $data(dnd,item)] || ![llength $data(items)] } {
if { [set cmd [Widget::getoption $path -dropcmd]] != "" } {
return [uplevel \#0 $cmd [list $path $source $data(dnd,item) $op $type $dnddata]]
}
}
return 0
}
# ----------------------------------------------------------------------------
# Command ListBox::_over_cmd
# ----------------------------------------------------------------------------
proc ListBox::_over_cmd { path source event X Y op type dnddata } {
set path [winfo parent $path]
variable $path
upvar 0 $path data
if { [string equal $event "leave"] } {
# we leave the window listbox
$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 equal $event "enter"] } {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -