## 6.3 Canvas Tags

Each item in a canvas is identified by a unique integer. This integer can be returned by using the `tkReturnInt` method for creating items rather than the `tk` method. The returned integer can then be used to manipulate the corresponding item. However, returning values from the graphics engine involves latency. But there are some good news here, since it is not necessary to refer to items by numbers.

tags

Canvas widgets offer a more powerful and easier method to manipulate single items or even groups of items. Items can be referred to by tags. A single item can be referred to by as many tags as you like to. Tags are provided as objects in Oz. Before an item can be added to a tag, a tag object must be created from the class `Tk.canvasTag` and initialized with respect to a particular canvas.

To add an item to a tag, the option `tags` is used when creating the item. For instance,

  `R={New Tk.canvasTag tkInit(parent:C)}
  {C tk(create rectangle 10 10 40 40 fill:red tags:R)}`

creates a new rectangle item and adds it to the tag `R`.

A second oval item can be added to the tag `R` by

  `{C tk(create oval 20 20 40 40 tags:R)}`

All items referred to by a tag can be manipulated simultaneously. The following moves all items 40 pixels to the right:

  `{R tk(move 40 0)}`

Figure 6.3 shows a small program that creates items interactively. Pressing the mouse button over the canvas widget creates either a rectangle item or an oval item at the position of the mouse pointer. All rectangle items created are added to the tag `R`, and all oval items are added to the tag `O`.

  `C={New Tk.canvas tkInit(parent:W width:300 height:200 bg:white)}
  R={New Tk.canvasTag tkInit(parent:C)}
  O={New Tk.canvasTag tkInit(parent:C)}
  {C tkBind(event: '<1>'
  args: [int(x) int(y)]
  action: proc {$ X Y}
  {C tk(create rectangle X-10 Y-10 X+10 Y+10
  tags:R fill:steelblue)}
  end)}
  {C tkBind(event: '<2>'
  args: [int(x) int(y)]
  action: proc {$ X Y}
  {C tk(create oval X-10 Y-10 X+10 Y+10
  tags:O fill:orange)}
  end)}
  {Tk.send pack(C)}`

Figure 6.3: A canvas for creating rectangles and ovals.

configuring items

Items can be configured with the command `itemconfigure`, which is similar to the command `configure` for widgets. The color of all rectangle and oval items in our previous example can be changed by:

  `{R tk(itemconfigure fill:wheat)}
  {O tk(itemconfigure fill:blue)}`

Besides of the `move` command there are other commands for manipulating items. For instance, executing the following statement

  `{O tk(delete)}`

deletes all oval items attached to the tag `O`. Other commands allow to scale items, to change the coordinates of items and so on. More information on possible commands are available from `canvas`.

### 6.3.1 Event Bindings

Similar to widgets, event bindings can be created for tags. Creating an event binding for a tag means to create the binding for all items referred to by the tag. The following example creates an event binding for all oval items.

  `Colors={New class $ from BaseObject
  attr cs:(Cs=red|green|blue|yellow|orange|Cs
  in
  Cs)
  meth get(?C)
  Cr in C|Cr = (cs <- Cr)
  end
  end noop}
  {O tkBind(event: '<3>'
  action: proc {$}
  {O tk(itemconfigure
  fill:{Colors get($)})}
  end)}`

Clicking with the right mouse button on an oval item, configures all items referred to by `O` to employ a different color. The `Colors` object serves as color generator. Each time the method `get` is invoked, it returns a color from the circular list of colors stored in the attribute `cs`.