[jnc] Dec 2, 2009 - Tk currently lacks a multiline entry widget. The text widget is a great widget but a bit complex if you just need a multiline plain text widget that acts like [entry]. This is one of many solutions on the wiki. This solution includes support for: * -textvariable * attaching scroll bars (vertical by default) * handling Tab and Shift-Tab correctly * optionally allowing tabs inside of the widget with the -allowtab option * readonly mode with common keyboard navigation using the -readonly option ====== snit::widget multiline_entry { delegate option * to text delegate method * to text # On/Off options option -yscroll -default yes option -xscroll -default no option -allowtab -default no option -readonly -default no # Miscellaneous options option -textvariable -default 0 constructor { args } { install text using text $win.txt grid $win.txt -row 0 -column 0 -sticky nswe $self configurelist $args if { [$win cget -yscroll] } { $win.txt configure -yscrollcommand [list $win.vsb set] ttk::scrollbar $win.vsb -command [list $win.txt yview] grid $win.vsb -row 0 -column 1 -sticky nsw } if { [$win cget -xscroll] } { $win.txt configure -xscrollcommand [list $win.hsb set] ttk::scrollbar $win.hsb -orient horizontal -command [list $win.txt xview] grid $win.hsb -row 1 -column 0 -sticky we } grid rowconfigure $win 0 -weight 1 grid columnconfigure $win 0 -weight 1 if {[$win cget -textvariable] != 0} { set varName [$win cget -textvariable] upvar 3 $varName v $win.txt insert 1.0 $v $win.txt mark set insert 1.0 trace add variable v write [list $self setContent] trace add variable v read [list $self getContent] } bind $win [list focus $win.txt] if { !$options(-allowtab) } { bind $win.txt [list $self focusPrev] bind $win.txt [list $self focusNext] } if { $options(-readonly) } { bind $win.txt break bind $win.txt break bind $win.txt continue bind $win.txt continue bind $win.txt continue bind $win.txt continue bind $win.txt continue bind $win.txt continue } } method getTextWidget {} { return $win.txt } method focusPrev {} { focus [tk_focusPrev $win] return -code break } method focusNext {} { focus [tk_focusNext $win.txt] return -code break } method setContent { name element op} { upvar 1 $name x $win.txt delete 1.0 end if { [array exists x] } { $win.txt insert 1.0 $x($element) } else { $win.txt insert 1.0 $x } } method getContent { name element op } { upvar 1 $name x if { [array exists x] } { set x($element) [$win.txt get 1.0 "end-1 char"] } else { set x [$win.txt get 1.0 "end-1 char"] } } } ====== ---- [jnc] Dec 21, 2009 - Added a `-readonly` option, however, it also prevents keyboard navigation. Any better ideas? [WHD] Redefine the "insert" and "delete" subcommands so that they do nothing if -readonly is true. Then, the Text bindings that change the content of the widget will have no effect. To be really fancy, define your own -state option with three values, "normal", "disabled", and "readonly"; pass the first two along to the hull and set your readonly flag for the third. [Bezoar] I rewrote the above widget using TclOO [Multi-line TclOO Text Entry Widget] just to see how hard it would be to convert between the two. Turns out it was very easy. I did add some features that don't exist in this version. First all option not recognized by the Widget get sent to the internal text widget so you get the -state option mentioned above by [WHD] for free. I also corrected the fact that you could still cut and paste into a readonly widget and finally when -xscroll = 1 I also shut off wrapping in the text widget otherwise it is useless. I have some test code at the afore mentioned page to test the widget. [jnc] Sep 15, 2010 - Updated code, includes better readonly support (keyboard navigation) and no mouse paste ability. Handling of getting/setting via array. ---- See also: [Multiline expanding entry widget], [Multi-Line Text Entry Widget - With Entry Widget Like Field To Field Tabbing] and [GRIDPLUS2]. ---- !!!!!! %| [Category Package] | [Category GUI] | [Category Widget] |% [text] - [Arts and crafts of Tcl-Tk programming] !!!!!!