Creating custom items

You can add new item types to the Slate by writing an Itcl class. You need to inherit from Picture or a subclass. The Picture class and its subclasses are not proper classes, but a mechanism for manipulating items IDs and tags to give the Slate client the appearance of a single complex item, which is made of many primitive items.

As an example, we will create a simple class that is an oval with a text label in the center of it. This is a simple version of the LabelledOval class. Firstly, we'll create the class body (the details will be filled in shortly):

class ::tycho::Simple {
    inherit ::tycho::Picture

    proc construct {id canvas slate tags x0 y0 x1 y1 args}
    proc coords    {id canvas slate args}
    proc _text     {id canvas slate tx}

    common _text
    common textitem
    common shape "oval"

    common methodtable
    array set methodtable [array get ::tycho::Picture::methodtable]
    set methodtable(construct) ::tycho::Simple::construct
    set methodtable(coords)    ::tycho::Simple::coords
    set methodtable(_text)     ::tycho::Simple::_text

    common optiondefault
    array set optiondefault [array get ::tycho::Picture::optiondefault]
    set optiondefault(-text) ""
}

Notice that the class contains procedures only -- not methods. The first three arguments to each procedure are always id (the item ID), canvas (the canvas widget inside the slate we are drawing on) and slate (the slate widget). Notice also that all data is ``common'': each is an array indexed by the item ID. Every Picture subclass must have at least the common variables shape, methodtable, and optiondefault.

To simulate inheritance, methodtable must first be set with the names of the procs in the parent class (the first array set), and then updated with procs defined in this class. The options are also inherited: the same procedure must be followed with the optiondefault array. This class has a single optoin, -text.

The construct procedure is called to create a new item. It must start by setting the options: the first three lines of code are common to every construct procedure. In this case, the text array will have an entry set to the supplied value of the -text option, or the default value if none is supplied.

The next line creates the "primary" item -- every picture must create one of these, which must be a primitive items. It is used by the slate to get the coordinates of the complex item. In this example, the primary item is also displayed; in other cases, it may not be displayed (by setting its -outline option to {}). The final line of code creates the text label, using the -text option, and remembers the text item ID in the textitem array.

body ::tycho::Simple::construct {id canvas slate tags x0 y0 x1 y1 args} {
    # Initialize the options
    foreach {option value} [concat [array get optiondefault] $args] {
		set _[string trimleft $option -]($id) $value
    }

    # Create the primary component. This is the displayed oval.
    set primary($id) [$canvas create oval $x0 $y0 $x1 $y1 \
	    -tags $tags]

    # Create the text label
    set textitem($id) [$canvas create text \
	    [expr ($x0+$x1)/2] [expr ($y0+$y1)/2] \
	    -text $_text($id) -tags $tags]
}

When the -text option is configured, the slate calls a procedure with the same name as the option (without the leading dash). Here is the text procedure -- it updates the text in the text item:

body ::tycho::Simple::_text {id canvas slate text} {
    set _text($id) $text
    $canvas itemconfigure $textitem($id) -text $_text($id)
}

Finally, we provide a special implementation of the coords procedure to handle a change in the coordinates. (In this example, it is not really necessary: the Slate provides a default behavior based on item scaling that will be adequate for many complex items.)

body ::tycho::Simple::coords {id canvas slate args} {
    if { $args == "" } {
		return [$canvas coords $primary($id)]
    }
    assign x0 y0 x1 y1 $args

    # Move the oval
    $canvas coords $primary($id) $x0 $y0 $x1 $y1

    # Move the text item
    $canvas coords $textitem($id) [expr ($x0+$x1)/2] [expr ($y0+$y1)/2]
}

To try out your new item type, just call the Slate as before:

set m [$slate create Simple 20 60 60 80 -text Foo]

Move it:

$slate move $m 10 10

Change its coordinates:

$slate coords $m 10 10 90 90

Change its label:

$slate itemconfigure $m -text Bar

Next
Back up
Tycho Home Page


Copyright © 1996, The Regents of the University of California. All rights reserved.
Last updated: 96/12/11, comments to: johnr@eecs.berkeley.edu