10.5.1.1 Using Gadgets

Every gadget has a
client
that is specified when the gadget is created. The client is notified via the callback mechanism when any important user interaction takes place. Typically, a gadget's client will be an application frame or a composite pane. Each callback generic function is invoked on the gadget, its client, the gadget id, and other arguments that vary depending on the callback.

For example, the argument list for
activate-callback
looks like
(gadget client gadget-id)
. Assuming the programmer has defined an application frame called
button-test
that has a CLIM stream pane in the slot
output-pane
, she could write the following method:

(defmethod activate-callback

((button push-button) (client button-test) gadget-id)

(with-slots (output-pane) client

(format output-pane

"The button ~S was pressed, client ~S, id ~S."

button client gadget-id)))

One problem with this example is that it differentiates on the class of the gadget, not on the particular gadget instance. That is, the same method will run for every push button that has the
button-test
frame as its client.

One way to distinguish between the various gadgets is via the
gadget id
, which is also specified when the gadget is created. The value of the gadget id is passed as the third argument to each callback generic function. In this case, if we have two buttons, we might install
start
and
stop
as the respective gadget ids and then use
eql
specializers on the gadget ids. We could then refine the previous method as:

(defmethod activate-callback

((button push-button) (client button-test)

(gadget-id (eql 'start)))

(start-test client))

(defmethod activate-callback

((button push-button) (client button-test)

(gadget-id (eql 'stop)))

(stop-test client))

;; Create the start and stop push buttons

(make-pane 'push-button

:label "Start"

:client frame :id 'start)

(make-pane 'push-button

:label "Stop"

:client frame :id 'stop)

Another way to distinguish between gadgets is to specify explicitly what function should be called when the callback is invoked. This is done by supplying an appropriate initarg when the gadget is created. The previous example could then be written as follows: