View this PageEdit this PageAttachments to this PageHistory of this PageHomeRecent ChangesSearch the SwikiHelp Guide
Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007

Subcanvases made semi-easy

Individual case by Nick Yaitsky

What is a subcanvas?

A subcanvas is a container with bounds and other properties used to hold other UI objects. It has no real aspect or value, but can pull a window spec from an ApplicationModel and display it.

The basics

majorKeyan ApplicationModel responsible for building the subcanvas
minorKeya full spec for the subcanvas to display
clientKeyan Application that controls the aspects of the components in the spec
componentsan OrderedCollection of components in the order that they were added

	^nil asValue.

All the aspect returns is a ValueHolder on nil, which theoretically, does nothing. Why? Doesn’t matter.

Pulling an existing subcanvas

If you have a subcanvas installed on a window spec, you can pull it out of that ApplicationModel at runtime. To do this, you need to access the named components of its builder.

subcanvas := (self builder componentAt: #subcanvas) widget.
selfis an instance of an ApplicationModel
#subcanvasis the ID of the subcanvas installed on that ApplicationModel

Changing the spec of a subcanvas

There are three ways to rebuild the subcanvas with another spec and client application.

subcanvas client: anApplicationModel.
subcanvas client: anApplicationModel spec: aFullSpec.
subcanvas client: anApplicationModel spec: aFullSpec builder: aBuilder

All three methods work the same way, and the only things you really need are the client and spec. If you don’t specify a spec, it will use the default spec of the client.

If you look at the code generated by the Painter Tool, you’ll notice that all it is is an array of component specs. We’re going to use that message and build a full spec out of it.

spec := UISpecification from: anElement class windowSpec.
anElementis a class with an installed spec
windowSpecis the message name that returns an array of spec components

In this case, anElement is an ApplicationModel and we’re using windowSpec as the spec to display on a subcanvas with an ID of #subcanvas:

spec := UISpecification from: anElement class windowSpec.
subcanvas := (self builder componentAt: #subcanvas) widget.
subcanvas client: anElement spec: spec.

Creating a subcanvas through code

To create subcanvas, you need to create a SubCanvasSpec. To do so you’ll need to set up its position, client, spec, and then use a builder to create the subcanvas itself.

First we set up the layout:

aLayoutFrame := LayoutFrame leftOffset: left topOffset: top rightOffset: right bottomOffset: bottom.
left, right, top, and bottomare all integers setting the bounds of the frame

Set up the basis of the canvas spec:

canvasSpec := UI.SubCanvasSpec layout: aLayoutFrame.
canvasSpec name: #subcanvasID.
canvasSpec majorKey: #{ClassName}.
canvasSpec minorKey: #specFunction.
canvasSpec model: anApplicationModel.
subcanvasIDis the name of the subcanvas
#{ClassName}is the class name of the class object that has a spec function
#specFunctionis the name of the function returning a spec
anApplicationModelis the instance of the class controlling the aspects of the components in the spec

And finally to build it and display it:

subBuilder := aModel builder newSubBuilder.
aSubcanvas := subBuilder add: canvasSpec.
parentSubcanvas add: aSubcanvas.

In order to apply the theme of the current application, we need to use the current application’s builder. aModel is that parent application. We create a new sub builder from the model, and add the canvasSpec to it. Now that we have the actual subcanvas, we have to put it on something. The parentSubcanvas is the container into which we add our new subcanvas just as any other component.


	| subcanvas canvasSpec subBuilder |
	subcanvas := (self parentModel builder componentAt: #subcanvas) widget.
	canvasSpec := UI.SubCanvasSpec layout: (LayoutFrame leftOffset: 255 topOffset: 110 rightOffset: 590 bottomOffset: 495).
	canvasSpec name: #showroomCanvas.
	canvasSpec majorKey: #{Project.Car}.
	canvasSpec minorKey: #tireSpec.
	canvasSpec model: self.
	subBuilder := self parentModel builder newSubBuilder.
	tireSubcanvas := subBuilder add: canvasSpec.

	subcanvas add: tireSubcanvas.

Links to this Page