Gnocl Cookbook‎ > ‎

    Redirecting event data to one of a number of choices

    A simple approach to managing a large number of interactive menu choice.

    Tcl is really good at making the difficult easy. Imagine a paint program with a range of tools, the action of which will differ yet they will all act to change a single buffer. What then, is the simplest way of for the application to decide how to pass  information about user interaction over to the appropriate functionality. I remember seeing, many years ago, the source code for the AT&T Tips paint software (running on now ancient Targa and Vista display buffers). Here the operator would make a choice, a global variable was set and the input data passed on after entering a cascade of switch/case operations. Would it not be simpler to have a unified series of arguments passed to a handling function the pointer to which is set rather than a variable?  This is how Gtk handles event programming and we can use a similar principle in our Gnocl scripts.

    Consider the following code segment to make a typical paint toolbar:

    # create tools
    set tools [gnocl::box]
    foreach i {clear pencil eraser picker fill undo redo copy paste} {
        catch { $tools add [gnocl::button \
                    -tooltip $i \
                    -name $i \
                    -icon "%/./icons/$i.png" \
                    -relief none \
                    -onClicked { set handler(active) [%w cget -name] }]
        }
    }

    All looks pretty straight forward, but further examination of the -onClicked command shows that the global variable handler(active) has been set to the name of of this widget.  This, of course assumes that a following procedure exists. The following example is for a simple pixel drawing pencil.

    proc pencil {w x y b m} { ....... }

    Where:

    w    -the widget-id of the calling widget
    x    -the cursor x coordinate
    y    -the curose y coordinate
       -the button event
    m    -the state of the keyboard modifiers

    Now, whenever user interaction occurs in the image  drawing/edit areas, all event information can be passed directly as the following snippet shows. All that has happened is that the name the handler script has changed -simple!

    set img1 [gnocl::image -image "%?$pb1"]
    set ebox1 [gnocl::eventBox \
        -child $img1 \
        -onMotion {  $handler(active) %w %x %y %b %m  }]

    Here a gnocl::image, which has no inherent signal mask is contained in a gnocl::eventBox.  Whenever a motion event occurs, the interpreter will involk the preselected handling function.

    The basic notion then is quite simple and potentially saves a whole pile checking issues. There's only one issue though. The -name option used by Glade produced UIs, so care must be taken to ensure consistency between proc and widget naming during the layout process.

    WJG


    Sections