Basic Node Structure
From Emitrom
Contents |
LienzoPanel
LienzoPanel is a GWT widget that extends the GWT FocusPanel class, that makes its contents focusable, and adds the ability to catch mouse and keyboard events.
The LienzoPanel constructor takes two parameters, the width and height of the panel in pixels. It contains a Viewport, which contains three Scenes: the Background Scene, the Main Scene and the Drag Scene.
Scenes can contain one or more Layers.
- The Background Scene contains at most one Layer, called the Background Layer
- The Drag Scene contains one Layer, called the Drag Layer
- The Main Scene can contain one or more (Regular) Layers
Layers contain IPrimitive nodes, such as Groups and Shapes. Groups may contain additional Shapes and Groups. GridLayers are Layers that draw an additional Grid behind their child nodes.
IPrimitive nodes have the following attributes that allow them to be placed and transformed: x, y, rotation, scale, shear, offset and transform. In addition, they can be drawn (see IDrawable), selected (a.k.a. picked), dragged (see Dragging), animated (see Animation), change visibility and listen for events.
Viewport, Scene, Layer and Group are ContainerNodes (i.e. they can have child nodes.)
Shape and ContainerNode are types of Nodes.
See the class hierarchy diagram with Node and its subclasses on the right.
Viewport
The Viewport contains the visible Layers, organized in Scenes.
The transform attribute of the Viewport (i.e. Viewport Transform) defines the viewable area of zoomable Layers.
TODO: mention Mediators, resize handlers, ViewportTransformChangedHandler
Viewport Attributes
| Attributes | Description |
|---|---|
| transform | See Transform related attributes |
Note that none of the other Node Attributes apply to Viewports.
Scene
The Viewport contains three Scenes: the Background Scene, the Main Scene and the Drag Scene. The Background Scene is drawn first, then the Main Scene and then the Drag Scene.
TODO:
- why do we have Scenes?
- why not put the Layers directly under the Viewport?
- mention that none of the Node Attributes apply to Scenes
Background Scene
The Background Scene has at most one Layer, called the Background Layer.
The sole purpose of the Background Scene is to make it easy for users to create a Layer with "static" graphics that is drawn behind the Regular Layers.
Main Scene
The Main Scene contains one or more Regular Layers with IPrimitive nodes. This is where you would add nodes with which you can interact, e.g. buttons, sliders, graphs of nodes that can be dragged, charts, etc.
The Main Scene can be accessed with:
LienzoPanel panel = new LienzoPanel(); Viewport viewport = panel.getViewport(); Scene mainScene = viewport.getScene(); // or: Scene mainScene = panel.getScene();
To create a Regular Layer and add it to the Main Scene:
LienzoPanel panel = new LienzoPanel(); Layer layer = new Layer(); panel.getScene().add(layer); // or panel.add(layer);
Drag Scene
The Drag Scene has only one Layer, called the Drag Layer. It is used when drawing IPrimitive nodes that are being dragged or during rubber banding operations, e.g. when stretching or rotating a shape in a node editor.
Layer
A Layer may contain multiple IPrimitive nodes, such as Groups and Shapes.
Each Layer has its own HTML5 canvas element (see CanvasElement).
Layer Attributes
| Attributes | Description |
|---|---|
| visible | Whether the Layer is visible (default: true.) |
| listening | Whether the Layer is listening for events (default: false.) |
| clearLayerBeforeDraw | Whether to clear the Layer (i.e. erase the graphics) before drawing (default: true.)
TODO: provide example of when you would set it to false |
| zoomable | Whether zoom and pan operations on the Viewport should affect the Layer (default: true.)
If true, the Transform of the Viewport is taken into account when the Layer is drawn.
|
| x, y, (location), rotation, scale, shear, offset and transform | See Transform related attributes |
See Node Attributes for additional info.
Regular Layer
Layers in the Main Scene are called Regular Layers. Regular Layers are different from the Background Layer in that they support Picking and Dragging of IPrimitive nodes and may respond to Events.
To create a Regular Layer and add it to the Main Scene:
LienzoPanel panel = new LienzoPanel(); Layer layer = new Layer(); panel.getScene().add(layer); // or panel.add(layer);
Selection Layer
Regular Layers have a secondary Layer, called the Selection Layer, where the toolkit draws the silhouette of each shape in a unique color. This makes it easy to find where each Shape was drawn during Dragging and Picking operations.
See Picking for a detailed description.
Drag Layer
The Drag Scene has a special layer called Drag Layer. The Drag Layer is always drawn on top of all other Layers.
It can be used for drawing temporary graphics, e.g. zoom boxes or rubberbanding graphics. It is used when Nodes are dragged with the built-in drag mechanism.
The Main Scene can be accessed with:
LienzoPanel panel = new LienzoPanel(); Viewport viewport = panel.getViewport(); Layer dragLayer = viewport.getDragLayer(); // or: Layer dragLayer = panel.getDragLayer();
Background Layer
The Background Layer is part of the Background Scene and is drawn behind all other Layers.
It is really just a Regular Layer, except it doesn't receive events, so Picking and Dragging won't work here.
You can set the Background Layer with:
LienzoPanel panel = new LienzoPanel(); Viewport viewport = panel.getViewport(); Layer backgroundLayer = new Layer(); viewport.setBackgroundLayer(backgroundLayer); // or panel.setBackgroundLayer(backgroundLayer);
Note that moving a (Regular) Layer to the back in the Main Scene can be achieved with:
Layer layer = new Layer(); viewport.getScene().add(layer); // add Layer to the Main Scene layer.moveToBottom(); // move it to the back
And switching off events notifications and Selection Layer overhead can be done with:
layer.setListening(false);
GridLayer
GridLayer is a Layer that can be used a Regular Layer or a Background Layer. It basically draws grid lines behind its child nodes.
For each direction (X for vertical lines) and (Y for horizontal lines) you may define a primary line and a secondary line.
For instance, you could draw a primary line every 200 pixels and a secondary line every 50 pixels.
We're assuming that the primary cell size is a multiple of the secondary cell size (in the same direction.)
The strokeWidth of the lines is impervious to any transforms defined on the Layer or its Viewport, i.e. a 1 pixel line will always show as a 1 pixel line, regardless of how far you zoomed in or out.
You can use the Line class to define the grid lines, so any Line attributes are allowed, including dashed lines.
Note that the empty GridLayer constructor does not add any Lines, so you will not see a grid unless you add some Lines.
Here's the code that produced the GridLayer in the image above:
LienzoPanel panel = new LienzoPanel(); Line line1 = new Line(0, 0, 0, 0).setStrokeColor(ColorName.BLUE); // primary line Line line2 = new Line(0, 0, 0, 0).setStrokeColor(ColorName.GREEN); // secondary line line2.setDashArray(2, 2); // the secondary lines are dashed lines // Use primary and secondary lines in both directions. // Primary lines every 200 pixels, secondary lines every 50 pixels GridLayer gridLayer = new GridLayer(200, line1, 50, line2); panel.add(gridLayer);
GridLayer Attributes
In addition to the Grid Attributes, GridLayer also supports:
| Attributes | Description |
|---|---|
| primarySizeX | Width of the primary grid cells |
| primaryLineX | Line used for drawing the vertical primary lines |
| primarySizeY | Height of the primary grid cells |
| primaryLineY | Line used for drawing the horizontal primary lines |
| secondarySizeX | Width of the secondary grid cells |
| secondaryLineX | Line used for drawing the vertical secondary lines |
| secondarySizeY | Height of the secondary grid cells |
| secondaryLineY | Line used for drawing the horizontal secondary lines |
IPrimitive
IPrimitive nodes have the following attributes that allow them to be placed and transformed: x, y, rotation, scale, shear, offset and transform. In addition, they can be drawn (see IDrawable), selected (a.k.a. picked), dragged (see Dragging), animated (see Animation), change visibility and listen for events.
There are two types of primitive nodes, Shapes (such a Circle, Rectangle, etc.) and Groups.
Group
Groups are IPrimitive nodes that may contain other IPrimitive nodes, such as Shapes and Groups. There is no restriction on how many levels deep Groups can be nested. Groups can be added to Groups and to Layers.
See Node Attributes for which attributes apply to Groups.
Shape
Shapes can be added to Groups and Layers.
See Shape for details of the various Shapes: Circle, Rectangle, Line, Text, Arc, Slice, Ellipse, PolyLine, Polygon, Triangle, QuadraticCurve, BezierCurve, RegularPolygon, Star, Parallelogram, Arrow, Picture, Movie
IDrawable
Objects that implement IDrawable can be drawn, they can be made (in)visible and listen for events. All Nodes extend IDrawable.
The IDrawable interface may become useful in the future. Right now it doesn't really do anything...



