-
Notifications
You must be signed in to change notification settings - Fork 52
01 Components
Roassal3, has different classes that you can use to create a visualization from a group of objects. In roassal3 all the classes start with the prefix RS, with the top class RSObject, because Pharo does not have namespaces like other smalltalk dialects, and we do not want that one of our classes have the same name that other class in other project.
A container of shapes. Adding a shape to the canvas makes it visible and responsible to user events.
A RSCanvas describes an interactive visualization, and is not part of the visual environment of the Pharo-Morphic system, but use a morph to render all the shapes with the method createMorph
.
- Canvas has a viewing camera RSCamera, useful to scale and translate the shapes in the visualization.
- Canvas has collections of shapes in different levels and groups(RSGroup).
- Shapes, the origin of this shapes is in the center of the morph, the camera affects this group.
- Fixed shapes, a second layer that renders after the first group of shapes, the camera does not affect this group, and the origin is in the top left corner of the visual area.
- Also a canvas has animations, these animations are executed by the canvas each time the canvas is updated.
- Canvas has a reference to the created morph, in order to access it and put it on other morphs for Pharo.
Drawing a canvas and its shapes dependes on the backend library, for Pharo depends on Athens-Cairo.
canvas := RSCanvas new.
canvas add: (RSEllipse new
color: Color red;
size: 10;
position: 0@0;
yourself).
canvas add: (RSBox new
color: Color blue;
size: 100;
position: 200@100;
yourself).
canvas
The previous example shows:
- the canvas origin is in the center of the window for non fixed shapes, the red ellipse in this case is in the canvas origin.
- the blue box defines a size (width and height) of 100 pixels, and a position of 200@100.
Is a visual entity such as lines, boxes, text, and more. Shapes can have a fill paint, or a border. A paint is used by Cairo graphics and it can be, a Color, or a Gradient, or an Image. And a border is represented by RSBorder, a border describes the line style, the paint, and the width of the border line of each shape.
There are two groups of shapes bounding shapes and line shapes, the position of a shape in Roassal is the center of the shape.
box := RSBox new.
box extent: 100@100.
box encompassingRectangle.
"(-50.0@ -50.0) corner: ([email protected])"
box position: 100@100.
box encompassingRectangle.
"([email protected]) corner: ([email protected])"
Shapes can have a reference to one model, and object whose graphical representation is the shape.
Also in order to create lines or edges between nodes, there is a class RSEdgeBuilder, this class interact with the shapes models
RSCanvas and RSShapes are subclasses of RSObjectWithProperty, this means that the canvas and the shapes has a dictionary of attributes, where you can put extra data for your visualization.
canvas propertyAt: #foo put: 'bar'
shape propertyAt: #foo put: 0.
shape includesKey: #foo.
"0"
shape removeKey: #foo.
shape propertyAt: #foo
"nil"
There are 2 types of shape containers in Roassal, RSCanvas and RSComposite, for that reason Roassal has a trait RSTContainer. Containers in Roassal have their shapes separated in nodes(subclasses of RSBoundingShape) and edges(line shapes, subclasses of RSAbstractLine).
Also containers respond to the method add:
and addAll:
canvas add: RSBox new.
"adding a new box"
canvas shapes size.
"1"
canvas add: RSLine new.
"adding a new line"
canvas shapes size.
"2"
canvas nodes size.
"1 box"
canvas edges size.
"1 line"
The class RSGroup is an OrderedCollection of shapes. Groups are used to uniformly manipulate a set of shapes.
Groups are not composite shapes but can perform some methods of composite shapes.
group := RSGroup new.
group add: (RSBox new size: 100).
group add: (RSEllipse new size: 200; position: 100@100).
group encompassingRectangle.
"(-50.0@ -50.0) corner: ([email protected])"
Roassal uses instances of Announcer class from Pharo to handle and organize events or subclasses ofRSEvent. please read more about Pharo-Announcement system.
Canvas, shapes and animations defines an announcer when the code has user events.
canvas := RSCanvas new.
"we create a canvas"
canvas privateAnnouncer.
"nil. the announcer has not been used"
canvas
when: RSExtentChangedEvent
do: [ :evt | canvas extent traceCr ].
canvas open
"transcript show ([email protected])"
In the previous example the announcer is only created when we use the method when:do:
, this method recibes a class subclass from Announcement, and a BlockClosure. The block can have or not and argument the event, usually an instance of the first argument, in this case evt
is an instance of RSExtentChangedEvent
.
The example register the events for the canvas, and triggers the event with canvas open
, because the event will be executed when open creates the instance of RSMorph, this opening process will change the extent of the canvas and RSMorph will send the message announce:
to the canvas.
Roassal offers a numerous different layouts and supports the composition of layouts, a layout is the visualization representation along a two-dimensional plan of shapes, typically edges and nodes.
canvas := RSCanvas new.
shapes := (1 to: 30) collect: [ :number|
RSEllipse new size: 12;
model:number ;
color: Color blue ].
canvas addAll: shapes.
RSEdgeBuilder line
canvas: canvas;
connectFrom: [ :number | number //2 ].
shapes do: [ :shape|
shape translateTo: (250 atRandom @ 250 atRandom) ].
canvas zoomToFit.
canvas
The script builds some nodes and edges that link these nodes, each node is translated to a random location, the moves the camera to fit to the visualization with zoomToFit
. Applying a RSTreeLayout
highlights the structure from the connection between the elements.
...
RSTreeLayout on: shapes.
canvas zoomToFit.
canvas
An animation is an interface for animating changes in the canvas. Instead of applying changes instantaneously, animations smoothly interpolate the shapes from its current state to the desired target state over a given duration.
To apply an animation, add a new animation to the canvas and then make the desired changes. For example:
canvas := RSCanvas new.
canvas newAnimation
from: Color white;
to: Color black;
onStepDo: [ :color | canvas color: color ].
canvas
In the previous example the code defines a new animation for the canvas background color. This animation starts in color white, after 2 seconds(the default time) the canvas color is black.
RSAbstractAnimation is an abstract class for animations, it has common methods that describes the behavior of each animation in Roassal.
Roassal offers 3 types of animations, in the packages Roassal3-Animations
:
- RSTransitionAnimation for animations from one value to another.
- RSSequentialAnimation this animation collects animations and execute them in sequence.
- RSParallelAnimation this animation collects animations and execute them in parallel.
There is a wiki page that talks in more detail about animations.