Next: Linked Variables, Previous: Argument Lists, Up: General [Contents]
It is possible to make certain areas of a window mouse sensitive, or to run commands on reception of certain events such as keystrokes, while the focus is in a certain window. This is done by having a lisp function invoked or some lisp form evaluated. We shall refer to such a lisp function or form as a command.
For example
(button '.button :text "Hello" :command '(print "hi")) (button '.jim :text "Call Jim" :command 'call-jim)
In the first case when the window .button is clicked on, the
word "hi" will be printed in the lisp to standard output. In the
second case call-jim will be funcalled with no arguments.
A command must be one of the following three types. What happens depends on which type it is:
If the value satisfies functionp then it will be called with
a number of arguments which is dependent on the way it was bound,
to graphics.
If the command is a string, then it is passed directly to TCL/TK for evaluation on that side. Lisp will not be required for the evaluation when the command is invoked.
Any other lisp object is regarded as a lisp form to be eval’d, and this will be done when the command is invoked.
The following keywords accept as their value a command:
:command :yscroll :yscrollcommand :xscroll :xscrollcommand :scrollcommand :bind
and in addition bind takes a command as its third argument,
see See bind.
Below we give three different examples using the 3 possibilities for
a command: functionp, string, and lisp form. They all accomplish
exactly the same thing.
For given a frame .frame we could construct a listbox
in it as:
(listbox '.frame.listbox :yscroll 'joe)
Then whenever the listbox view position changes, or text is inserted,
so that something changes, the function joe will be invoked with 4
arguments giving the totalsize of the text, maximum number of units
the window can display, the index of the top unit, and finally the
index of the bottom unit. What these arguments are is specific
to the widget listbox and is documented See listbox.
joe might be used to do anything, but a common usage is to have
joe alter the position of some other window, such as a scroll
bar window. Indeed if .scrollbar is a scrollbar then
the function
(defun joe (a b c d) (.scrollbar :set a b c d))
would look after sizing the scrollbar appropriately for the percentage of the window visible, and positioning it.
A second method of accomplishing this identical, using a string (the second type of command),
(listbox '.frame.listbox :yscroll ".scrollbar set")
and this will not involve a call back to lisp. It uses the fact that
the TK graphics side understands the window name .scrollbar and
that it takes the option set. Note that it does not get
the : before the keyword in this case.
In the case of a command which is a lisp form but is not installed
via bind or :bind, then the form will be installed as
#'(lambda (&rest *arglist*) lisp-form)
where the lisp-form might wish to access the elements of the special
variable *arglist*. Most often this list will be empty, but for
example if the command was setup for .scale which is a scale,
then the command will be supplied one argument which is the new numeric
value which is the scale position. A third way of accomplishing the
scrollbar setting using a lisp form is:
(listbox '.frame.listbox :yscroll '(apply '.scrollbar :set *arglist*))
The bind command and :bind keyword, have an additional
wrinkle, see See bind. These are associated to an event in a
particular window, and the lisp function or form to be evaled must have
access to that information. For example the x y position, the window
name, the key pressed, etc. This is done via percent symbols which
are specified, see See bind.
(bind "Entry" "<Control-KeyPress>" '(emacs-move %W %A ))
will cause the function emacs-move to be be invoked whenever a control key is pressed (unless there are more key specific or window specific bindings of said key). It will be invoked with two arguments, the first %W indicating the window in which it was invoked, and the second being a string which is the ascii keysym which was pressed at the same time as the control key.
These percent constructs are only permitted in commands which are
invoked via bind or :bind. The lisp form which is passed
as the command, is searched for the percent constructs, and then a
function
#'(lambda (%W %A) (emacs-move %W %A))
will be invoked with two arguments, which will be supplied by the
TK graphics server, at the time the command is invoked. The
*arglist* construct is not available for these commands.
Next: Linked Variables, Previous: Argument Lists, Up: General [Contents]