| 1 | package require Metawidget |
|---|
| 2 | |
|---|
| 3 | # name: Scrollbox |
|---|
| 4 | # args: args |
|---|
| 5 | # creates the widgets. the widget option -scrollbar is defined |
|---|
| 6 | # by calling its respective member functions. |
|---|
| 7 | metawidget create Scrollbox { |
|---|
| 8 | scrollbar $this.scrv -command "$this.list yview" |
|---|
| 9 | scrollbar $this.scrh -command "$this.list xview" -orient horiz |
|---|
| 10 | listbox $this.list -bg white -border 1 -selectborder 0 -selectback black \ |
|---|
| 11 | -selectfore white -yscroll "$this.scrv set" -xscroll "$this.scrh set" |
|---|
| 12 | |
|---|
| 13 | grid columnconf $this 0 -weight 1 |
|---|
| 14 | grid rowconf $this 0 -weight 1 |
|---|
| 15 | grid $this.list -column 0 -row 0 -sticky news |
|---|
| 16 | |
|---|
| 17 | bind $this.list <1> { focus %W } |
|---|
| 18 | |
|---|
| 19 | -scrollbar off |
|---|
| 20 | } {} -default list |
|---|
| 21 | |
|---|
| 22 | # name: _setscroll |
|---|
| 23 | # args: - |
|---|
| 24 | # if -scrollbar is auto, displays or hides the two scrollbars. |
|---|
| 25 | # uses the fraction values the scrollbars would be set to. |
|---|
| 26 | # anything > 0 and < 1 would indicate that the scrollbar should |
|---|
| 27 | # be displayed. |
|---|
| 28 | metawidget proc Scrollbox _setscroll {} { |
|---|
| 29 | if { [my -scrollbar] != "auto" } return |
|---|
| 30 | |
|---|
| 31 | mkw.lassign [$this.scrv get] fFrac1 fFrac2 |
|---|
| 32 | if { $fFrac1 > 0 || $fFrac2 < 1 } { |
|---|
| 33 | grid $this.scrv -column 1 -row 0 -sticky ns |
|---|
| 34 | } else { |
|---|
| 35 | grid forget $this.scrv |
|---|
| 36 | } |
|---|
| 37 | |
|---|
| 38 | mkw.lassign [$this.scrh get] fFrac1 fFrac2 |
|---|
| 39 | if { $fFrac1 > 0 || $fFrac2 < 1 } { |
|---|
| 40 | grid $this.scrh -column 0 -row 1 -sticky we |
|---|
| 41 | } else { |
|---|
| 42 | grid forget $this.scrh |
|---|
| 43 | } |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | # name: _redraw |
|---|
| 47 | # args: - |
|---|
| 48 | # updates the scrollbars after becoming idle. any |
|---|
| 49 | # old job is deleted, so exactly one redraw is done. |
|---|
| 50 | metawidget proc Scrollbox _redraw {} { |
|---|
| 51 | catch { cancel [my hJob] } |
|---|
| 52 | my hJob [after idle $this _setscroll] |
|---|
| 53 | } |
|---|
| 54 | |
|---|
| 55 | # name: -scrollbar |
|---|
| 56 | # args: sScrollbar: on, off or auto |
|---|
| 57 | # option member. lets the scrollbars either appear (on) or disappear (off). |
|---|
| 58 | # for auto, _setscroll takes care of that. the binding is needed to |
|---|
| 59 | # update the scrollbars when the window is resized. |
|---|
| 60 | metawidget proc Scrollbox -scrollbar { sScrollbar } { |
|---|
| 61 | my -scrollbar [mkw.complete $sScrollbar {auto on off}] |
|---|
| 62 | |
|---|
| 63 | switch [my -scrollbar] { |
|---|
| 64 | auto { |
|---|
| 65 | bind $this.list <Configure> "$this _setscroll" |
|---|
| 66 | _redraw |
|---|
| 67 | } |
|---|
| 68 | on { |
|---|
| 69 | bind $this.list <Configure> {} |
|---|
| 70 | grid $this.scrv -column 1 -row 0 -sticky ns |
|---|
| 71 | grid $this.scrh -column 0 -row 1 -sticky we |
|---|
| 72 | } |
|---|
| 73 | off { |
|---|
| 74 | bind $this.list <Configure> {} |
|---|
| 75 | grid forget $this.scrv $this.scrh |
|---|
| 76 | } |
|---|
| 77 | } |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | # name: find |
|---|
| 81 | # args: args: listbox entries (not indexes) to search for |
|---|
| 82 | # the position for each entry is determined and appended to a list. the |
|---|
| 83 | # list is returned. a -1 indicates that the element is not in the list. |
|---|
| 84 | metawidget proc Scrollbox find { args } { |
|---|
| 85 | set lEntries [$this.list get 0 end] |
|---|
| 86 | set lHits {} |
|---|
| 87 | |
|---|
| 88 | foreach sText $args { |
|---|
| 89 | lappend lHits [lsearch -exact $lEntries $sText] |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | return $lHits |
|---|
| 93 | } |
|---|
| 94 | |
|---|
| 95 | # name: selection |
|---|
| 96 | # args: sOption: option to set or get the selection |
|---|
| 97 | # args: depends on sOption |
|---|
| 98 | # extends the 'listbox selection' command by the two options setbyval |
|---|
| 99 | # and get. 'setbyval' sets the selection for all listbox entries in args. |
|---|
| 100 | # (whereas 'set' sets them by index). get is the opposite of setbyval. |
|---|
| 101 | # all other options are directly handed over to the listbox. |
|---|
| 102 | metawidget proc Scrollbox selection_ { sOption args } { |
|---|
| 103 | switch $sOption { |
|---|
| 104 | setbyval { |
|---|
| 105 | set lEntries [$this.list get 0 end] |
|---|
| 106 | |
|---|
| 107 | foreach sText $args { |
|---|
| 108 | set iPos [lsearch -exact $lEntries $sText] |
|---|
| 109 | if { $iPos == -1 } continue |
|---|
| 110 | $this.list selection set $iPos |
|---|
| 111 | } |
|---|
| 112 | } |
|---|
| 113 | get { |
|---|
| 114 | set lResult {} |
|---|
| 115 | |
|---|
| 116 | foreach iIndex [$this.list curselection] { |
|---|
| 117 | lappend lResult [$this.list get $iIndex] |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | return $lResult |
|---|
| 121 | } |
|---|
| 122 | default { |
|---|
| 123 | eval $this.list selection $sOption $args |
|---|
| 124 | } |
|---|
| 125 | } |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | # name: set |
|---|
| 129 | # args: args: listbox entries |
|---|
| 130 | # deletes all entries in the listbox and adds the ones defined in args. |
|---|
| 131 | metawidget proc Scrollbox set_ { args } { |
|---|
| 132 | $this.list delete 0 end |
|---|
| 133 | eval $this.list insert 0 $args |
|---|
| 134 | _redraw |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | # name: removes |
|---|
| 138 | # args: args: listbox entries |
|---|
| 139 | # removes all entries specified in args from the listbox. |
|---|
| 140 | metawidget proc Scrollbox remove { args } { |
|---|
| 141 | set lEntries [$this.list get 0 end] |
|---|
| 142 | eval set_ [eval mkw.lshrink \$lEntries $args] |
|---|
| 143 | } |
|---|
| 144 | |
|---|
| 145 | # name: sort |
|---|
| 146 | # args: args: passed to the lsort command |
|---|
| 147 | # sorts the listbox using lsort. args is passed to the lsort command. |
|---|
| 148 | metawidget proc Scrollbox sort { args } { |
|---|
| 149 | set lEntries [$this.list get 0 end] |
|---|
| 150 | eval set_ [eval lsort $args \$lEntries] |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | # name: insert |
|---|
| 154 | # args: args: passed to 'listbox insert' |
|---|
| 155 | # wrapper around 'listbox insert'. redraws the scrollbars. |
|---|
| 156 | metawidget proc Scrollbox insert { args } { |
|---|
| 157 | eval $this.list insert $args |
|---|
| 158 | _redraw |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | # name: delete |
|---|
| 162 | # args: args: passed to 'listbox delete' |
|---|
| 163 | # wrapper around 'listbox delete'. redraws the scrollbars. |
|---|
| 164 | metawidget proc Scrollbox delete { args } { |
|---|
| 165 | eval $this.list delete $args |
|---|
| 166 | _redraw |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | metawidget command Scrollbox _setscroll _setscroll |
|---|
| 170 | |
|---|
| 171 | metawidget command Scrollbox delete delete |
|---|
| 172 | metawidget command Scrollbox insert insert |
|---|
| 173 | metawidget command Scrollbox sort sort |
|---|
| 174 | metawidget command Scrollbox remove remove |
|---|
| 175 | metawidget command Scrollbox set set_ |
|---|
| 176 | metawidget command Scrollbox selection selection |
|---|
| 177 | metawidget command Scrollbox find find |
|---|
| 178 | |
|---|
| 179 | metawidget option Scrollbox -scrollbar -scrollbar |
|---|
| 180 | |
|---|
| 181 | proc test {} { |
|---|
| 182 | global iLine |
|---|
| 183 | |
|---|
| 184 | set iLine 0 |
|---|
| 185 | |
|---|
| 186 | pack [radiobutton .rad1 -value 0 -text "Scrollbars always on" -command {.sbox config -scrollbar on}] -anchor w |
|---|
| 187 | pack [radiobutton .rad2 -value 1 -text "Scrollbars always off" -command {.sbox config -scrollbar off}] -anchor w |
|---|
| 188 | pack [radiobutton .rad3 -value 2 -text "Scrollbars in auto mode" -command {.sbox config -scrollbar auto}] -anchor w |
|---|
| 189 | |
|---|
| 190 | pack [button .addl -text "Add a line" -command { |
|---|
| 191 | incr iLine |
|---|
| 192 | .sbox insert end "It is [clock format [clock seconds] -format %H:%M:%S]. This is line $iLine." |
|---|
| 193 | .sbox see end |
|---|
| 194 | }] -fill x |
|---|
| 195 | |
|---|
| 196 | pack [button .reml -text "Remove first line" -command {.sbox delete 0}] -fill x |
|---|
| 197 | pack [scrollbox .sbox] -fill both -expand 1 |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | #test |
|---|
| 201 | |
|---|