Creating custom items

You can add new item types to the Slate by writing an Itcl class. You need to inherit from ComplexItem or a subclass. The ComplexItem 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 LabeledOval class. Firstly, we'll create the class body (the details will be filled in shortly):

class ::tycho::Simple {
    inherit ::tycho::ComplexItem

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

    protected common shape "oval"

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

    private common optiondefault
    array set optiondefault [array get ::tycho::ComplexItem::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 ComplexItem subclass must have 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 option, -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 component array (define in the ComplexItem superclass).

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

    # 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 component(label$id) [$canvas create text \
	    [expr ($x0+$x1)/2] [expr ($y0+$y1)/2] \
	    -text $option(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 option(text$id) $text
    $canvas itemconfigure $component(label$id) -text $text
}

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)]
    }
    ::tycho::assign x0 y0 x1 y1 $args

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

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

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

  set slate [::tycho::Slate::demoslate]
  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-1998, The Regents of the University of California. All rights reserved.
Last updated: 04/06/98, comments to: johnr@eecs.berkeley.edu