[GUI] Another call for votes

Daan Leijen daanleijen@xs4all.nl
Tue, 18 Mar 2003 12:33:44 +0100


Hi all,

> 2) For every callback, there should be a register function.
> The register function should return an IO action that can be used to unregister the callback.

I disagree with this design. It is very awkward to install callbacks this way as we
have to maintain the "unregister" function. We can no longer use "nice" syntax like:

  button [on click := messageBox "hi there"]

I also think that "register/unregister" is a confusing name. Here is my proposal.
We have two functions for each event type. One to set the current callback,
and one to get the current callback. (there is only one callback at any time).

  buttonOnClick    :: IO () -> Button -> IO ()
  buttonGetOnClick :: Button -> IO (IO ())

  windowOnMenu     :: MenuItem -> IO () -> Window -> IO ()
  windowGetOnMenu  :: MenuItem -> Window -> IO (IO ())

  ...

This mechanism is enough to build a nice framework around. For example, you
could add a callback to the existing ones.

  buttonAddOnClick io button
    = do prev <-buttonGetOnClick button
         buttonSetOnClick (do{ io; prev }) button

(ha, do we still want concurrency here :-)

Or implement the yahu/gio syntax for setting/getting events:
 w <-window [on click := dropBall]

In general, you can implement "listeners" or callback transformers like filters.
Maybe one of these designs indeed returns an "unregister" function but that is
up to the library writer.

The only think lacking is indeed the "unregister" call but I think it is a highly
unusual thing to deinstall a callback without replacement on an existing widget.
Normally, the callbacks are deinstalled when the widget dies.
But for completeness, we might want to have:

   buttonIgnoreOnClick :: Button -> IO ()


All the best,
  Daan.