Picture Elements
The presentation library provides the presentation.Picture
element that allows creating
more complex line drawings, and similar. Its design is inspired from TikZ in LaTeX. As such, a
picture contains a set of nodes and a set of edges (actually implemented as a single set of
picture elements, presentation.PElement
).
The picture itself acts as a regular element with regard to the remainder of the presentation. It
automatically computes a bounding box of the pictures, and centers its contents in the allocated
area. It is also possible to scale the entire contents of a picture using its scale
attribute.
The picture element is integrated with the remainder of the presentation library. As such, a custom syntax is available for creating picture elements conveniently. Furthermore, it is possible to apply animations to individual elements inside a picture, just as to elements in a presentation.
Syntax
A picture element can be defined anywhere a regular element would otherwise be defined using the
keyword picture
. The keyword is then followed by a block that contains the definition of the
picture. Note that a limitation in the picture syntax is that it is not possible to define
parameters for the parent layout inside the picture block. If this is necessary, wrap the picture in
a Stack
layout or similar.
The syntax inside a picture
block is similar to that of the layout language, but with some minor
differences. Each line corresponds to adding some element to the picture. Lines have the form:
[<var> =] <name> <parameters> { <attributes>; }
As in the layout, <name>
is the name of a function or type, and <parameters>
is a
comma-separated list of parameters to the function or constructor. Optionally, a number of
<attributes>
may be specified. These have the form <name>: <parameters>;
where <name>
is the
name of a member in the created type, and <parameters>
are parameters to the member. If <name>
refers to a member variable, and only one parameter is provided, the member variable is assigned
instead.
The optional <var> =
allows assigning the created element to a variable in addition to adding it
to the picture. This makes it possible to reference the element later on, which is handy to position
other elements relative to the element, or to connect edges to it.
The language also contains special syntax for relative positioning. If a property is specified as
<cardinal>: <number> of <element>
, then the library will automatically set the element's position
and alignment to achieve the desired positioning. <cardinal>
can be any of the cardinal directions
in the layout library, <number>
is any number, and <element>
is either a Node
or a Point
. If
the element is a Node
, then the measurement is relative the edge at <cardinal>
to ensure that
the distance between the closest edges of the two elements two is as specified.
For example, two nodes with a connecting edge can be created as follows:
use presentation; presentation Picture "Picture" { slide content "Picture" { picture { // Create a rectangle at position 0, 0 with the size of 100, 100. a = rectangle { minSize: 100, 100; at: 0, 0; } // Create a rectangle of the same size, use the relative positioning // to place it 200 to the east of a:s east side. b = rectangle { minSize: 100, 100; east: 200 of a; } // Connect them with an edge. Will automatically pick the proper start // and end points of the rectangle. edge a, b { toArrow: FancyArrow; } } } }
As with other parts of the presentation language, all names are resolved using the normal rules for Basic Storm. As such, it is possible to create custom elements by subclassing the relevant classes. It is also possible to set default values by creating a function that creates an element, sets the defaults, and returns it. For example, a rectangle with a default size can be created as follows:
Rectangle largeRectangle() { Rectangle r; r.minSize(500, 500); r; }
This would allow using the node type largeRectangle
in the picture syntax.
Nodes
All nodes inherit from the presentation.Node
class. A node is specified in terms of a
point (at
), and an anchor (anchor
). The anchor is of the type Cardinal
, and is used to
determine what part of the node should be located at the point at
in the picture's coordinate
system.
The size of the node is specified in terms of its minimum size (minSize
) and the size of the
contained text (if any). The final size (as returned by size
) is then the maximum of the minSize
and the size of the contained text.
There are multiple ways to access the final node's position in order to easily position other
elements relative to already created nodes. For example, pos
can be used to get the final
rectangle that the node occupies. There are also functions that correspond to the cardinal
directions (i.e. center
, north
, northEast
, east
, southEast
, south
, southWest
, west
,
and northWest
) that extract that particular point of the node's rectangle. Furthermore, the member
atEdge
computes the point at the edge of the node that is at a particular angle of the node. This
is used for determining where edges start and end.
The Node
class has the following properties:
-
layout.Cardinal anchor
Anchor point.
-
core.geometry.Size margin
Margin around the text.
-
void margin(core.Float x)
Set both dimensions of the margin conveniently.
-
void margin(core.Float w, core.Float h)
Set individual horizontal and vertical margin conveniently.
-
core.geometry.Size minSize
Minimum size.
-
void minSize(core.Float w, core.Float h)
Convenient way to set minimum size from the syntax.
-
void font(ui.Font f)
Set current font.
-
void style(presentation.TextStyle t)
Set font and text brush.
-
void text(core.Str t)
Set text.
-
void text(ui.FormatStr t)
Set text.
-
layout.Cardinal textAnchor
Text alignment.
-
ui.Brush textBrush
Text color.
-
void textColor(graphics.Color c)
Set text color.
-
ui.Brush borderBrush
Border color.
-
void borderColor(graphics.Color c)
Set border color.
-
core.Maybe<ui.Brush> fillBrush
Fill color.
-
void fillColor(graphics.Color c)
Set fill color.
In terms of appearance, a simple Node
only draws the contained text. To give the node an
appearance, use any of the provided subclasses to define the geometry of the node itself. The
following nodes are available by default:
-
node
A plain node. Only draws the contained text.
-
rectangle
A node shaped like a rectangle. Draws a potentially filled rectangle with a border around it. If
rounded
is set to a nonzero value, then the corners are rounded. -
circle
A node shaped like a circle. If
allowOval
istrue
(e.g. by callingoval
), then the node may be oval. -
imageNode <bitmap>
Displays an image inside the node. The property
scale
determines the size of the image. Any text is drawn on top of the image.
Edges
An edge is a line between two points, or two nodes. The edge may optionally have arrowheads at each end. An edge may also be bent to create a round shape if desired.
Edges are created by the edge
function that accepts two parameters. These parameters may either be
points, or nodes. If they are nodes, the library will automatically determine the starting point
based on shape of the node. Since parameters may also be points, the behavior can be fine-tuned by
passing for example node.east
as an explicit starting point.
An edge has the following attributes:
-
ui.Brush brush
Brush used to draw the edge.
-
void color(graphics.Color c)
Set the color.
-
core.Float width
Line width.
-
void bendLeft()
Bend the line a bit to the left.
-
void bendLeft(core.Float amount)
Bend the line to the left. The amount is expressed as a fraction of the original line length.
-
void bendRight()
Bend the line a bit to the right.
-
void bendRight(core.Float amount)
Bend the line to the right. The amount is expressed as a fraction of the original line length.
-
void fromArrow(presentation.Arrow a)
Set the arrow tip in the "from" direction.
-
void toArrow(presentation.Arrow a)
Set the arrow tip in the "to" direction.
Arrow Tips
The following arrow tips are provided:
-
PlainArrow
- an arrow that consists of two lines. The length and angle can be specified as parameters to customize the appearance. -
TriangleArrow
- an arrow that consists of a filled triangle. Essentially a filled version ofPlainArrow
. The length and angle of the arrow can be specified as parameters. -
FancyArrow
- a fancy, filled, arrow where the side furthest from the tip bends inward. As with the two previous arrows, the angle and length can be specified as parameters to the constructor.
Paths
A path is a final type of elements that may be contained in a picture. They expose an interface
similar to the ui.Path
class in the UI
library. They are created using the name path
and
have the following attributes for creating the actual path:
-
void fill()
Fill the path?
-
void start(core.geometry.Point pt)
Start a new segment.
-
void line(core.geometry.Point to)
Add a line segment.
-
void point(core.geometry.Point to)
Add a point.
-
void bezier(core.geometry.Point c1, core.geometry.Point to)
Add a bezier segment.
-
void bezier(core.geometry.Point c1, core.geometry.Point c2, core.geometry.Point to)
Add a bezier segment.
-
void close()
Close the segment.