This chapter presents a user interface to view and edit bindings. A good way to learn about how a widget works is to examine the bindings that are defined for it. This chapter presents a user interface that lets you browse and change bindings for a widget or a class of widgets. The interface uses a pair of listboxes to display the events and their associated commands. An entry widget is used to enter the name of a widget or a class. There are a few command buttons that let the user add a new binding, edit an existing binding, save the bindings to a file, and dismiss the dialog. Here is what the display looks like: Example 43-1 A user interface to widget bindings. proc Bind_Interface { w } { # Our state global bind set bind(class) $w # Set a class used for resource specifications set frame [toplevel .bindui -class Bindui] # Default relief option add *Bindui*Entry.relief sunken startup option add *Bindui*Listbox.relief raised startup # Default Listbox sizes option add *Bindui*key.width 18 startup option add *Bindui*cmd.width 25 startup option add *Bindui*Listbox.height 5 startup # A labeled entry at the top to hold the current # widget name or class. set t [frame $frame.top -bd 2] label $t.l -text "Bindings for" -width 11 entry $t.e -textvariable bind(class) pack $t.l -side left pack $t.e -side left -fill x -expand true pack $t -side top -fill x bind $t.e <Return> [list Bind_Display $frame] # Command buttons button $t.quit -text Dismiss \ -command [list destroy $frame] button $t.save -text Save \ -command [list Bind_Save $frame] button $t.edit -text Edit \ -command [list Bind_Edit $frame] button $t.new -text New \ -command [list Bind_New $frame] pack $t.quit $t.save $t.edit $t.new -side right # A pair of listboxes and a scrollbar scrollbar $frame.s -orient vertical \ -command [list BindYview \ [list $frame.key $frame.cmd]] listbox $frame.key \ -yscrollcommand [list $frame.s set] \ -exportselection false listbox $frame.cmd \ -yscrollcommand [list $frame.s set] pack $frame.s -side left -fill y pack $frame.key $frame.cmd -side left \ -fill both -expand true foreach l [list $frame.key $frame.cmd] { bind $l <B2-Motion>\ [list BindDragto %x %y $frame.key $frame.cmd] bind $l <Button-2> \ [list BindMark %x %y $frame.key $frame.cmd] bind $l <Button-1> \ [list BindSelect %y $frame.key $frame.cmd] bind $l <B1-Motion> \ [list BindSelect %y $frame.key $frame.cmd] bind $l <Shift-B1-Motion> {} bind $l <Shift-Button-1> {} } # Initialize the display Bind_Display $frame } The Bind_Interface command takes a widget name or class as a parameter. It creates a toplevel and gives it the Bindui class so that resources can be set to control widget attributes. The option add command is used to set up the default listbox sizes. The lowest priority, startup, is given to these resources so that clients of the package can override the size with their own resource specifications. At the top of the interface is a labeled entry widget. The entry holds the name of the class or widget for which the bindings are displayed. The textvariable option of the entry widget is used so that the entry's contents are available in a variable, bind(class). Pressing <Return> in the entry invokes Bind_Display that fills in the display. Example 43-2 Bind_Display presents the bindings for a widget or class. proc Bind_Display { frame } { global bind $frame.key delete 0 end $frame.cmd delete 0 end foreach seq [bind $bind(class)] { $frame.key insert end $seq $frame.cmd insert end [bind $bind(class) $seq] } } The Bind_Display procedure fills in the display with the binding information. The bind command returns the events that have bindings, and what the command associated with each event is. Bind_Display loops through this information and fills in the listboxes. |