Previous section   Next section

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Part V.  Tk Details

Chapter 43. A User Interface to Bindings

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.

      Previous section   Next section