| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | package require Tk |
| |
|
| | ::tk::Megawidget create ::tk::IconList ::tk::FocusableWidget { |
| | variable w canvas sbar accel accelCB fill font index \ |
| | itemList itemsPerColumn list maxIH maxIW maxTH maxTW noScroll \ |
| | numItems oldX oldY options rect selected selection textList |
| | constructor args { |
| | next {*}$args |
| | set accelCB {} |
| | } |
| | destructor { |
| | my Reset |
| | next |
| | } |
| |
|
| | method GetSpecs {} { |
| | concat [next] { |
| | {-command "" "" ""} |
| | {-font "" "" "TkIconFont"} |
| | {-multiple "" "" "0"} |
| | } |
| | } |
| |
|
| | |
| |
|
| | method index i { |
| | if {![info exist list]} { |
| | set list {} |
| | } |
| | switch -regexp -- $i { |
| | "^-?[0-9]+$" { |
| | if {$i < 0} { |
| | set i 0 |
| | } |
| | if {$i >= [llength $list]} { |
| | set i [expr {[llength $list] - 1}] |
| | } |
| | return $i |
| | } |
| | "^anchor$" { |
| | return $index(anchor) |
| | } |
| | "^end$" { |
| | return [llength $list] |
| | } |
| | "@-?[0-9]+,-?[0-9]+" { |
| | scan $i "@%d,%d" x y |
| | set item [$canvas find closest \ |
| | [$canvas canvasx $x] [$canvas canvasy $y]] |
| | return [lindex [$canvas itemcget $item -tags] 1] |
| | } |
| | } |
| | } |
| |
|
| | method selection {op args} { |
| | switch -exact -- $op { |
| | anchor { |
| | if {[llength $args] == 1} { |
| | set index(anchor) [$w index [lindex $args 0]] |
| | } else { |
| | return $index(anchor) |
| | } |
| | } |
| | clear { |
| | switch [llength $args] { |
| | 2 { |
| | lassign $args first last |
| | } |
| | 1 { |
| | set first [set last [lindex $args 0]] |
| | } |
| | default { |
| | return -code error -errorcode {TCL WRONGARGS} \ |
| | "wrong # args: should be\ |
| | \"[lrange [info level 0] 0 1] first ?last?\"" |
| | } |
| | } |
| |
|
| | set first [$w index $first] |
| | set last [$w index $last] |
| | if {$first > $last} { |
| | set tmp $first |
| | set first $last |
| | set last $tmp |
| | } |
| | set ind 0 |
| | foreach item $selection { |
| | if {$item >= $first} { |
| | set first $ind |
| | break |
| | } |
| | incr ind |
| | } |
| | set ind [expr {[llength $selection] - 1}] |
| | for {} {$ind >= 0} {incr ind -1} { |
| | set item [lindex $selection $ind] |
| | if {$item <= $last} { |
| | set last $ind |
| | break |
| | } |
| | } |
| |
|
| | if {$first > $last} { |
| | return |
| | } |
| | set selection [lreplace $selection $first $last] |
| | event generate $w <<ListboxSelect>> |
| | my DrawSelection |
| | } |
| | get { |
| | return $selection |
| | } |
| | includes { |
| | return [expr {[lindex $args 0] in $selection}] |
| | } |
| | set { |
| | switch [llength $args] { |
| | 2 { |
| | lassign $args first last |
| | } |
| | 1 { |
| | set first [set last [lindex $args 0]] |
| | } |
| | default { |
| | return -code error -errorcode {TCL WRONGARGS} \ |
| | "wrong # args: should be\ |
| | \"[lrange [info level 0] 0 1] first ?last?\"" |
| | } |
| | } |
| |
|
| | set first [$w index $first] |
| | set last [$w index $last] |
| | if {$first > $last} { |
| | set tmp $first |
| | set first $last |
| | set last $tmp |
| | } |
| |
|
| | for {set i $first} {$i <= $last} {incr i} { |
| | lappend selection $i |
| | } |
| | set selection [lsort -integer -unique $selection] |
| | event generate $w <<ListboxSelect>> |
| | my DrawSelection |
| | } |
| | } |
| | } |
| |
|
| | method get item { |
| | set rTag [lindex $list $item 2] |
| | lassign $itemList($rTag) iTag tTag text serial |
| | return $text |
| | } |
| |
|
| | |
| | |
| | |
| | method deleteall {} { |
| | $canvas delete all |
| | unset -nocomplain selected rect list itemList |
| | set maxIW 1 |
| | set maxIH 1 |
| | set maxTW 1 |
| | set maxTH 1 |
| | set numItems 0 |
| | set noScroll 1 |
| | set selection {} |
| | set index(anchor) "" |
| | $sbar set 0.0 1.0 |
| | $canvas xview moveto 0 |
| | } |
| |
|
| | |
| | |
| | method add {image items} { |
| | foreach text $items { |
| | set iID item$numItems |
| | set iTag [$canvas create image 0 0 -image $image -anchor nw \ |
| | -tags [list icon $numItems $iID]] |
| | set tTag [$canvas create text 0 0 -text $text -anchor nw \ |
| | -font $options(-font) -fill $fill \ |
| | -tags [list text $numItems $iID]] |
| | set rTag [$canvas create rect 0 0 0 0 -fill "" -outline "" \ |
| | -tags [list rect $numItems $iID]] |
| |
|
| | lassign [$canvas bbox $iTag] x1 y1 x2 y2 |
| | set iW [expr {$x2 - $x1}] |
| | set iH [expr {$y2 - $y1}] |
| | if {$maxIW < $iW} { |
| | set maxIW $iW |
| | } |
| | if {$maxIH < $iH} { |
| | set maxIH $iH |
| | } |
| |
|
| | lassign [$canvas bbox $tTag] x1 y1 x2 y2 |
| | set tW [expr {$x2 - $x1}] |
| | set tH [expr {$y2 - $y1}] |
| | if {$maxTW < $tW} { |
| | set maxTW $tW |
| | } |
| | if {$maxTH < $tH} { |
| | set maxTH $tH |
| | } |
| |
|
| | lappend list [list $iTag $tTag $rTag $iW $iH $tW $tH $numItems] |
| | set itemList($rTag) [list $iTag $tTag $text $numItems] |
| | set textList($numItems) [string tolower $text] |
| | incr numItems |
| | } |
| | my WhenIdle Arrange |
| | return |
| | } |
| |
|
| | |
| | |
| | |
| | method invoke {} { |
| | if {$options(-command) ne "" && [llength $selection]} { |
| | uplevel #0 $options(-command) |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | method see rTag { |
| | if {$noScroll} { |
| | return |
| | } |
| | set sRegion [$canvas cget -scrollregion] |
| | if {$sRegion eq ""} { |
| | return |
| | } |
| |
|
| | if {$rTag < 0 || $rTag >= [llength $list]} { |
| | return |
| | } |
| |
|
| | set bbox [$canvas bbox item$rTag] |
| | set pad [expr {[$canvas cget -highlightthickness]+[$canvas cget -bd]}] |
| |
|
| | set x1 [lindex $bbox 0] |
| | set x2 [lindex $bbox 2] |
| | incr x1 [expr {$pad * -2}] |
| | incr x2 [expr {$pad * -1}] |
| |
|
| | set cW [expr {[winfo width $canvas] - $pad*2}] |
| |
|
| | set scrollW [expr {[lindex $sRegion 2]-[lindex $sRegion 0]+1}] |
| | set dispX [expr {int([lindex [$canvas xview] 0]*$scrollW)}] |
| | set oldDispX $dispX |
| |
|
| | |
| | |
| | if {($x2 - $dispX) >= $cW} { |
| | set dispX [expr {$x2 - $cW}] |
| | } |
| | |
| | |
| | if {($x1 - $dispX) < 0} { |
| | set dispX $x1 |
| | } |
| |
|
| | if {$oldDispX ne $dispX} { |
| | set fraction [expr {double($dispX) / double($scrollW)}] |
| | $canvas xview moveto $fraction |
| | } |
| | } |
| |
|
| | |
| |
|
| | |
| | |
| | method Arrange {} { |
| | if {![info exists list]} { |
| | if {[info exists canvas] && [winfo exists $canvas]} { |
| | set noScroll 1 |
| | $sbar configure -command "" |
| | } |
| | return |
| | } |
| |
|
| | set W [winfo width $canvas] |
| | set H [winfo height $canvas] |
| | set pad [expr {[$canvas cget -highlightthickness]+[$canvas cget -bd]}] |
| | if {$pad < 2} { |
| | set pad 2 |
| | } |
| |
|
| | incr W [expr {$pad*-2}] |
| | incr H [expr {$pad*-2}] |
| |
|
| | set dx [expr {$maxIW + $maxTW + 8}] |
| | if {$maxTH > $maxIH} { |
| | set dy $maxTH |
| | } else { |
| | set dy $maxIH |
| | } |
| | incr dy 2 |
| | set shift [expr {$maxIW + 4}] |
| |
|
| | set x [expr {$pad * 2}] |
| | set y [expr {$pad * 1}] |
| | set usedColumn 0 |
| | foreach sublist $list { |
| | set usedColumn 1 |
| | lassign $sublist iTag tTag rTag iW iH tW tH |
| |
|
| | set i_dy [expr {($dy - $iH)/2}] |
| | set t_dy [expr {($dy - $tH)/2}] |
| |
|
| | $canvas coords $iTag $x [expr {$y + $i_dy}] |
| | $canvas coords $tTag [expr {$x + $shift}] [expr {$y + $t_dy}] |
| | $canvas coords $rTag $x $y [expr {$x+$dx}] [expr {$y+$dy}] |
| |
|
| | incr y $dy |
| | if {($y + $dy) > $H} { |
| | set y [expr {$pad * 1}] |
| | incr x $dx |
| | set usedColumn 0 |
| | } |
| | } |
| |
|
| | if {$usedColumn} { |
| | set sW [expr {$x + $dx}] |
| | } else { |
| | set sW $x |
| | } |
| |
|
| | if {$sW < $W} { |
| | $canvas configure -scrollregion [list $pad $pad $sW $H] |
| | $sbar configure -command "" |
| | $canvas xview moveto 0 |
| | set noScroll 1 |
| | } else { |
| | $canvas configure -scrollregion [list $pad $pad $sW $H] |
| | $sbar configure -command [list $canvas xview] |
| | set noScroll 0 |
| | } |
| |
|
| | set itemsPerColumn [expr {($H-$pad) / $dy}] |
| | if {$itemsPerColumn < 1} { |
| | set itemsPerColumn 1 |
| | } |
| |
|
| | my DrawSelection |
| | } |
| |
|
| | method DrawSelection {} { |
| | $canvas delete selection |
| | $canvas itemconfigure selectionText -fill $fill |
| | $canvas dtag selectionText |
| | set cbg [ttk::style lookup TEntry -selectbackground focus] |
| | set cfg [ttk::style lookup TEntry -selectforeground focus] |
| | foreach item $selection { |
| | set rTag [lindex $list $item 2] |
| | foreach {iTag tTag text serial} $itemList($rTag) { |
| | break |
| | } |
| |
|
| | set bbox [$canvas bbox $tTag] |
| | $canvas create rect $bbox -fill $cbg -outline $cbg \ |
| | -tags selection |
| | $canvas itemconfigure $tTag -fill $cfg -tags selectionText |
| | } |
| | $canvas lower selection |
| | return |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | method Create {} { |
| | variable hull |
| | set sbar [ttk::scrollbar $hull.sbar -orient horizontal -takefocus 0] |
| | catch {$sbar configure -highlightthickness 0} |
| | set canvas [canvas $hull.canvas -highlightthick 0 -takefocus 1 \ |
| | -width 400 -height 120 -background white] |
| | pack $sbar -side bottom -fill x -padx 2 -pady {0 2} |
| | pack $canvas -expand yes -fill both -padx 2 -pady {2 0} |
| |
|
| | $sbar configure -command [list $canvas xview] |
| | $canvas configure -xscrollcommand [list $sbar set] |
| |
|
| | |
| | |
| | set maxIW 1 |
| | set maxIH 1 |
| | set maxTW 1 |
| | set maxTH 1 |
| | set numItems 0 |
| | set noScroll 1 |
| | set selection {} |
| | set index(anchor) "" |
| | set fill black |
| |
|
| | |
| | |
| | bind $canvas <Configure> [namespace code {my WhenIdle Arrange}] |
| |
|
| | bind $canvas <Button-1> [namespace code {my Btn1 %x %y}] |
| | bind $canvas <B1-Motion> [namespace code {my Motion1 %x %y}] |
| | bind $canvas <B1-Leave> [namespace code {my Leave1 %x %y}] |
| | bind $canvas <Control-Button-1> [namespace code {my CtrlBtn1 %x %y}] |
| | bind $canvas <Shift-Button-1> [namespace code {my ShiftBtn1 %x %y}] |
| | bind $canvas <B1-Enter> [list tk::CancelRepeat] |
| | bind $canvas <ButtonRelease-1> [list tk::CancelRepeat] |
| | bind $canvas <Double-ButtonRelease-1> \ |
| | [namespace code {my Double1 %x %y}] |
| |
|
| | bind $canvas <Control-B1-Motion> {;} |
| | bind $canvas <Shift-B1-Motion> [namespace code {my ShiftMotion1 %x %y}] |
| |
|
| | if {[tk windowingsystem] eq "aqua"} { |
| | bind $canvas <Shift-MouseWheel> [namespace code {my MouseWheel [expr {40 * (%D)}]}] |
| | bind $canvas <Option-Shift-MouseWheel> [namespace code {my MouseWheel [expr {400 * (%D)}]}] |
| | bind $canvas <Command-Key> {# nothing} |
| | bind $canvas <Mod4-Key> {# nothing} |
| | } else { |
| | bind $canvas <Shift-MouseWheel> [namespace code {my MouseWheel %D}] |
| | } |
| | if {[tk windowingsystem] eq "x11"} { |
| | bind $canvas <Shift-Button-4> [namespace code {my MouseWheel 120}] |
| | bind $canvas <Shift-Button-5> [namespace code {my MouseWheel -120}] |
| | } |
| |
|
| | bind $canvas <<PrevLine>> [namespace code {my UpDown -1}] |
| | bind $canvas <<NextLine>> [namespace code {my UpDown 1}] |
| | bind $canvas <<PrevChar>> [namespace code {my LeftRight -1}] |
| | bind $canvas <<NextChar>> [namespace code {my LeftRight 1}] |
| | bind $canvas <Return> [namespace code {my ReturnKey}] |
| | bind $canvas <Key> [namespace code {my KeyPress %A}] |
| | bind $canvas <Alt-Key> {# nothing} |
| | bind $canvas <Meta-Key> {# nothing} |
| | bind $canvas <Control-Key> {# nothing} |
| |
|
| | bind $canvas <FocusIn> [namespace code {my FocusIn}] |
| | bind $canvas <FocusOut> [namespace code {my FocusOut}] |
| |
|
| | return $w |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | method AutoScan {} { |
| | if {![winfo exists $w]} return |
| | set x $oldX |
| | set y $oldY |
| | if {$noScroll} { |
| | return |
| | } |
| | if {$x >= [winfo width $canvas]} { |
| | $canvas xview scroll 1 units |
| | } elseif {$x < 0} { |
| | $canvas xview scroll -1 units |
| | } elseif {$y >= [winfo height $canvas]} { |
| | |
| | } elseif {$y < 0} { |
| | |
| | } else { |
| | return |
| | } |
| | my Motion1 $x $y |
| | set ::tk::Priv(afterId) [after 50 [namespace code {my AutoScan}]] |
| | } |
| |
|
| | |
| |
|
| | |
| | method MouseWheel {amount} { |
| | if {$noScroll || $::tk_strictMotif} { |
| | return |
| | } |
| | if {$amount > 0} { |
| | $canvas xview scroll [expr {(-119-$amount) / 120}] units |
| | } else { |
| | $canvas xview scroll [expr {-($amount / 120)}] units |
| | } |
| | } |
| | method Btn1 {x y} { |
| | focus $canvas |
| | set i [$w index @$x,$y] |
| | if {$i eq ""} { |
| | return |
| | } |
| | $w selection clear 0 end |
| | $w selection set $i |
| | $w selection anchor $i |
| | } |
| | method CtrlBtn1 {x y} { |
| | if {$options(-multiple)} { |
| | focus $canvas |
| | set i [$w index @$x,$y] |
| | if {$i eq ""} { |
| | return |
| | } |
| | if {[$w selection includes $i]} { |
| | $w selection clear $i |
| | } else { |
| | $w selection set $i |
| | $w selection anchor $i |
| | } |
| | } |
| | } |
| | method ShiftBtn1 {x y} { |
| | if {$options(-multiple)} { |
| | focus $canvas |
| | set i [$w index @$x,$y] |
| | if {$i eq ""} { |
| | return |
| | } |
| | if {[$w index anchor] eq ""} { |
| | $w selection anchor $i |
| | } |
| | $w selection clear 0 end |
| | $w selection set anchor $i |
| | } |
| | } |
| |
|
| | |
| | |
| | method Motion1 {x y} { |
| | set oldX $x |
| | set oldY $y |
| | set i [$w index @$x,$y] |
| | if {$i eq ""} { |
| | return |
| | } |
| | $w selection clear 0 end |
| | $w selection set $i |
| | } |
| | method ShiftMotion1 {x y} { |
| | set oldX $x |
| | set oldY $y |
| | set i [$w index @$x,$y] |
| | if {$i eq ""} { |
| | return |
| | } |
| | $w selection clear 0 end |
| | $w selection set anchor $i |
| | } |
| | method Double1 {x y} { |
| | if {[llength $selection]} { |
| | $w invoke |
| | } |
| | } |
| | method ReturnKey {} { |
| | $w invoke |
| | } |
| | method Leave1 {x y} { |
| | set oldX $x |
| | set oldY $y |
| | my AutoScan |
| | } |
| | method FocusIn {} { |
| | $w state focus |
| | if {![info exists list]} { |
| | return |
| | } |
| | if {[llength $selection]} { |
| | my DrawSelection |
| | } |
| | } |
| | method FocusOut {} { |
| | $w state !focus |
| | $w selection clear 0 end |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | method UpDown amount { |
| | if {![info exists list]} { |
| | return |
| | } |
| | set curr [$w selection get] |
| | if {[llength $curr] == 0} { |
| | set i 0 |
| | } else { |
| | set i [$w index anchor] |
| | if {$i eq ""} { |
| | return |
| | } |
| | incr i $amount |
| | } |
| | $w selection clear 0 end |
| | $w selection set $i |
| | $w selection anchor $i |
| | $w see $i |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | method LeftRight amount { |
| | if {![info exists list]} { |
| | return |
| | } |
| | set curr [$w selection get] |
| | if {[llength $curr] == 0} { |
| | set i 0 |
| | } else { |
| | set i [$w index anchor] |
| | if {$i eq ""} { |
| | return |
| | } |
| | incr i [expr {$amount * $itemsPerColumn}] |
| | } |
| | $w selection clear 0 end |
| | $w selection set $i |
| | $w selection anchor $i |
| | $w see $i |
| | } |
| |
|
| | |
| | |
| | method KeyPress key { |
| | append accel $key |
| | my Goto $accel |
| | after cancel $accelCB |
| | set accelCB [after 500 [namespace code {my Reset}]] |
| | } |
| |
|
| | method Goto text { |
| | if {![info exists list]} { |
| | return |
| | } |
| | if {$text eq "" || $numItems == 0} { |
| | return |
| | } |
| |
|
| | if {[llength [$w selection get]]} { |
| | set start [$w index anchor] |
| | } else { |
| | set start 0 |
| | } |
| | set theIndex -1 |
| | set less 0 |
| | set len [string length $text] |
| | set len0 [expr {$len - 1}] |
| | set i $start |
| |
|
| | |
| | |
| | while {1} { |
| | if {[string equal -nocase -length $len0 $textList($i) $text]} { |
| | set theIndex $i |
| | break |
| | } |
| | incr i |
| | if {$i == $numItems} { |
| | set i 0 |
| | } |
| | if {$i == $start} { |
| | break |
| | } |
| | } |
| |
|
| | if {$theIndex >= 0} { |
| | $w selection clear 0 end |
| | $w selection set $theIndex |
| | $w selection anchor $theIndex |
| | $w see $theIndex |
| | } |
| | } |
| | method Reset {} { |
| | unset -nocomplain accel |
| | } |
| | } |
| | |
| | return |
| |
|
| | |
| | |
| | |
| | |
| |
|