Using GLG drawings as widgets 7
Selecting an Object and Changing Object Geometry 9
Choosing from Several Selected Objects 9
Using Undo 10
Editing object attributes using the Edit Toolbox 12
Integrated Zooming and Panning 15
Using GLG Widgets and Palettes 16
Using GLG Graphs and other Widgets 16
Defining resources for animation 17
Prototyping Animation in the Builder 17
Creating resource hierarchies 18
Defining Tags for Global Access to Data 20
Adding a Tag to an Object Attribute 21
Mapping Tags to DataSources in the Builder 21
Mapping Tags in an Application at Run-Time 22
Prototyping a Drawing in the Builder Using Tags 22
Adding geometrical dynamics 22
Blinking 25
Editing control points and attaching control point dynamics 28
Adding Extended Rendering Attributes 29
Text Boxes 31
Editing individual objects in a group 31
Editing all objects in a group 32
Adding and Deleting objects from a group 32
Constraining object attributes 35
Using Constrained Dynamics and Marked Transformations 36
Constrained Dynamics Example 36
Using Marked Transformations 37
The Second Flavor of the Fill Dynamics 37
Loading the Drawing into a C or C++ Program 45
Loading the Drawing into a Java Program, GLG Bean or Applet 45
Loading the Drawing into an ActiveX Control 46
Supplying data for animation from a program 46
Creating a Container Object 56
Creating Container Instances 57
Editing Container's Template 57
Creating Reference Instances and Editing the Template 59
Rebinding Reference Attributes 60
Subdrawing 62
Accessing the Subdrawing's Template 64
Creating a Template with Multiple Icons 65
This tutorial presents an overview of the tasks involved in creating animated drawings using GLG and using them in a program. It is intended for users that prefer finding things by a trial and error approach rather than reading the manual. Refer to the GLG documentation for further details.
The Tutorial starts with simple animation examples and moves on to examine more complex features of the Toolkit (constraints, etc.). You won't need these advanced features for your first animations, but you may need them later on as you develop more elaborate drawings.
A GLG drawing is a collection of objects created and saved using the GLG Builder . This drawing can be loaded into a C/C++ , Java or ActiveX program and animated with the data supplied by a program. A drawing used in a program is referred to as the Widget throughout this document.
Any GLG drawing must use a GLG viewport object to contain the drawing's graphical objects. A viewport is an encapsulation of the native window object that is used in the Toolkit to contain graphical objects (polygons, circles, etc.) and to provide a drawing surface for them. A viewport may also contain other nested viewports.
To use a drawing as a widget in a program, the drawing must have a viewport named "$Widget" . This viewport will be displayed in a program when the drawing is used as a widget. A drawing created and saved using the GLG Builder can then be used as a widget in a C/C++ or Java program, Java bean or applet or ActiveX control.
When the GLG Builder is first started, it automatically creates a new widget (a viewport named "$Widget" ) and moves the editing focus into it.
To see the widget, use the
Hierarchy Up
button
from the
Control Panel
on the left or
Traverse, Hierarchy Up
from the main menu, and that will bring you up to the top level. You'll see the outline of the viewport object and a text comment at the top of the drawing.
To go back into the widget, first select the viewport by clicking on it with the left mouse button. This will show control points in two corners and the center of the viewport, and also will show the viewport's name and object type in the
Status Panel
at the bottom. With the viewport selected, use the
Hierarchy Down
button from the
Control Panel
or
Traverse, Hierarchy Down
from the main menu: this will bring you down into the viewport, so you can start creating objects.
The Builder's New menu also provides two options for creating new widgets: Widget and
Widget (No Stretch/Resize). The first option creates a resizable widget that stretches or changes the size of objects in the drawing accordingly when the widget is resized. The second option creates a widget that does not stretch or resize the objects in the drawing, but shows a smaller or bigger part of the drawing area when the widget is resized.
The widget created by default on the Builder startup is resizable.
You can create graphical objects by selecting from a variety of drawing primitives in the Object Palette on the left of the Drawing Area:
All buttons in the Builder have tooltips, so you can move the mouse over the button to find it's exact meaning if not sure.
To create an object, select one of the drawing primitives on the left (a
Filled Polygon
, for example) and click several times in the drawing to define the polygon's points. To finish defining points, click the right mouse button on Windows, the middle mouse button on Unix, or the
Escape
key on both platforms.
For different objects, a different number of control points may be required. For example, an arc will require 3 control points.
Some object may also require entering additional information. For example, you'll be asked to type a text string when creating a text object.
When objects are being created or any other actions requiring user input are performed, a prompt with additional instructions is displayed in the Prompt Area at the bottom.
All objects have to be created inside the widget ( "$Widget" viewport).
After creating an object, it may be edited in a variety of ways. To edit an object, it has to be selected.
The simplest way to select an object is to click on it with the left mouse button. When an object is selected, its control points and resize box are highlighted in the drawing, and its name and type are displayed in the Status Panel at the bottom.
The move point appears at the object's center, it's a dynamically calculated point, provided for convenience in the Builder only. You can reposition an object precisely by Shift+clicking on the move point, and using the arrows in the Object Move Point dialog. To avoid accidental movement while you are selecting an object, use Shift+click to select the object. For less precise movements, just drag the object with the mouse.
An 8-point resize box appears around an object. Use its points to resize the object. You can also flip the object by dragging any of the resize points to the other side of the object's box. Objects with only one control point (marker, fixed text, etc.) can't be resized, and resize points for these objects appear desensitized (in a gray color).
A rotate point appears on the right side on the resize box. To rotate an object precisely by a specified angle, Shift+click on the rotate point and use the arrows in the Object Rotation Point dialog. For quicker or less precise rotation, drag the rotate point with the mouse.
Control points appear at the vertices or other important points. To change the shape of the object, drag its control points with the mouse. You can also edit a control point precisely by Shift+clicking on it and either using the arrows to move the point, or entering the point's coordinates into the Value field of the Control Point dialog.
To select an object with no fill (for example, an unfilled polygon), click on the object's edge. The FillType attribute controls this aspect of an object's appearance.
When several objects are located close to each other and it is difficult to select the object of your choice, you can use the Shift key to help choose among several objects.
Shift-clicking in the drawing area with the left mouse button pops up a menu that allows you to select an object out of several potentially selected objects.
If the Properties dialog is open, the arrow button in the upper right corner of the dialog may be used to select an object when several objects are potentially selected as well.
The changes applied to the object's geometry or attributes may be reverted by selecting Edit, Undo options from the main menu, where the last operation is displayed at the top of the menu. For example, try moving an object with the mouse. To undo the move operation, select Edit, Undo Object Move or Stretch.
For multiple step undo, Edit, Undo History option may be used. For example, try resizing the object using its resize box and then click and drag one of its control points with the mouse. To reverse one or both of these operations, select Edit, Undo History, Undo Point Move to undo the point move operation, and then select Edit, Undo History, Undo Object Move or Stretch to undo the resize operation. Notice that the Undo History list displays performed operations in the reverse order, so that the last operation appears at the top of the list.
Note: The order of undo steps is important and should be considered when undoing a complex sequence of editing operations.
You can use the
Properties
toolbar button to bring up the
Selected Object Properties
dialog. Alternatively, you can use the right mouse button and select
Properties
from a popup menu, or
Object
,
Properties
from the main menu.
The Selected Object Properties dialog allows you to edit an object's properties. Some generic properties common for all objects ( Name, Visibility, HasResources flag ) are displayed at the top of the dialog. Specific properties that depend on the type of the selected object are listed below.
Some properties, for example a
FillColor
property, have an ellipses button
next to it. The button indicates that the attribute is an object, and you can press it to get the dialog with a color palette and other options for editing the attribute.
You can select a new fill color from a palette, or give this attribute a specific name that you can later use to access the attribute from a program.
For other attributes, different attribute-related pallets will be shown: try selecting the ellipsis button
for the
LineWidth
and
LineType
attributes.
The Type field of the Attribute Object dialog shows the type of the attribute object and may be D for double numerical values, S for string values or G (geometrical) for XYZ or RGB triples used to represent colors and control points in the Toolkit.
For faster editing of common object attributes, the
Edit Toolbox
can be used, alternatively to the
Properties
dialog. Click on the Edit Toolbox
toolbar button to bring the
Edit Toolbox
for the selected polygon object.
You can edit various attributes, such as FillColor or LineWidth. For example, click on the LineWidth button and select a new line width from the line width palette displayed in the middle of the dialog. As the polygon's line width changes, notice that the text box value at the bottom of the dialog reflects the current setting for the selected attribute.
Only the attribute buttons that are applicable to the selected object type are activated in the Edit Toolbox , while the other buttons are disabled. For example, for the polygon object, the FillColor and EdgeColor buttons are activated, while the TextColor buttons are disabled.
While Properties dialog provides access to all attributes that are available for the selected object, the Edit Toolbox displays attributes that are commonly used for a given object type. For example, for a polygon object, you can edit such attributes as FillColor or EdgeColor via the Edit Toolbox , however, the OpenType attribute is accessible only via the Properties dialog. Likewise, the GradientType attribute can be accessed only through the Properties dialog, while the value of GradientColor attribute can be edited using the Edit Toolbox. The Edit Toolbox is convenient for a quick and easy editing of the visual appearance of objects, as well as editing multiple objects or all objects in a group. For editing the non-visual entities, such as attribute names, HasResources flag and others, the Properties dialog should be used.
Create three polygon objects using the
Filled Polygon
button. To select multiple objects for editing, click and drag a rectangle to enclose the objects you want to edit. For example, click and drag a rectangle to include all three polygons. This creates a temporary group that includes all selected objects.
Notice that the Status panel at the bottom of the Builder's window indicates that the selected object is of type Group and its name is $TempGroup , which is a predefined name for a temporary group. The resize box of a temporary group is shown as a dashed line. Temporary group is volatile and will be discarded when it is unselected.
To exclude or include an object from the group, you can Ctrl+click on the object you want to delete or add. For example, Ctrl+click on one of the polygons to delete it from the group. Ctrl+click on the same polygon again to add it back to the group.
Let's try to change
FillColor
of all three polygons. Click on the Edit Toolbox
toolbar button to bring the
Edit Toolbox
for the selected objects. Click on the
FillColor
button in the
Edit Toolbox
and select a new color in the color palette. All selected objects will reflect the color change.
Press Escape to unselect the objects.
In the above example, a temporary group was created using a click and drag operation that defined a rectangular area containing the objects to be selected. This option may be inconvenient in some cases, when there are several intersecting objects and precise object selection is required. Alternatively, a temporary group may be created by Ctrl+clicking on each object that needs to be selected.
For example, Ctrl+click on one of the polygons with the left mouse button to select it. Ctrl+click on another polygon, and then on the third one. All three polygons will be selected. Attribute editing of all selected objects can be done using the Edit Toolbox , as described earlier.
In GLG, the polygon is a fundamental graphical primitive. Most other GLG graphical objects (arcs, connectors, splines, etc.) inherit their attributes from the polygon object. As an example, let's try editing attributes of a filled polygon.
Click on one of the previously created polygon objects to select it, then click on the
Properties
toolbar button to display the polygon's Properties dialog for it.
Click the ellipsis button
for the
FillColor attribute and select the fill color from a color palette, then select the edge color using the same procedure for the EdgeColor attribute. The colors may also be entered as RGB values in the range of 0 to 1 by typing them into the corresponding value fields of the Properties dialog.
The LineWidth attribute may be entered by typing the pixel line width value into the LineWidth text box. To select a line width from a palette, click on the ellipsis button
for the
LineWidth attribute and select a line width from a palette. To select a line type from a palette,
click on the ellipsis button
for the
LineType attribute.
The FillType attribute controls whether the polygon is drawn as an outline, fill or both. The attribute has an option menu that allows selecting the fill type. The ellipsis button
for the attribute may also be used to pop up the Attribute Object dialog which allows naming the attribute, setting its flags and attaching attribute dynamics.
The OpenType attribute controls whether the polygon draws the line connecting the first and last polygon's points, and may be edited in the same way as the FillType.
The Builder's Object Palette has convenience icons for creating both filled, unfilled, open and closed polygons. However, the FillType and OpenType attributes may be changed after the polygon was created as well.
The Shading attribute provides a way to selectively disable 3D shading of the polygon when it is displayed in a viewport with the shading enabled (Light attribute set to FLAT). This attribute is not an object, so there is no ellipsis button for this attribute. The only available attribute action is changing its value using the option menu.
The PointList item in the polygon properties is enabled in the Enterprise Edition of the Builder and allows adding, deleting and rearranging the order of the polygon points after the polygon has been created. Pressing the ellipsis button
for the PointList displays the list of the polygon's points, with buttons for adding, deleting and rearranging the points' order. Selecting a point in the list with the mouse displays the Control Point dialog for editing the point's value, name and flags.
The last item in the property list allows adding and editing optional rendering attributes, such as gradient fill, cast shadows, arrowheads and fill dynamics. Refer to Adding Extended Rendering Attributes on page 29 for details.
A viewport object is a GLG encapsulation of a window, which may be used to draw other graphical objects. In addition, the viewport object provides its own coordinate system, resizing all objects in the viewport when the viewport is resized. The viewport may be used as a container holding functionally different parts of the drawing, or as a component containing other graphical objects (a graph, control, etc.). Viewports may be used recursively, with one viewport containing a hierarchy of several nested viewports, each containing its own drawing.
To create a viewport, select the Viewport
icon from the drawing primitives, then click twice in the drawing area to define the position of the viewport's corners. After the viewport was created and selected, use the
Hierarchy Down
button from the
Control Panel
or
Traverse, Hierarchy Down
from the main menu to go "down" into the viewport. You can add any objects to the viewport by creating them while being inside the viewport, then use the
Hierarchy Up
button from the
Control Panel
or
Traverse, Hierarchy Up
from the main menu to go back up to the previous level.
The viewport has its own coordinate system with the origin at the center of the viewport and the Z axis perpendicular to the plane of the viewport's rectangle. The corners of the viewport are [-1000,-1000] and [1000, 1000] in the viewport's coordinate system, and this mapping is maintained when the viewport is resized. The viewport's coordinate system is used to interpret the coordinates of any objects drawn in the viewport. When the viewport is resized, all objects within are resized as well.
Panning and zooming affects the mapping of the viewport's coordinate system. For example, if the viewport is zoomed in to by a factor of 2, the corners of the viewport will correspond to (-500 -500) and (500 500) instead of (-1000 -1000) and (1000 1000) without zooming. The screen object associated with each viewport has additional SpanX and SpanY attributes that control the viewport's coordinate extent and coordinate mapping. Refer to Screen on page 63 of the GLG User's Guide and Builder Reference Manual for details.
Setting the editing focus provides a convenient shortcut for quick access to objects inside the viewport without traversing down the hierarchy. To move the focus inside the viewport, click on the Set Focus
button from the
Control Panel and click on the viewport
, or simply Ctrl-Shift-click on the viewport. The viewport will be highlighted with thick borders to show it has the editing focus, and you can edit, add or delete objects inside the viewport (Note: The Hierarchy Down button is disabled while the focus is inside the viewport). When finished, click on the Main Focus
button in the Control Panel, or Ctrl-Shift-click outside the viewport to return the focus to the main drawing area.
Note: Set Focus should only be used for quick access to viewport's objects for minor editing. Use Hierarchy Down as the primary way to access objects inside the viewport.
The viewport's FillColor, EdgeColor and LineWidth attributes control the background color, border color and border width of the viewport. The viewport's screen
ShadowWidth
attribute controls drawing the shadowed bevels around the viewport's borders. The sign of the ShadowWidth controls the type of the bevels: raised shadows for positive values and depressed shadows for negative values. To gain access to the ShadowWidth attribute, display the viewport's Properties dialog, then press the ellipsis button
next to the More label.
In the Builder, the vertical and horizontal scrollbars on the sides of the Drawing Area can be used to scroll the drawing. The drawing can also be scrolled by clicking and dragging it with the mouse. To start dragging, the click should happen in an empty area of the drawing. If the whole drawing is completely occupied by objects, the dragging may be started by selecting the Scroll by Dragging option of the View menu, then clicking anywhere in the drawing and dragging the mouse.
If the drawing needs to be scrolled at run time, the integrated zooming and panning features of a viewport object can be used. Every viewport supports integrated scrollbars for automatic panning that are controlled by the viewport's Pan attribute. To enable the scrollbars for a viewport, set its Pan attribute to Pan XY using the Properties dialog. The scrollbars allow the user to scroll the drawing at run time when it extends beyond the boundaries of the viewport's visible area. The scrollbars may be enabled for any viewport object that requires them. If required, only one of the scrollbars can be enabled by selecting the Pan X or Pan Y setting of the Pan attribute.
If the viewport's ZoomEnabled attribute is set to YES, the viewport object also handles zoom and pan accelerators. For example, "i" will zoom into the viewport, "o" will zoom out and "n" will reset zooming and panning. Scrolling the drawing with the mouse using the Ctrl-drag sequence is also supported. Refer to Viewport on page 58 of the GLG User's Guide and Builder Reference Manual for a complete list of zoom and pan accelerators. If ZoomEnabled is set to NO, the accelerator keys are disabled, but the integrated zooming and panning is still available for use programmatically.
To try integrated zooming and panning, draw a few objects inside of a viewport with panning enabled, then start the prototyping mode by pressing the
Start
toolbar button or selecting Run, Start from the main menu and entering an empty run command. Click on the viewport with the mouse to move the keyboard focus to the viewport, then press "i" several times until the objects displayed in the viewport extend beyond the visible area of the viewport's window. Use scrollbars or the Ctrl-drag sequence to pan, then press "n" to reset zooming and panning, and press the Stop
toolbar button to return to the edit mode.
Refer to Integrated Zooming and Panning on page 103 of the GLG User's Guide and Builder Reference Manual for details.
The Palettes menu provides access to palettes of pre-built widgets and objects. You can use these objects by simply dragging them from the palette and dropping them in the drawing. The objects have built-in dynamics and resources to control their appearance. By default, only the Custom Objects palette is installed. Other palettes are optional and will be installed only if purchased. Possible palettes include 2D graphs, 3D graphs, controls, process control and special widgets palettes. You can find a Widget Catalog with images of all available palettes and widgets on GLG 's web site www.genlogic.com .
The Palette menu lists all available palettes of pre-built objects. To display a Custom Objects palette, select it from the palettes list. To add an object from a palette into the drawing, click on its icon in the palette. For example, click on the Bar Graph in the Custom Objects palette to insert a copy of the graph in the drawing. Give the graph a name for accessing its resources and adjust its shape using the resize box.
If the Builder was just started (or after File, New, Widget), the editing focus is inside the $Widget viewport and the graph will be placed inside the $Widget viewport. This is convenient when you want to create a drawing containing several widgets, for example a panel of several graphs or dials. Each instance of the widget has to be given a unique name to avoid name conflicts.
If you want to create a drawing with only one widget in it, you don't need the additional $Widget viewport: you can use the widget itself and name its viewport $Widget. In this case, you may want to start by selecting File, New (instead of File, New, Widget), place a single widget in the drawing, name it "$Widget" and save the drawing.
You can also use the widget files exactly as they are, loading them in the Builder, editing resources and saving them as custom drawings. The Builder provides a convenient shortcut for loading widget files from the palettes. Simply press the Ctrl key down while selecting a widget from the palette, the content of the drawing will be discarded and the selected widget file will be loaded. This will also set up the correct animation command to animate the widget (see Prototyping Animation in the Builder on page 17).
To save the drawing, use either the
Save
toolbar button or
File, Save
from the main menu.
The Options menu contains settings that control how the drawing is saved. The default ASCII save format enables the drawing to be displayed on different hardware platforms and in the Java version of the Toolkit. The default Save Compressed option minimizes the size of the drawing. Disable the drawing compression if the drawing is used for code generation.
Defining resources for animation is as simple as naming the objects. For example, name the polygon you created
"Poly1"
by entering the name into the
Properties
dialog, then select the ellipsis button
next to its
LineWidth
attribute and name the attribute
"Width1"
.
Select
All Resources
from either the toolbar, popup menu or
Object
menu to bring up the
Resource Browser
dialog showing all resources of the drawing. The dialog will show the
"Poly1"
and
"Width1"
resources we just created.
Select the "Width1" resource by double-clicking on it and try changing the resource by selecting a new line width from the Line Width palette.
Double-clicking on the "Poly1" will show the default resources of a polygon, such as Fill Color, Edge Color, Line Width , etc. You can double-click on any of these resources to edit them.
All these resource names can later be used to animate the drawing in the program or on a Web page.
You can animate any named resources right in the editor by selecting
Start
from the toolbar or
Run, Start
from the main menu. If you were inside the widget, running will bring you back to the top level.
You'll have to supply an animation script to specify what resource you want to animate. For example, you may use the line:
$datagen -sin d 1 50 $Widget/Width1to animate the "Width1" resource of the polygon we named earlier, where:
$datagen is the name of the Builder's data generator,
-sin parameter selects a sinusoidal waive to be used for animation ( -lin is another alternative for incrementing the value linearly),
d specifies a data type for animation (d for double, s for string or G for geometrical),
1 50 parameters supply the range for generated data values.
$Widget/Width1 specifies a resource name to animate. The "$Widget" prefix is used since the polygon is inside the widget. Refer to the next chapter for more details on defining resource hierarchies.
Quit the prototyping mode by using the
Stop
toolbar button or
Run, Stop
from the main menu.
You can also animate any default resource of the "Poly1" polygon using one of the following scripts:
To animate the polygon's fill color with random RGB values (RGB range is from 0 to 1):
$datagen g 0 1 $Widget/Poly1/FillColorTo animate the polygon's fill color with a smoothly changing gray color:
$datagen -sin g 0 1 $Widget/Poly1/FillColorTo animate polygon's line width using a default name of the width attribute:
$datagen -sin d 0 50 $Widget/Poly1/LineWidthTo animate polygon's line width using a linear increment:
$datagen -lin d 0 50 $Widget/Poly1/LineWidthYou can also animate several resources at a time with the following script:
$datagen g 0 1 $Widget/Poly1/FillColorRefer to the Data Generator Reference Manual for more details of animation script parameters and on saving an animation script in a file.
As you recall, both "Poly1" and "Width1" resources were displayed on the same level in the Resource Browser , even though logically the width resource belongs to the polygon. This section will explain how to change this to arrange the resource hierarchy in which the "Width1" resource belongs to the "Poly1" resource.
Bring up the
Resource Browser
again by using
All Resources
toolbar button. Since you are at the top level, you'll have to double-click on
"$Widget"
to see the resources inside it. The
"Poly1"
and
"Width1"
resources are displayed at the same level of hierarchy.
Select the widget viewport and go down into it. Select the "Poly1" polygon and bring up the Properties dialog.
Set the polygon's HasResources flag to YES . This defines a resource hierarchy, and now the "Width1" resource will now appear under the "Poly1" in the Resource Browser . The default value of the HasResources property was NO , that means that the object is resource-transparent.
Bring up the Resource Browser. You'll see "Poly1" but not "Width1" . Double-click on "Poly1" to see the resources inside it, and you'll now see "Width1" as one of the resources of the "Poly1" polygon.
Note: Default attributes of the object always appear under the object in the resource hierarchy, even if HasResources flag is set to NO .
Create a copy of a polygon by using Edit, Full Clone from the main menu or pressing Control+L accelerator key to create a copy of the polygon. Name the copy "Poly2" . Move the copy further away from the first polygon.
Bring up the Resource Browser and open "Poly1" by double-clicking on it to see its resources. Then double-click on ".." to return back, and open "Poly2" . You can see that both "Poly1" and "Poly2" have their own "Width1" resources. You can now edit the "Width1" resource of each polygon individually and use "Poly1/Width1" or "Poly2/Width1" resource names to access the line width of one polygon or another.
Try prototyping using the following animation script:
$datagen -sin d 1 50 $Widget/Poly1/Width1to animate the first polygon and:
$datagen -sin d 1 50 $Widget/Poly2/Width1script to animate the second one.
The resource hierarchies are a convenient way to define collections of objects. You can copy or instantiate objects several times using different names and access the attributes or dynamics properties of each instance by simply using a different top level name without changing the resource hierarchy inside an object. The following three lines show an example of accessing the "Valve/Open" resource of three different instances of an object:
Since the resource hierarchy inside each instance is identical, a function may be used to set the valve open for any of the instances:
// assembly_name may be "Assembly0", "Assembly1", etc. void SetValveOpen( GlgObject drawing, char * assembly_name, double open_value ) { char * res_name = GlgConcatResNames( assembly_name, "Valve/Open" ); GlgSetDResource( drawing, res_name, open_value ); GlgFree( res_name ); }or, if the Extended API is used:
void SetValveOpen( GlgObject drawing, char * assembly_name, double open_value ) { GlgObject assembly; assembly = GlgGetResourceObject( drawing, assembly_name ); GlgSetDResource( assembly, "Valve/Open", open_value ); }Objects in the drawing may be animated by accessing their attributes using one of the following access methods: using the attribute's resource name or using a tag attached to the attribute. While resources are hierarchical, tags are global and provide a way to access attributes using a flat structure. The use of tags shields an application from the necessity to be aware of the resource hierarchy of the drawing, which is convenient for process control applications that view a drawing as a collection of data sources that need to be updated with real-time process data.
A tag is added to an attribute in a form of a tag object which has several attributes of its own: TagName, TagSource and TagComment.
TagName is a string attribute that assigns a meaningful name to a tag to identify the tag in an application and assist the user in mapping the tags to data sources using a Tag Browser. TagName is persistent and does not change when the tag's data source is modified.
TagSource is a string attribute that defines a source of run-time data used to dynamically change the value of the attribute the tag is attached to. For example, TagSource may specify a name of a field in the process database used to supply real-time data for animating the attribute. Any attribute with a tag attached may be accessed by the tag's TagSource via the tag-based data access mechanism.
The TagComment attribute is a string that may be used to store any additional user-defined information associated with the tag.
Tags simplify data connectivity by providing a mapping between the dynamic attributes and data sources used to animate the drawing. The tag's TagSource attribute specifies the source of dynamic data for each attribute. When an application receives a data change event for a particular field, it can update the corresponding tag using the GLG API.
In the Builder, the user can browse tags using the Tag Browser, which display a list of all tags defined either in the drawing or in the selected object. To change the database mapping, the user can browse tags, select the tag whose database connection needs to be changed and edit its TagSource.
Let's modify our drawing so that it can be animated from a " LWValue " datasource variable using a tag with the same TagSource.
Select the "
Poly1
" object you created. Bring its Properties dialog and click on the ellipsis button
next to the
LineWidth
attribute. As indicated in the Attribute Object dialog, the
LineWidth
attribute is named "
Width1
", making "
Width1
" a resource of the
Poly1
object.
Add a tag to the LineWidth property by clicking on the Add Tag button. Type " LineWidthAnimation " in the TagName field as a tag description, then enter "LWValue" in the TagSource field.
Close the Tag Object dialog by clicking on the OK button.
The Edit Tag button next to the Tag field provides access to editing the tag object. The tag information in the Tag field shows both the tag's TagName and TagSource separated by the `=' character.
As shown in the Attribute Object dialog, the LineWidth attribute of the Poly1 object has both a resource name, " Width1 ", as well as a tag source, " LWValue ". This enables an application to access the LineWidth attribute using one of the following methods:
using resource name Poly1/Width1
using default resource name Poly1/LineWidth
Notice that LWValue is a global name. The application doesn't need to know which object or attribute it is connected to.
Each time an application receives a data change event from the LWValue datasource (which can be a LWValue variable in a process database), all it need to do to animate the drawing is to push a new data value into the LWValue tag using the GlgSetDTag API method.
To view all tags defined in the
Poly1
object, select it and click on the
Tags
toolbar button. All the object's tags will be displayed, showing the TagName and TagSource attributes of each tag.
Select LWValue from the list of tags to popup the Tag dialog. The Attribute Object dialog will also appear, indicating what resource is associated with the selected tag. In this case, it is Width1 resource.
The datasource associated with the tag may be changed by editing the TagSource attribute. TagName provides a persistent name that identifies the tag regardless of the changes to its TagSource attribute.
Often times, defining tag sources manually is not convenient, and a user wants to be able to browse available variable names from a custom data source and select an appropriate variable name for a tag source. For that purpose, the Browse button is provided next to the TagSource field of the Tag dialog.
Click on the Browse button next to TagSource field. A data browser comes up with a list of available tag sources. This list is populated by a custom data DLL, glg_custom_data.dll , which is found in the same directory as the GlgBuilder executable (on Unix/Linux platforms, it is a shared library called libglg_custom_data.so). Select one of the fields from a list of available tag sources, for example " controller1/group11/tag111 ". This tag source gets assigned to the tag. Change the tag source back to LWValue to continue with the rest of this example.
A sample of a custom data browser DLL is provided with the release, including the source code. A user can use the source code as a template for writing a custom DLL which will connect to the application's data sources using a custom data acquisition system and return a list of available variable names. The returned list of names is used by the Builder to populate the Data Browser dialog with names of available custom data source variables to be assigned to a tag source.
To view a list of all tags defined in the drawing, close the Tag Browser, unselect the object by pressing the
Escape
button and click on the
Tags
toolbar button again. The Tag Browser will show all tags defined in the drawing. You can also select the
$Widget
viewport to see all tags defined in the widget.
An application can also map tags to datasources at run-time using the GLG API. An application can use the GlgGetTagList method to obtain a list of tags defined in the drawing, traverse the list and remap each tag in the list by changing its TagSource attribute. The TagName attribute of each tag may be used by an application to identify the tag.
In the previous section, the LineWidth attribute was animated using the resource name Width1 . Alternatively, the LineWidth attribute of the polygon Poly1 can be animated using an assigned tag source, LWValue .
Select the
Start
toolbar button and supply the following animation command:
Please notice that since tags are global, the tag names do not have a hierarchy related to a resource structure in the drawing, like the $Widget/Width1 resource path we used to animate the polygon's LineWidth using resources.
You can add 2D and 3D dynamic behavior by adding dynamics to objects. The available geometrical dynamics include rotate, scale, move, path and other types of dynamics.
Let's add rotation dynamics to the
"Poly1"
polygon. Select the
"Poly1"
polygon and use
Add Dynamics
from the toolbar, popup menu or
Object
menu to bring up the
Add Dynamics
dialog.
Select the Rotate transformation type at the top of the Add Dynamics dialog, and select the Z rotation axis to rotate in 2D:
You can either enter the rotation angle in degrees, or define it by selecting Angle In Drawing and selecting two points anywhere in the Drawing Area. Try entering 180 as the angle value.
You can also change the center of rotation from its default position by either entering its new coordinates (in the range -1000 to 1000) or selecting the Center In Drawing button and clicking in the drawing with the mouse to define a new position.
Type "RotateVar" as the Variable Name and click on Apply . This will attach the dynamics to the object and will bring up the Edit Dynamics dialog that shows dynamics attached to the object. The dialog also shows the resource names assigned to the dynamics' parameters that will later be used to animate or change them: notice that "RotateVar" is used as a resource name of the dynamics' controlling factor .
Prototype the dynamics (
Start
icon from the toolbar) with the following animation script:
that will change the "RotateVar" parameter from 0 to 1, causing the object to do a 180 degree rotation defined by the Angle parameter. Also notice the use of the resource hierarchy since "Poly1" has the HasResources set to YES.
Stop the animation (
Stop
toolbar button), go down into the widget viewport and select the
"Poly1"
object. Activate the
Edit Dynamics
dialog by selecting
Edit Dynamics
from the toolbar (you can also select Dynamics
Edit
from the bottom of the
Properties
dialog, or use the
Edit Dynamics
button from the Object or popup menu).
The
Edit Dynamics
dialog shows the number and types of dynamics attached to an object (any number of dynamics may be attached), as well as parameters of the selected dynamic transformation. You can edit the dynamics' parameters after it has been created by either entering numerical values or selecting the ellipsis button
next to the parameter for more options.
For the rotate transformation, either the Angle or the controlling Factor parameter may be changed. The controlling factor is a normalized value in the range from 0 to 1. The actual rotation angle displayed in the drawing is calculated as multiplication of the Angle and Factor parameters. Therefore, there are two ways of animating the rotation dynamics.
1. You can set the Angle to the actual value and animate the controlling Factor in the range from 0 to 1 to rotate the object by the defined angle.
2. You can set the Factor to 1 and animate the Angle parameter by setting it to the actual desired angle of rotation.
While animating the Angle is specific to the Rotate dynamics, animating the controlling Factor may be used as a universal way to animate geometrical dynamics of any type.
If the object is moved, the rotation center does not move with the object, resulting in the object still rotating around the old center position. It's not a desired behavior when you want an object to rotate around it's corner, for example. In this case, select an object and place it into a container by using the
Container
icon from the
Object Palette
. This will create a container and place the object into it. The container preserves the object's coordinate system when the container is moved, so that the object will still rotate around its corner.
In addition to setting attribute values directly as it was done in earlier examples, you can also add attribute dynamics to the attribute object in a way similar to adding geometrical dynamics to objects. The types of dynamics differ for different attributes and some of them are described below. Refer to the GLG documentation for the complete list of available attribute dynamics.
In addition to setting the RGB value of objects' color attributes using the resource mechanism, color dynamics may be used to allow selecting a color from a list of colors.
Go down into the widget's viewport, select the
"Poly1"
polygon and bring up the
Properties
dialog. Select the ellipsis button
next to the
Fill Color
attribute to activate the
Attribute Object
dialog.
Select the Dynamics Add button at the bottom of this Attribute Object dialog. This will display the list of available dynamics on the right of the dialog. Select the List dynamics button, which attaches a list of color values to the attribute and brings the Edit Dynamics dialog showing the List dynamics attached to the Fill Color attribute object.
The Edit Dynamics dialog may later be invoked by selecting the Dynamic Edit button from the Attribute Object dialog.
Enter "ColorIndex" as a name for the dynamics' Value Index parameter in the right-most field. This resource name will be used to change the color displayed. The value of 0 will display the first color, the value of 1 will display the second color, and so on.
Select the ellipsis button
next to the
List of Values
to display the list of colors. Select the first item in the list and define it's color by selecting a color from the palette, then select the second item and define its color as well.
Click on the Add button at the bottom of the List dialog to add the third color value and define its color.
Try changing the value of the Value Index parameter from 0 to 1 and 2 and notice the colors changing according to the colors in the list.
Animate the drawing with the following script:
$datagen -sleep 0.2 d 0 3 $Widget/Poly1/ColorIndexwhere -sleep 0.2 is used to slow down the animation by pausing for 0.2 sec. after each update.
Note: the color of the attribute itself is added to the color from the list, so the attribute value is set to black (RGB value of [0,0,0]) when the list dynamics is applied to avoid interference.
GLG objects may have a blinking or simple animation functionality added in the GLG Builder, so that the "blinking effect" or animation is incorporated into the drawing and achieved with no programming.
It is accomplished by adding a timer transformation to an object's attribute which needs to be animated. To achieve blinking effect, the value of the attribute needs to be toggled between two values representing the OFF and ON state. Timer transformation can be added only to an attribute of a D type. For example, it may be attached to object's Visibility attribute to toggle the object's visibility on and off. To implement color blinking, the timer transformation can be attached to the ValueIndex attribute of the color list transformation attached to an object's color.
Let's add timer transformation to the ColorIndex attribute of the Poly1 object.
Go down into the widget's viewport, select the "
Poly1
" polygon and bring its
Properties
dialog. Click in the ellipsis button
next to the
FillColor
attribute. In the
Attribute Object
dialog, select the
Dynamics Edit
button. This will bring a dialog for editing the
List
transformation attached to the polygon's
FillColor
. Click on the ellipsis button
next to the
ValueIndex
attribute (which is named
ColorIndex
).
In the Attribute Object dialog of the ColorIndex attribute, select the Dynamics Add button and select Timer . This will add a Timer transformation to the attribute and pop up a dialog for editing the transformation's attributes.
To alternate between 3 colors of the color list transformation, set the Period attribute to 3. Name the Interval attribute " TimeInterval " and set its value to 0.5 (time interval is defined in seconds). Set MaxValue to 2, since we want the ColorIndex attribute to alternate between values 0, 1 and 2.
Name the Enabled attribute " AlarmEnabled ", so that it can be accessed as a resource if needed. When the attribute is set to 1, the timer will go off automatically with a specified timer interval, and the object will "blink" at run time with no programming involved. The blinking effect will be achieved by alternating between 3 colors in this case (to alternate between two colors, set Period =2 and MaxValue =1). To turn off the timer, the AlarmEnabled resource may be set 0.
Let's animate the drawing by clicking on the
Start
toolbar button. Erase the animation command, since no resources need to be animated (the timer goes off automatically), and click
OK
. The polygon will change its color every 0.5 seconds to indicate an alarm state.
Blinking effect also may be achieved by adding a Timer transformation to the Visibility attribute of an object. As an example, let's use a text object and add blinking functionality to it by toggling its visibility.
Create a fixed text object by clicking on the
Fixed Text
button in the
Object Palette
. Click in the drawing to define its anchor point and enter the string to be displayed, for example "ALARM", then click on
OK
to finish.
Bring the Properties dialog for the text object. Name the object " Label" and set HasResources =YES.
Click on the ellipsis button
next to the
Visibility
attribute to pop up its
Attribute Object
dialog. Click on the
Add Dynamics
button and select
Timer
transformation.
When the timer is disabled, the value of the text object's Visibility attribute will be set to the timer's MinValue attribute. To make text object visible when the timer is disabled, set MinValue =1 and MaxValue =0.
Set the timer's Interval attribute to 0.3 to define 0.3 sec. time interval. Name the Enabled attribute " AlarmEnabled ". When it is set to 1, the timer will go off and the text will blink. The Label/AlarmEnabled resource can be set programmatically to enable or disable text object's blinking.
Let's animate the drawing again by clicking on the
Start
toolbar button. A polygon object will blink by alternating its color, and the text object will blink by alternating its visibility. Quit the prototype.
The timer transformation may also be used to animate attributes of objects or object's transformations. For example, a timer transformation may be connected to an angle attribute of the rotate transformation to continuously rotate the object the transformation is attached to.
The simplest way to implement text dynamics is by setting the string attribute of the text object directly from a program. If a numerical or formatted value has to be displayed, GLG also provides a way to format the numerical value right in the drawing instead of coding it in the program.
This type of dynamics is used to display formatted numbers. Let's create a text object to exercise this type of dynamics. We'll use the Fixed Text in this section, but the dynamics may be applied to any type of a GLG text object.
Go down inside the widget viewport. Select
Fixed Text
from the
Object Palette
, click in the drawing to define text's position and enter the text string. Bring up the
Properties
dialog and select the ellipsis button
next to the
Text String
attribute to bring up the
Attribute Object
dialog for the string attribute.
Select the Dynamics Add button from the Attribute Object dialog to list the available text dynamics and click on the FormatD button to add numerical format dynamics. This will activate the Edit Dynamics dialog, showing the format dynamics attached to the text object's String attribute.
Name the Data parameter "Value1" by entering the name in the right-most field. This resource name may now be used to supply data for display. Try entering a different numerical value for the Data parameter and see how it changes in the drawing.
The Format parameter is a C language double format specification used to format the output. It must use some form of the "%lf" C format for double values. The number after the decimal point defines the number of digits after the decimal point displayed in the output. You may also add other format symbols, for example try changing format to read "Value1 = %.3lf" .
The FormatS dynamics is similar to the numerical text dynamics described above. The only differences are that the Data parameter is a string instead of a double numerical value, and the format uses the " %s" C format specification to format the output.
As an example, try attaching a formatted text dynamics to the Text String attribute of another text object and name it's Data parameter "string1" . Use "string1 = %s" as the format and "Hello, world!" as the value of the Data attribute.
The list dynamics used above for colors may also be applied to the String attribute of the text object. In this case the list will contain strings to be displayed, and the Value Index parameter of the list dynamics will control which string is displayed.
The Range transformation may be used to change the range of an object attribute or dynamics' parameter to adjust to the range of a variable used in a program. For example, it may be used to change the range of the controlling variable of the rotate dynamics attached to the "Poly1" polygon created earlier.
Let's try changing the range so that the object rotates by an angle defined by the dynamics' Angle parameter when the Factor parameter changes from 5 to 10 instead of from 0 to 1.
Go down inside the widget viewport. Select the
"Poly1"
object, bring up the
Edit Dynamics
dialog (use the
Edit Dynamics
toolbar button), make sure the
Rotate
dynamics is selected and click on the ellipsis button
next to the
Factor
to display the list of available transformations. Select
Range
to attach a range transformation. This will also display the just attached range transformation in the
Edit Dynamics
dialog.
Change the In Low to 5 and In High to 10, leaving the Out Low as 0 and Out High as 1. Now the object will rotate from 0 degrees to the angle defined by the Angle parameter when the controlling Factor changes from 5 to 10.
Click on the Prev button at the bottom of the Edit Dynamics dialog to return to the Rotate dynamics and try changing the Factor by entering values in the range from 5 to 10.
The range transformation may be attached to any numerical attribute of any object.
To return to the
Factor's
Range
transformation at a later time, select the ellipsis button
next to the
Factor
and click on the Dynamics
Add
button in the activated
Attribute Object
dialog.
You can adjust control points by moving them with the mouse. You can also Shift -click on the control point (click on the point with the left mouse button while pressing the Shift key) to bring up the Control Point dialog for fine tuning the control point values. Shift -click is also convenient for selecting one out of several closely positioned control points.
You can use the Control Point dialog to enter the X, Y and Z coordinate values of the control point (in the -1000 to +1000 range for the default coordinate mapping).
You can also use the directional buttons to fine-tune the control point position, moving it by one or more pixels in a selected direction.
You can
Shift
-click on the
Move Control Point
(a special
point in the center of the object) to move the object using directional buttons. You can also
Shift
-click on the
Rotate Point
(a special
point on the right side of the
Resize Box
) to rotate the object by a defined angle using directional buttons.
You can add geometrical dynamics to individual control points by selecting the Dynamics Add button in the Control Point dialog, and then proceeding in the same way as when attaching geometrical dynamics to objects.
To move several control points uniformly, use the constrained transformations described in Using Constrained Dynamics and Marked Transformations.
A rendering object may be attached to GLG graphical primitives (polygon, arc, etc.) to define an optional set of extended rendering attributes. These attributes are not part of the object by default for the sake of efficiency, and are added only to the objects that truly need them. The extended rendering attributes include attributes that define and control several types of gradient fill, cast shadows, arrowheads and fill dynamics.
To add rendering attributes to an object, select the object, display its Properties dialog, then click on the Add Rendering button at the end of the properties list. This will add rendering to the selected object and display the properties of the rendering object. For example, create a filled polygon, set its FillColor to white, display its Properties dialog and add rendering to it.
If the selected object has already had rendering added, the Edit Rendering button will be displayed, allowing the user to access the rendering attributes for editing.
To delete the rendering, press the Delete Rendering button at the end of the Rendering Properties list.
To return to the object attributes without deleting Rendering Attributes, press the Previous button at the bottom of the Properties dialog.
To add a linear gradient fill to the polygon created above, change the Gradient Type from NONE to ACYCLIC LINEAR in the Rendering Properties dialog. The object will be rendered with a gradient fill, changing its color from its original FillColor to the GradientColor.
The GradientColor attribute defines the second color for the gradient fill. Press the ellipsis button
next to the GradientColor to display a color palette for selecting it.
Change the GradientType to CYCLIC LINEAR and notice the change in the gradient fill: it now cycles from the object's FillColor to the GradientColor and back to the FillColor.
The GradientAngle attribute controls the angle of the gradient, measured counter clock-wise relative to the X axis. Change the angle to 90 to render a vertical gradient fill.
Change the GradientType to CONICAL and then SPHERICAL to see the corresponding gradient fills. Finally, change the GradientType from SPHERICAL to INVERSED SHPERICAL and notice the change in the gradient fill colors: instead of changing from the object's FillColor to the GradientColor, the color change is inversed.
The GradientLength attribute controls area of the object rendered using the gradient fill. Change the GradientLength to 0.5 to see only half of the object area filled with the corresponding gradient.
The GradientCenter attribute defines the gradient center in relative coordinates. Change the GradientCenter to 0,0,0 to have the gradient centered at the lower left corner of the object's bounding box. Setting the attribute's value to 1,1,1 centers the gradient at the top right corner of the object's bounding box.
The GradientResolution defines the number of polygon segments used to render the gradient fill. On non-True Color systems, due to the lack of available colors, the actual number of polygons used may be less than the specified value.
The FillAmount attribute is used to implement the fill dynamics commonly encountered in process control and other drawings showing tanks filled with liquid substances. A changing substance level may be implemented by adding rendering attributes and changing the FillAmount of the object representing the tank.
Try changing the value of the FillAmount of a filled polygon with rendering attributes. If the value is 1, the whole object is drawn. If the value is less then 1 (0.5, for example), only a portion of the object's fill will be drawn, as defined by the fill amount. If the value is 0, the fill is not drawn (i.e. tank is empty). Notice that the object's edge is not affected by the value of the FillAmount, and that the object's fill type must be either FILL or FILL AND EDGE in order to use fill dynamics.
The FillAmount attribute may be named for easy access (press the ellipsis button
next to the FillAmount and enter the name in the Attribute Object dialog). The name of the FillAmount will appear in the resource browser together with the other object resources.
The FillDirection attribute defines the direction of the fill dynamics. You may select one of the 4 preset values: UP, DOWN, LEFT or RIGHT, or define an arbitrary angle. To define an arbitrary angle, press the ellipsis button
next to the FillDirection and enter the value of the fill angle. The angle is measured counter clock-wise, relative to the X axis (for example, an angle of 90 corresponds to the UP fill direction).
The ShadowOffset attribute controls the offset of the cast shadow. The offset is in screen pixels, and if the offset's value is not 0 in the X or Y direction, a shadow is rendered, as defined by the ShadowColor attribute. Press the ellipsis button
next to the ShadowColor to display a color palette for selecting the color.
The ArrowType attribute defines the type (LINES or FILLED) and position (one of the ends, both ends, or the middle) of arrowheads drawn on a polygon, arc, and other polygon-like objects. The arrowheads are drawn when the ArrowType differs from NONE. Try selecting different ArrowType values and observe the resulting arrowheads. The ArrowShape attribute allows the user to define a custom arrow shape by specifying the X and Y extent of the arrowhead.
The text object allows the user to define an optional text box around the text by attaching the Box Attributes object. The Box Attributes define the attributes of an outline or filled box drawn around the text.
Try creating a text object and adding Box Attributes by clicking on the ellipsis button
next to the Add Box Attributes label at the end of the text's Properties dialog. An outline drawn around the text will appear. Change the FillType from EDGE to FILL & EDGE to display a filled box, then select the FillColor of the box (click on the FillColor's ellipsis button to display a color palette). The BoxOffset attribute defines an offset in pixels between the text and the edge of the box.
To delete the Box Attributes, click on the Delete Box Attributes button at the bottom of the Box Attributes' properties.
To return to the text object's attributes without deleting the Box Attributes, press the Previous button at the bottom of the Properties dialog.
A group object provides a convenient way to hold several objects together, so that they can be saved, moved or edited as one entity.
To create a group, select the
Group
icon from the Object Palette, then click and drag the mouse to define a rectangular area. A new group will be created and all objects that are either completely or partially inside the defined rectangle will be placed inside that group.
When the group is selected, the control points of all objects in the group are displayed. Also, the group's control points don't have a cross in the middle.
To get access to individual objects in the group, go inside the group in the same way you got used to with the viewport object. Select the group and click on the
Hierarchy Down
button to zoom into the group. After this you'll be able to select and edit individual objects inside the group. Go back up when finished editing.
You can also select individual objects in the group in the context of the drawing without traversing down. Click on Select Next in the group's Properties dialog and selecting the object in the group you want to edit. After editing an object, simply select the next one with the mouse. Select an object outside of the group to finish editing group objects.
When several groups are nested, you may use Select Bottom from the group's Properties dialog to select an object on the bottom of the group's hierarchy.
Select Next
and
Select Bottom
are also available as toolbar buttons. When a permanent group is selected, Ctrl-Shift-click on an object inside the group also works as a shortcut for the SelectNext operation.
Groups provide a convenient way to edit many objects at once. To edit multiple objects in an existing group, select the group, click on the Edit All button in the group's Properties dialog or use the Edit All (First) option in the Traverse or Arrange menus. The properties to be edited will be determined by the type of the first object in the group. As you edit any of the attributes, all objects in the group that have that attribute will be changed. To return to the properties of the group, click on the Prev button at the bottom of the Properties dialog.
A group may contain objects of different types, such as polygons or text objects, in which case the Edit All (Select) option allows you to select a set of properties to edit by clicking on an object in the group. The type of the selected object will define the set of attributes to edit.
For example, to edit Anchoring of all text objects in the group, click on Edit All (Select) and select any text object in the group with the mouse to edit text attributes. To edit the Line Width of all polygons in the group, use Edit All (Select) and select a polygon to define the polygon attribute set.
If you constrain an attribute (see Using Constraints below) while editing all objects in the group, the corresponding attribute of all the objects in the group will be constrained.
If you want to edit multiple objects that do not belong to a group together, create a temporary group as described in the Multiple Selection on page 12. The temporary group will be destroyed automatically when unselected.
You can add or delete objects from a group by using the Add To Group and Delete From Group toolbar buttons.
To add to a group, select the group, click on the
Add To Group
toolbar button and select objects in the Drawing Area you want to add. Press the Escape key to finish.
To delete objects from the group, select the group, click on the
Delete From Group
toolbar button and select the objects in the group you want to delete. The objects will be deleted from the group and added to the Drawing Area.
You can also zoom down into the group to manipulate group objects one by one.
To release the objects from the group, explode the group by using the
Explode Object
toolbar button or
Arrange, Explode, Explode Object
from the main menu.
Explode operation may be applied to other objects as well, such as circles, arcs or series, but keep in mind that Explode action can't be reversed when executed.
If you need to align or layout a group of objects, Layout Toolbox provides a point and click interface for such functionality. Examples of layout and alignment operations include aligning several objects horizontally or vertically, setting the same width for several objects, positioning objects within a defined distance from each other, or distributing the objects evenly across the defined extent in a horizontal or vertical direction.
Create three rectangles using the
Filled Rectangle
button and position them horizontally, one next to the other. Select all rectangles by clicking and dragging to define a rectangular area that includes all three rectangle objects. This will create a temporary group that contains selected objects.
Click on the Layout Toolbox
button in the toolbar to activate a
Layout Toolbox
. Alternatively, the
Layout Toolbox
can be activated using Layout, Layout Toolbox option in the main menu. The following picture shows the
Layout Toolbox:
Let's align the bottom of all selected rectangles. First, we need to select an anchor object relatively to which all other objects will be aligned. If the anchor is not defined explicitly, one of the objects in the group will be chosen as an anchor automatically. Click on the Select Anchor Object
button in the
Layout Toolbox
, then click on one of the rectangles. Click on the
Align Bottom
button in the
Layout Toolbox
and notice that the bottom of all selected rectangles will be aligned to the bottom of the anchor rectangle.
Once the anchor is defined, it will be persistent for all layout operation until another anchor is chosen or the objects are unselected.
Let's position all rectangles to be within 50 world coordinates from each other, as measured between the rectangles' extents in the horizontal direction. Click on the
Set Horizontal Space
button in the
Layout Toolbox.
Notice that the label of the text edit box at the bottom of the
Layout Toolbox
displays the selected operation and is set to
Horiz.Space.
Click on Coord: World button in the Layout Toolbox to indicate that the horizontal space between objects will be defined in world coordinates. Enter 50 as the value in the Horiz. Space text box. The rectangles will be positioned so that the space between them will be 50 world coordinates.
A layer is a collection of objects whose visibility may be turned ON or OFF . Layers are usually used to display collections of objects or icons on maps, schematic diagrams, etc.
A layer of objects may be created by placing several objects in a permanent group. The group's visibility attribute is then used to make the layer visible or invisible by setting just one visibility attribute (of the group). Objects in the layer may use attribute constraints described in the previous section to constrain some attributes to have the same value. For example, if you constrain the color attributes of all the layer's objects, changing one color resource will change the color of all objects. Different layers may use different colors, line widths, etc., to accent the layer.
Constraints may be used to constrain the value of an object attribute to an attribute of another object. This simplifies maintaining or animating collections of objects.
For example, imagine a drawing or a car that uses different polygon objects to render different parts of the body. If the color attributes of all the polygons are constrained, you can change the color of just one polygon object and the color of the whole car will change.
In more complex cases, parameters of dynamics may be constrained to change synchronously as will be shown in Using Constrained Dynamics and Marked Transformations.
To exercise attribute constraints, start with a new widget (use
File, New Widget
from the main menu). Create three polygons in the drawing and name them
"Poly1", "Poly2"
and
"Poly3"
. Select
"Poly1"
, bring up it's
Properties
dialog and select the ellipsis button
next to it's
Fill Color
attribute to activate the
Attribute Object
dialog.
Select the Constrain button on the left of the Attribute Object dialog and select the "Poly2" polygon in the drawing with the mouse: this will constrain the Fill Color attribute of the currently selected polygon to the Fill Color attribute of the polygon you selected with the mouse.
Try changing the color by selecting a new color from the color palette: the color of both polygons will change.
This way of constraining works for constraining attributes of the same type. It will not work for example, for constraining Fill Color of one polygon to the Edge Color of another polygon. To do this, the Builder has features to mark attributes and later use marked attributes.
Click on the Mark button in the Attribute Object dialog to mark the Fill Color attribute of "Poly1" , which is still selected (in editions of the Builder other than Basic, you also have to select Mark 0 from the list since more then one mark is available).
Now select "Poly3" , bring up the Attribute Object dialog for its Edge Color attribute and click Constrain . To constrain the edge color to the attribute that was previously marked, select the Use Marked button from the list on the right of the Attribute Object dialog (another option is to constrain to a resource by using the Resource Browser ).
If you now select a new color from the palette, the Edge Color of "Poly3" and the Fill Color of the other two polygons will change simultaneously.
The marking feature may also be used to constrain parameters of object's dynamics to change in unison.
The object's control points (other then the move point) may be constrained as well. Shift -click on a control point to bring up the Control Point dialog, click on Constrain button and select a control point of some object in the drawing to constrain to. If you now move the control point, both points will move.
The Attribute Object dialog also has the Merge button. If several attributes are constrained, the Constrain button unconstrains from a previous place and constrains to a new place, while the Merge button constrains the attribute itself as well as all other attributes that were constrained to it to a new place.
If you're not sure, use the Merge button as a first choice to preserve any existing constraints of complex objects.
Constrained dynamics is convenient when you need to move several objects together. In case of geometrical objects, the simplest way to move them together is to place them in a group and then attach dynamics to the group. However, if you want to move two control points in the same way, constrained dynamics provides the best solution.
For example, let's try to create an animated object that resembles a bar of a bar graph.
Start with a new widget (use
File, New Widget
). Create a filled, rectangular shaped polygon by clicking on the
Filled Polygon
icon and selecting 4 points in the drawing as shown in the picture:
Don't define the fifth point: it will be completed by the polygon when you finish entering points by pressing the right or middle mouse button.
Now we are going to animate the top two points of the polygon to move up and down together. Shift -click on the first top point to bring up the Control Point dialog and select Dynamics Add button to activate the Add Dynamics dialog. Select the Move transformation type, click on the Move Vector In Drawing button, and select two points in the drawing to define a vertical moving distance. Enter "Height" as the Variable Name and hit Apply .
This will attach the Move dynamics to the control point and will bring up the Edit Dynamics dialog showing the parameters of the attached transformation. "Height" should appear as the name of the dynamics' controlling Factor . Try changing the factor from 0 to 0.3, for example, and notice the point moving in the drawing.
Select the Mark Object button from the Edit Dynamics dialog to mark the currently selected dynamics for later use (the Mark List button marks all dynamics attached). Then close the Edit Dynamics dialog, Shift -click on the second top point and select the Dynamics Add button.
But this time we are not going to attach a Move dynamics. Instead, we'll reuse the same dynamics that we just marked. Change the transformation type from Move to Use Marked , and select the Constrained clone type. This means that a copy of the marked Move dynamics will be attached, and all parameters of this copy will be constrained to the parameters of the marked dynamics.
Hit Apply to attach the dynamics and try changing the value of the controlling Factor (named "Height" ) from 0.3 to 0.5: both points will move the same distance.
Let's adjust the initial position of the moving points to be at the bottom of the bar. Set the " Height" parameter to 0, close the Edit Dynamics dialog and move the top points down to coincide with the bottom points when the height equals 0.
Now prototype the drawing with the following animation script:
$datagen -sin d 0 1 $Widget/HeightThe script will change the value of the Height resource from 0 to 1, resulting in the two top points moving up and down by a defined distance.
Marking and then using marked transformations (as described in the above example) is a convenient way to add the same transformation to several objects. In the transformation dialog, one transformation or a whole list may be marked for reuse. Selecting the Use Marked choice of transformation types will attach one or more marked transformations to the object.
The Clone Type option controls the constraining of the cloned object's attributes: if Full Clone is selected, a fully independent copy of the transformation is attached, Constrained Clone attaches a constrained copy with all attributes of the copy (or copies) constrained to the corresponding attributes of the original transformation(s). The Weak Clone constrains only the attributes with Global flag set to GLOBAL, and Strong Clone constrains attributes with the GLOBAL or SEMIGLOBAL settings of the Global flag.
The constrained control points dynamics described in the previous section may be used to create a Fill Dynamics similar to the one described in Adding Extended Rendering Attributes.
While using the FillAmount rendering attribute is the easiest way to implement fill dynamics, the fill dynamics implemented using control points' dynamics allows a few additional features: it affects not only the fill but also the edge of the object, and it rotates with the object when the object is rotated. For example, if rotate dynamics is attached to the object, the fill will rotate with the object instead of continuing to fill vertically or horizontally. The fill dynamics implemented with the FillAmount may be rotated only by changing the angle of the FillDirection attribute.
The GLG drawing supports integrated object tooltips. If an object (or any of its parents) have a TooltipString resource of S type defined, the value of this resource is used to display a tooltip when the mouse is moved over the object. If the object is a group, the tooltip will be displayed every time the mouse moves over any of the group's subobjects.
To attach a tooltip resource to an object, create an object, set its HasResources=YES and select Object, Add Tooltip from the main menu (Enterprise Edition of the Builder is required to add the tooltip). This will attach a custom property named TooltipString to the object and display a dialog for entering the tooltip string. Enter the tooltip string. To enable tooltips, set the ProcessMouse attribute of the viewport that contains the object to Move and Click. To try the tooltip in the prototyping mode of the Builder, press the Start
toolbar button and enter an empty run command. Move the mouse over the object and wait a fraction of a second to see the tooltip. The tooltip disappears when the mouse is moved away from the object. Press the Stop
toolbar button to return to the edit mode.
At run time, the tooltip is handled by the Toolkit automatically, with no program actions required. Refer to Integrated Tooltips of the GLG User's Guide and Builder Reference Manual for more details.
The GLG drawing can highlight objects in the drawing when the mouse is moved over them. This is done by defining the MouseOverState resource of D type which is set to 1by the Toolkit when the mouse moves over the object and reset to 0 when the mouse moves away. The drawing also supports the MouseClick feedback, which is implemented by setting the value of the object's MouseClickState resource to 1 when object is clicked with the mouse, and resetting it back to 0 when the mouse button is released. If the object has a resource named MouseClickToggle, the value of the resource is toggled between 0 and 1 every type the mouse clicks on the object. The MouseOverState, MouseClickState and MouseClickToggle resources can control object attributes or various dynamics attached to the object to implement any custom type of feedback or highlighting.
To try the MouseOver highlight, create a filled polygon, name it, set its FillType attribute to FILL & EDGE and HasResources=YES. Press the ellipses button
next to the LineWidth attribute to display the Attribute Object dialog for LineWidth, then press the Add Dynamics button and select List to add a list dynamics to it. The Edit Dynamics dialog will be displayed. Name the ValueIndex attribute of the list transformation "MouseOverState", then click on the List of Values button to edit list items. Select the first list item and set its value 1, then select the second item and set its value to 3 to alternate between the thin and thick lines. Now press the Object Resources toolbar button and check that the MouseOverState resource is visible as a resource of the object.
Set the ProcessMouse attribute of the containing the object to Move & Click, then start the prototyping mode by pressing the
Start
toolbar button and entering an empty run command. The polygon will be highlighted by changing its line width every time the mouse moves over it. Press the Stop
toolbar button to return to the edit mode.
Alternating the LineWidth attribute is just one of the ways to highlight the object. Various other types of highlighting may be implemented by using different attributes and transformation types. The following examples use different transformation type to implement a different form of visual feedback.
To define the MouseClick feedback for the object, select the polygon object used in the previous example and select the Add Dynamics toolbar button. Select the Move transformation type in the Add Dynamics dialog, set the Start Point to "0 0 0" and End Point to "50 50 0", then enter MouseOverState as the Variable Name. This will attach a move transformation to the object, with the transformation Factor attribute named MouseClickState. The ProcessMouse attribute of the object's viewport already includes Click event processing, so you can start the prototyping mode (select
Start
toolbar button and enter an empty run command).
Try clicking the object with the mouse and notice it moving a little bit diagonally and then returning back when the mouse button is released. The MouseOver feedback is also displayed when the mouse moves over the object. Press the Stop
toolbar button to return to the edit mode.
Select the polygon object again, press Edit Dynamics toolbar button and change the name of the transformation's Factor from MouseClickState to MouseClickToggle. Reset the drawing using the Reset toolbar button and run the drawing in the prototyping mode again. Now when the object alternates its position every time you click on it.
At run time, the MouseOver feedback, MouseClick highlight and MouseClick toggle are handled automatically, with no program actions required. Refer to MouseOver Highlight and MouseClick Feedback and Toggles of the GLG User's Guide and Builder Reference Manual for more details.
Custom MouseOver and MouseClick selection events may be attached to objects in the GLG drawing to allow for convenient event processing at run time. A custom event is attached to an object as a named custom property, and the Add MouseOver Event and Add MouseClick Event buttons are provided in the Enterprise Edition of the Builder. Pressing either button will attach a custom event property and will display a dialog for entering its value used as a custom event label.
The object's HasResources must be set to YES to allow attaching custom event properties, and the ProcessMouse attribute of the object's parent viewport must include Move events for the MouseOver custom events or Click for MouseClick events.
At run time, the program's Input callback will be invoked, providing the program with information about the event type, custom event label, the object that generated the event, etc. The program will then use this information to process the custom event to implement the application logic.
Refer to Custom Selection Events of the GLG User's Guide and Builder Reference Manual for more details. Refer to the GLG Programming Manual for more details of the Input callback and custom event handling.
The Editing Focus feature provides a shortcut to edit objects inside the viewport without zooming down into it.
To move the editing focus inside the viewport, select the
Set Focus
button from the
Control Panel
on the left and click on the viewport whose objects you want to edit. The editing focus will be temporarily be moved inside the viewport, changing it's border width to indicate the current focus. You can now select and edit objects inside the viewport.
To move the focus to some other viewport, set the focus again. To reset the focus back to the Drawing Area, select the
Main Focus
button.
The focus is very convenient for editing nested viewports without traversing down several hierarchy levels.
Note: You zoom down only if editing focus is set to the Drawing Area. If the focus is moved into some viewport, reset it back to the Drawing Area before zooming down.
The fonts used in a drawing are defined by the viewport's Font Table. You can edit the Font Table of any viewport right in the builder to define the number and types of fonts which can be used. The text objects in the drawing use the font type and font size indexes to select a font from the font table.
The Font Tables are used to optimize real-time access to the font rendering engine and prevent rendering a huge number of slightly different fonts that can bring even the powerful CPU to its knees, since GLG drawings may contain hundreds or even thousands of text objects. The future versions of the Toolkit will also provide an alternative way for specifying the font directly as an attribute of a text object for applications with a smaller number of fancy text objects.
The font tables may contain any font existing on the system, True Type or not, proportional or monospaced. The fonts are organized into font families that contain different sizes of the same type of font. These sizes are used to scale the GLG scalable text objects.
To change the font, click the
More
button from the viewport's
Properties
dialog, click on the Add Font Table button to add a custom font table
and
select the ellipsis button
next the
Fonts
label to show the attributes of the font table.
You can then define the number of font types and sizes in the font table, as well as select the fonts used. For each font, you can define separate font names to be used in a Unix, Windows or Java environment. When finished, you can save the font table for later reuse in this and other drawings.
If a drawing contains several nested viewports, you can define the font table only for the top "$Widget" viewport of the drawing and set the rest of the nested viewports to use the default font table. This will cause the nested viewports to inherit the table from the parent "$Widget" viewport.
The GLG Toolkit provides collections of pre-built widgets, such as 2D graphs, 3D graphs, controls, as well as avionics, process control and special widget sets.
The Professional and Enterprise version of the builder also allow building custom interface objects from scratch (refer to the Widget Input chapter of the GLG Programming Reference Manual for more details).
The Builder's Custom Objects palette provides a few samples of graph and control widgets.
The
Custom Objects
Palette (the
Custom Objects
icon in the
Object Palette or Palettes/Custom Object option of the main menu
) provides a few predefined interface objects that may be used in GLG drawings.
The Custom Object palette provides the following interface objects:
A button with custom graphics inside. To edit or replace the graphics, select the button's viewport and go down into it.
The button has a TooltipString resource that defines the tooltip string displayed in the Run mode.
A toggle with custom graphics inside. To edit or replace the graphics, select the button's viewport and go down into it. The toggle's graphics must have a resource named "OnState" . The toggle changes the value of this resource between 0 and 1 when you click on the toggle in the Run mode.
You may delete the
OnState
resource and provide your own. For example, create a toggle from the palette, select it and zoom down into it. Use the
All Resources
toolbar button to bring up the
Resource Browser
, select the
OnState
resource and erase its name in the
Attribute Object
dialog. Close the resource browser.
Now select the moving red part of the toggle, bring up the
Properties
dialog, click on the ellipsis button
next to it's
Visibility
attribute and name the
Visibility
attribute
"OnState"
by typing the name into the
Name
field of the
Attribute Object
dialog.
Go back up (this also resets the drawing after resource names change) and prototype with an empty animation script. When you click on the toggle, it will change the visible state of the switch. This technique can be used to display a custom checkmark in a toggle.
The toggle also has a TooltipString resource that defines the tooltip string displayed in the Run mode.
This is a native windowing system button object. It's behavior depends on the windowing system used (X/Motif or Windows). The name of the button is used as it's label. You'll have to reset the drawing with the
Reset
toolbar button to see the label change.
Same as the custom button, the button has a TooltipString resource.
This is a native windowing system toggle object. It's behavior depends on the windowing system used (X/Motif or Windows). The name of the toggle is used as it's label. You'll have to reset the drawing with the
Reset
toolbar button to see the label change.
Same as the custom toggle, the toggle has a TooltipString resource and a OnState resource that indicates it's current state. The OnState resource may be set or queried from a program. Some resources in the drawing, for example the Visibility attribute of an object in the drawing, may also be constrained to the OnState resource, so that the toggle will change the object visibility when activated.
Slider objects (scrollbar on Windows) represent native windowing system sliders or scrollbars. Their behavior depends on the windowing system used (X/Motif or Windows).
The sliders have a Value resource that changes from 0 to 1 when the sliders are moved in the run mode. The Value resource may be set or queried from a program. Some resources in the drawing, for example a controlling factor of dynamics, may also be constrained to the Value resource, so that a slider will animate the dynamics when the slider is moved in the Run mode.
3D Cube and Cylinder objects are built as collection of polygons that render a cubical or cylindrical 3D shape. To see the shape in 3D, you may need to rotate the view using the 3D rotation controls in the Control Panel on the left.
The polygons are grouped, select the group and zoom down into it to edit individual polygons or attributes. The color attributes of the polygons are constrained, so by changing the color of one of polygons, all polygons change their color.
The corner points of the polygons are constrained, which makes it easier to edit the shape. For example, select the cube's group, click on the
Select Next
toolbar button and select one polygon of the cube (you can use
Shift-
click when selecting to get a finer control over selecting).
Try moving the selected polygon with the mouse: the rest of the polygons will stretch to stay connected.
Two samples of process control objects: a valve and a tank are provided in the Custom Object palette. Both objects use a container object to encapsulate their sub-objects.
To edit graphical primitives of these models, zoom down into the container using the
Hierarchy Down
button
from the
Control Panel
, select the object, then zoom down once more to go down into the group object.
The valve has Rotation dynamics attached to the moving element with the dynamics' controlling Factor named "Angle" . When the "Angle" parameter changes from 0 to 1, the valve gradually changes from fully closed to fully open position.
The tank has the constrained move dynamics connected to the two moving control points, same as the control point dynamics described in Using Constrained Dynamics and Marked Transformations. The dynamics moves both points up or down when its controlling factor named "Level" changes from 0 to 1. Set the "BackgroundColor" resource of the tank to match the background color of the drawing.
Two graphs: a Line Graph and a Bar Graph are provided with the Basic edition of the Builder. More 2D and 3D graph widgets sets may be purchased.
Refer to Using GLG Graphs of this manual for detail on how to use GLG graphs' resources.
New objects may be added to the custom objects palette by saving them in the widgets/custom_objects directory. Refer to Read Directory of GLG Graphics Builder Menus for more details.
To use GLG drawings created with the GLG Builder in a C/C++, Java or ActiveX environment, a number of GLG containers are provided
GLG Wrapper Widget (X, Xt and Motif)
GLG C++ and MFC classes (C++ and MFC)
GLG cross-platform API (C/C++)
and others. Each of these containers encapsulates a GLG drawing for use in one of the programming environments.
To use a GLG drawing on the Web and in Java, save the drawing using the default ASCII save format to ensure accessed from any hardware platform. Use the default Save Compressed option to decrease the size of the drawing file.
To use the drawing with a C/C++ program, it must contain a viewport named "$Widget" . This viewport will be displayed when the drawing is loaded.
The specific method for loading the drawing depends on the programming environment used.
A C/C++ program may use the GlgLoadWidgetFromFile function or the LoadWidgetFromFile C++ method to load a drawing in a platform-independent way. The drawing is then displayed by using the GlgInitialDraw function or the InitialDraw C++ method.
In a Windows environment , either a GLG MFC control class or a Windows custom control may be used to encapsulate a GLG drawing.
On X Windows , a GlgWrapper widget may be used to display the drawing. The XtNglgDrawingFile resource of the widget is used to specify the drawing to load.
Refer to Displaying a GLG Drawing of the GLG Programming Guide for more details.
To use the drawing with a Java program, GLG Bean or applet, it must contain a viewport named "$Widget" . This viewport will be displayed when the drawing is loaded.
The GLG Bean has a parameter that defines a URL with the drawing file. Setting this parameter loads the drawing from that URL. A GLG Bean also has methods that allow to load the drawing from a file on demand under the program's control.
To load the drawing into the Java Applet or Java Bean , set the DrawingURL property of the applet or bean to the URL of the drawing. The URL may use the "file:" notation to specify a local file.
To load the drawing into a Java program , you can also use the LoadWidget method of the GlgObject class or the LoadWidgetExt method of the GLG Java Bean.
Refer to the GLG Java Programming Tutorial for more details.
To use the drawing with an ActiveX control, it must contain a viewport named "$Widget" . This viewport will be displayed when the drawing is loaded.
The GLG ActiveX Control has a parameter that defines a URL with the drawing file. Setting this parameter loads the drawing from that URL. A GLG ActiveX Control also has methods that allow to load the drawing from a file on demand under the program's control.
To load the drawing into the GLG ActiveX Control , set the DrawingURL property of the control to the URL of the drawing. The URL may use the "file:" notation to specify a local file.
The ActiveX control may also use the DrawingFile property to specify a local file, or use a LoadWidgetExt method of the ActiveX control.
Refer to Using the ActiveX Control of the GLG Programming Guide for more details.
When the drawing is loaded into a C/C++ or Java program or ActiveX control, the GLG resource mechanism is used to access resources of the drawing and to supply new resource values for animation, in the same way you did when prototyping the drawing in the Builder.
All GLG containers for different programming environments provide SetResource methods for setting named resources in the drawing. The resources may be of the D (double), S (string) or G (XYZ or RGB triplet) type. The names and syntax of methods slightly differ depending on the programming environment used (C/C++, Java or ActiveX), but they are used the same way in all environments. The Update method is used to redraw changes on the screen after setting the new resource values.
For example, the following fragment from the GLG Animation examples "blinks" the object 3 times by alternating it's color:
// Change the ColorIndex of the color dynamics attached to // the object's FillColor attribute from 0 to 1 and back // to blink. for( j=0; j<6; ++j ) { GlgSetDResource( viewport, "CatchMe/ColorIndex", (j % 2) ? 1. : 0. ); GlgUpdate( viewport ); GlgSleep( 100 ); // Delay for 0.1 sec }In this example, the GlgSetDResource method is used to set the new value of the "CatchMe/ColorIndex" resource, and the GlgUpdate method is used to update the graphics making the changes visible.
When a GLG drawing is embedded into an HTML page using a Java applet or ActiveX control, the data may be supplied programmatically or from a Web URL as described below.
If a Java applet is used, it may provide Java code that supplies data.
Both the Java applet and the ActiveX control may use scripts (Java script or VB script for ActiveX) to invoke the applet's or control's methods to supply data.
The following Java Script example calls the methods of the GLG ActiveX Control or Applet to supply data into a GLG graph displayed on a web page:
// Set titles document.obj.SetSResource( "Title/String", "Graph Example" ); document.obj.SetSResource( "XAxisLabel/String", "Value" ); document.obj.SetSResource( "YAxisLabel/String", "Time" ); // Set number of samples in a graph document.obj.SetDResource( "DataGroup/Factor", 10. ); // Set number of labels and minor ticks document.obj.SetDResource( "XLabelGroup/Factor", 5. ); document.obj.SetDResource( "XLabelGroup/MinorFactor",2.); // Set ranges document.obj.SetDResource( "YLabelGroup/YLabel/High",1.); document.obj.SetDResource( "YLabelGroup/YLabel/Low", 0.); // Fill the graph with data for( i=0; i<100; ++i ) { document.obj.SetDResource( "DataGroup/EntryPoint", GetData( i ) ); document.obj.SetDResource( "XLabelGroup/EntryPoint", GetLabel( i ) ); // Update after every iteration of data document.obj.Update(); }Both the applet and the ActiveX control allow supplying data from an arbitrary Web URL. The data must be in the GLG Script format. The URL may be a file as well as a CGI or IS API process that gets up-to-date data from a database on the fly, formats them as a GLG Script and sends them to the GLG container that requested the data.
The following example shows a GLG Script that fills a GLG graph displayed on a Web page with data:
# Set titles, etc. set_value Title/String s Graph Example set_value XTitle/String Value set_value YTitle/String Time set_value DataGroup/Factor d 5 set_value XLabelGroup/Factor d 5 set_value XLabelGroup/MinorFactor d 1 set_value YLabelGroup/YLabel/High d 0 set_value YLabelGroup/YLabel/Low d 1 # Fill the data set_value DataGroup/EntryPoint d 0.1 set_value DataGroup/EntryPoint d 0.2 set_value DataGroup/EntryPoint d 0.3 set_value DataGroup/EntryPoint d 0.4 set_value DataGroup/EntryPoint d 0.5 # Fill the labels set_value XLabelGroup/EntryPoint s 1:00 set_value XLabelGroup/EntryPoint s 2:00 set_value XLabelGroup/EntryPoint s 3:00 set_value XLabelGroup/EntryPoint s 4:00 set_value XLabelGroup/EntryPoint s 5:00 # Display the changes updateThe database support features of GLG scripting may be used for integration with databases. Refer GLG Script of the GLG Programming Reference for details.
The GLG examples directory contains C and C++ source code for a simple GLG animation examples that shows how to load and display a drawing, animate it with data and handle user interaction with the drawing.
The DEMOS directory contains source code for more elaborate C/C++ demos: an aircombat simulation, a GIS map demo, a diagram editor demo and others.
The DEMOS/java_demos directory contains the source code of Java demos. These demos are also available on-line on the www.genlogic.com web site.
The examples_java directory contains source code examples for the GLG Java Programming Tutorial.
This section explains the design of the drawing used for the GLG Animation example in the GLG examples directory. To learn how the drawing is built, this section lists step-by-step instructions for building the drawing from scratch. It is assumed here that you're already familiar with the basic GLG Builder navigation described at the beginning of this tutorial.
The drawing we'll be building here will display a bouncing ball with an attached X and Y move dynamics that is used to animate the ball's movement. The ball also has a Fill Color dynamics that is used to flash colors when the ball is hit with the mouse.
To create this or any other GLG drawing that will be used with a program, start with a new widget ( File, New Widget ): this will create a new viewport and bring the editing focus into it.
Use the
Properties
toolbar button to bring up the viewport's
Properties
dialog and click on the
More
button. Set
Stretch
=NO to preserve X/Y ratio of the drawing: we are going to create a circle object and this will prevent the circle from being "squished" when the drawing is resized. Set
PushIn
=YES: this makes the default [-1000;+1000] coordinate extent to always appear in the viewport's window regardless of its X/Y ratio.
Create a small circle in the center of the drawing by clicking on
Filled Circle
from the
Object Palette
and selecting two points in the drawing area: the first point will define the circle's center and the second will define its size. Position the circle in the center of the drawing by selecting the drawing's center as the circle's center point, or moving the circle after it has been created.
Use the
Properties
toolbar button to bring up the
Properties
dialog and name the circle
"CatchMe"
. Change the circle's
HasResources
flag to
YES
to define the resource hierarchy: all circle's resources will be referenced by using a
"CatchMe/"
path prefix.
Click on the ellipsis button
next the
Fill Color
attribute to activate the
Attribute Object
dialog, then select the Dynamics
Add
button at the button of the dialog. Select
List
from the list of color dynamics choices. This will attach the list color dynamics to the circle's
Fill Color
attribute and will bring up the
Edit Dynamics
dialog showing the dynamics we just attached.
Type the " ColorIndex " name in the right-most field for the dynamics' Value Index parameter. This resource name will be used to change the color displayed. The value of 0 will display the first color, the value of 1 will display the second color, and so on.
Select the ellipsis button
next to the
List of Values
to display the list of colors. Select the first item in the list and define it's color by selecting a red color from the palette, then select the second item and select a yellow color.
Try changing the value of the Value Index parameter from 0 to 1: the circle's colors should change from red (0) to yellow (1). Restore the index value to 0 and close the dialog.
Make sure the circle object is still selected and click on the
Add Dynamics
toolbar button to bring up the
Add Dynamics
dialog. Set the transformation type to
MoveBy
at the top of the dialog, set
Move Direction
=
X
and hit
Apply
. This attaches a
MoveX
transformation to the circle and brings up the
Edit Dynamics
dialog showing its attributes.
Set XDistance =0 and name the attribute " XValue " in the Name field to the right of it - this name will be used to set the set the X movement amount when animating the object. Set relative Factor =1, so that the effective movement value (defined as the multiplication of the Factor and XDistance ) is completely controlled by the XDistance attribute.
Click on the
Add Dynamics
toolbar button again, change
Move Direction
to
X
and hit
Apply
. This attaches a
MoveY
transformation to the circle. Set
YDistance
=0 and name the attribute "
YValue
". Set
Factor
=1.
The MoveX and MoveY transformations will be used to animate circle's movements by changing their XValue and YValue resources.
Unselect the circle by pressing the ESC key and select Options, SnapTo, To Grid from the main menu to make it easier to create a rectangular polygon.
Use the
Closed Polygon
Object Palette
icon and select 4 points in the drawing to create a rectangular polygon as shown in the following picture:
Bring up the Properties dialog for the polygon, name it "Area" and set its HasResources =YES. Shift -click on the polygon's lower left control point to bring its Control Point Editing dialog and name the point " LLPoint" . Shift -click on the polygon's upper right control point and name it " URPoint ". These names will be used by the program to access the points, to query the extent of the Area polygon. The program will then use the extent to animate the circle, moving it within the Area boundaries.
Click on the
Custom Objects
icon in the
Object Palette
to bring up the
Custom Objects
dialog and select a
Button
object from the dialog. This will paste a native button object into the drawing. Place two buttons at the bottom of the drawing and name them
"Slower"
and
"Faster"
. These buttons will be used to change the moving ball's speed when the user clicks on a button. Reset the drawing by clicking the
Reset
toolbar button to force the buttons to display the new names.
Click the
All Resources
toolbar button to bring up the
Resource Browser
, double-click on the
Faster
resource, then select the
TooltipString
resource and set it's value to
"Increase Speed"
. This value will be used to display the
"Faster"
button's tooltip in the run mode.
Double click on the ".." item in the Resource Browser to return to the top level, double-click on the Slower resource, and set it's TooltipString to "Decrease Speed" .
Reset the drawing by clicking the
Reset
toolbar, and select the
Start
toolbar button to prototype the drawing. Enter an empty animation script and hit
OK
to start prototyping. Position the mouse over one button then another and wait to see the tooltips coming up. Stop the prototyping by clicking on the
Stop
toolbar button.
We now finished creating the drawing. Rename the old "animation.g" drawing in the GLG's examples directory to "animation_bak.g" and save the drawing as "animation.g" in the examples directory by using File, Save As from the main menu. You should now be able to run the example using the new drawing.
If you get errors running the example with the new drawing, check the spelling, letter capitalization and resource paths of resource names reported in the error messages. Use the Resource Browser to check the names in the Builder: the names and resource paths should appear exactly like they are reported in the error messages for the resources that aren't found.
You can use pre-built graphs, dials, meters and other components to start displaying data right the way, either in your application or on a Web page. The
Basic
and
Demo
editions of the Builder come with two graphs,
bar1.g
and
line1.g
, that can be used to display dynamic data. The graphs are located in the custom objects palette (
Custom Object
icon in the
Object Palette
). Additional 2D and 3D graphs, controls and other widget sets may be purchased either with the
Professional
or
Enterprise
versions of the GLG Builder or separately.
To use the graph, simply place it in the drawing inside the widget viewport. If you want to display several graphs in the drawing, place them inside the widget viewport, adjusting their position and size as desired.
If a graph is the only thing you want in the drawing, you can delete the widget viewport, place the graph in the drawing and name it "$Widget" . This way the graph's viewport will serve as the widget viewport. When finished, save the drawing into a file and load it in the program or on the Web page by using one of the GLG containers described in Loading the Drawing into a C or C++ Program.
To supply data for the graph, use one of the methods described in Supplying data for animation from a program or Supplying data for animation when used on a Web page.
While the graphs have a lot of resources for customization, most of them have a common resource set that controls the graph:
You can use graphs other than the basic bar1.g and line1.g to display more than one data set or display data in 3D.
The examples in Supplying data for animation from a program or Supplying data for animation when used on a Web page list some typical resources that are used to animate the GLG graphs.
More C source code examples may be found in the GLG examples/graphs directory. Java examples are located in the DEMOS/java_demos and examples_java directories.
Reference object is a wrapper object created around an object or group of objects. It has a single control point that defines its position. The reference is often used as a wrapper around complex objects, such as nodes or icons, making it easier to position them. There are two subtypes of a reference object with different reference types: Container and Reference .
All drawings described in the tutorial may be found in the <glg_dir>/tutorial directory. These drawings may be used to verify the final result of the steps described in the following chapters.
Container object is the simplest type of a reference object, which is used as a convenient wrapper for positioning complex objects. Let's try to create one and see how it is used.
Start with a new drawing by selecting
File, New Widget
from the main menu. Using the
Filled Polygon
button, create a filled triangle centered around the center of the drawing (the center of the drawing is marked with the axis icon). Bring the polygon's
Properties
dialog, name it "
Polygon
" using the
Name
field. The polygon's
HasResources
=NO.
Let's add rotation dynamics to the polygon. Click on Add Dynamics button and select Rotate for transformation type in the Add Dynamics dialog. Set Rotation Axis to Z to rotate in the XY plane of the drawing. Set Center parameter to "0 0 0", which coincides with the center of the polygon. At this point, it doesn't matter what the Angle parameter is set to.
Click on Apply to attach the transformation; the Edit Dynamics List dialog will come up. Set the Factor parameter to 1. Set ZAngle parameter to 0 and name this parameter " Angle ". Click on OK to close the dialog.
Make sure not to move the polygon with the mouse at this point, since it will distort its position relatively to the rotation center. Later on in this chapter, we'll talk about preserving the position of rotation center relative to the object, so that it is not affected by the object move.
Create a fixed text object with a text " label " and position it below the triangle. Bring its Properties dialog and name the text object " Label ". Click on the ellipsis button next to the TextString attribute to bring its Attribute Object dialog, and name the attribute " LabelString " using the Name field.
Click on the
Group
button and create a group object containing both triangle and label objects. Bring its
Properties
dialog and name the group "
IconGroup
". Notice its
HasResources=NO
setting.
You can think of this group object as a graphical icon composed of a triangle and a label. The triangle may represent some live object (for example, an airplane) and the label may be used to display some textual information next to it, such as a flight number. The triangle may be rotated around its center to annotate airplane's current direction. When such icon is used in a program, it needs to be positioned at the exact latitude/longitude coordinates of the airplane it represents. It would be convenient to be able to position the icon by setting coordinates of a single control point, which could be accessed as a resource from the program. A reference object does exactly that - it allows to create a "wrapper" around a group of objects, with a single point to position it.
While the group object is selected, create a container object by clicking on the
Container
button in the
Object Palette
. Define the position of the container's control point by clicking in the center of the triangle - the control point will be attached at that place.
Bring up the container's Properties dialog and notice that its ReferenceType is set to Container . Name the container " Icon " and set its HasResources =YES. Notice the FixedSize property which, if set to YES, may be used to create icons of a fixed size. The fixed size containers do not resize when the drawing is zoomed or resized, even if the drawing itself is resizable. The only way to change the size of a fixed size container is by editing or scaling its template.
Shift+ click on the control point to brings its Control Point dialog and name the point " Position ". Try changing the coordinates of this point to "200 0 0". The object will move, with its control point (the center of the triangle) placed at the location (200,0,0). The Position resource may be accessed from a program to position the icon.
With the
Icon
object selected, select
Object, Object Resources
from the main menu (or
Object Resources
toolbar button) to bring the
Resource Browser
. It will show the following resources of the
Icon
:
Position , defines the icon's position
LabelString , defines the text string of the label displayed below the icon
Angle , defines the triangle's rotation angle
Polygon , provides an access to the triangle's attributes, such as FillColor , etc.
Label , provides an access to the triangle's attributes, such as FillColor , etc.
Template and Origin resources, which will be explained later.
Notice that even though the LabelString and Angle resources are parameters of the group's text and polygon object respectively, they are visible at the Icon level, since HasResources =NO for both the text, polygon and group. It makes the resources visible at the container's level, making it possible to access them as Icon/LabelString and Icon/Angle . This is convenient, as we can access icon's attributes without knowing its exact object hierarchy.
Set the LabelString resource to "Plane 1100", set Position resource to "400 0 0", and change Polygon/FillColor resource to red using a color palette. The icon will move to a new position and will be displayed in the new color. The icon's label will display a new text as well. When the drawing is deployed in a program, the same resource settings can also can be done programmatically using the GLG API to update the icon with real-time data.
Set the Angle resource to 30. Notice that although the icon has moved, the polygon is still rotated around its center, meaning that the relative position of the rotation center is preserved when the object moves. In fact, the reference object preserves the relative position of rotation center by moving both the object and the rotation center, so that their position relatively to each other does not change. The same is true for the scale center if a scale transformation is used.
The Resource Browser also displays the container's Origin and Template resources. The Origin defines the attachment position of the container's control point.
The group object used to create the container is called a template, and is displayed as a Template resource in the Resource Browser . For the container object, the Template and IconGroup resources displayed in the Resource Browser refer to the same object: the group containing the triangle and label objects. " Template" is a default resource name which may be used to access the container's template when it is unnamed. In our case, since we set template's HasResources =NO to make its resources visible at the level of the reference object, both the Template and IconGroup show no resources inside them in a resource browser.
Let's try to make multiple instances of the icon. Create a copy of the
Icon
object by selecting
Edit
,
Full Clone
(or using the
Ctrl+L
key). The copy will be selected. Position it in the drawing using the mouse, then bring its
Properties
dialog and name it "
Icon2
". Click on the
Object Resources
toolbar button to display
Icon2
's resources, and set the resource values as follows:
Polygon/FillColor = yellow color from the color palette.
The copy will reflect the new resource values. The changes are persistent: if you save the drawing and load it back, or reset it using the Reset toolbar button, the resource setting will be preserved for both the Icon and Icon2 objects.
While resources provide a way to access the template's attributes, the container's template is still accessible for direct editing, such as changing triangle's geometry or changing the position of the label object. Let's try to edit the Icon2 's template.
Select the Icon2 object with the mouse and click on the
Hierarchy Down
button to go "down" into the container. The container's template will appear in the center of the drawing. Click on the triangle: it will select the group object which holds the triable and the label. Click on the
Hierarchy Down
button again to go down into the group. Select the triangle and move one of its control points to change the triangle's shape. Click on the
Hierarchy Up
button twice to get back to the drawing level, the
Icon2
object will be selected again.
Notice that only the Icon2 instance changed, and the Icon object was not affected by the change. That is because each instance of container objects keeps its own, unique copy of the template, allowing each instance to modify it. That is not true for the reference object discussed below, which share the template between the instances.
When traversing down into the container's template, the Origin attribute may also be edited directly. The Origin is displayed as a round marker, which can be selected and moved with the mouse. The template is drawn above the Origin , so in our case it will obscure it. To make the Origin marker visible, select the template and reorder it using Arrange, Reorder, Move To Back . The round marker will become visible in the center of the drawing. If you move it to one of the triangle's corners, the container's control point will now be attached at that corner when you go back up. The attachment point of the container's control point may also be changed by moving the control point with the mouse while simultaneously pressing both the Control and Shift keys.
A reference with ReferenceType = Reference is a more complex type of a reference object used to replicate multiple instances of a shared template in a drawing. The template is shared among the instances and can be changed in one place for all of them.
Let's create this second type of a reference object using the template from the previously saved
container.g
drawing. Load the drawing using
File
,
Open
, select the
$Widget
viewport and traverse down into it using the
Hierarchy Down
button. Select the
Icon
reference object and traverse down to its template as well. Click on the triangular polygon to select the group object containing both the polygon and the label. Click on the
Copy
toolbar button to copy the group object.
Create a new drawing using
File, New Widget
. Click on the
Paste
toolbar button to paste the group object into the drawing: it will be placed in the center of the drawing, the same way as in the original drawing. We are going to use it as a template for a reference object we are about to create. Bring its
Properties
dialog and set its
HasResources
=YES, so that all template resources are visible at the template's level.
To create a reference with the
IconGroup
object as its template, make sure the
IconGroup
is selected and click on the
Reference
button in the
Object Palette
. Click in the center of the triangle to select an attachment point (if you want to position it exactly in the center of the drawing, click on the
Point Value
button and enter "
0 0 0
"). A text entry dialog will come up asking to enter
ObjectPath
and
OriginPath
. Press
OK
to use defaults for now.
Bring the Properties dialog of the created reference object. Name it Icon and set its HasResources =YES. The following properties are present in the reference object's Properties dialog:
ReferenceType = Reference (as opposed to Container )
Source = Template , meaning that a template is saved with the drawing
SourcePath = `blank' (defines a template path when Source is set to File or Palette )
ObjectPath = `blank' (defines an icon path inside a template with several icons)
CloneType = STRONG , defines what resources, if any, are constrained among the instances. If CloneType =STRONG (default), resources that are Global will be constrained.
Click on the
Object Resources
toolbar button to display resources of the
Icon
object we just created. The resource browser shows the list of
Icon
's resources, with the new
Source
,
SourcePath
and
ObjectPath
resources added to the list. The list also shows the Template resource, which is the IconGroup template object. In case of the reference, there is also a new resource called
Instance
, which is a copy of IconGroup template.
For the reference, the template is shared between all instances of the reference object, and each instance creates a copy of the template and then uses it for rendering. This is a major difference between a container and a reference. Each instance of a container object has its own copy of a template and renders it directly, while all instances of a reference share a template, and each instance creates a copy of the template for rendering.
Since both the template and its copy have the same name ( IconGroup in our case), the Template and Instance default resource names provide a way to access both the template and its rendered copy. The IconGroup resource in the resource browser refers to the copy of the template, which is the same object as the Instance resource.
Only the template is saved with the drawing, while an instance is created dynamically during hierarchy setup. It means that when a drawing is deployed in an application, an instance and its attributes are accessible only after hierarchy setup.
The reference creates a copy of its template at the hierarchy setup time. Before the hierarchy setup, the value of the Instance resource is null . After the hierarchy setup, the Instance resource is not null , and the IconGroup resource refers to the Instance object.
Double-click on the Template resource in the resource browser to see the list of its resources. Since IconGroup has HasResources =YES, the resources are visible at the template level. Double-click on the " .. " entry in the resource list to go back to the resources of the Icon object, and double-click on the Instance resource: it contains the same set of resources as the template, but they refer to resources of the template copy, which is rendered on the screen. If you change the Polygon/FillColor resource of the Instance , it will be immediately reflected on the screen.
For containers, there is only one instance of the template, but for references, the resources of both the template and its copy may need to be accessed. Both the Template and the Instance have the same set of resources. Setting the template's HasResources =YES ensures that resources of both the Template and the Instance are accessible as resources of the corresponding object: Template or Instance . For example, the Template/Polygon/FillColor resource path may be used to access the fill color of the template polygon, and the instance's colors may be accessed using either Instance/Polygon/FillColor or IconGroup/Polygon/FillColor resource path.
Let's make a copy of the Icon object by selecting Edit, Full Clone (or using the Ctrl+L key). It will create a copy of the reference object using the same template. The copy will be selected. Position it in the drawing using the mouse, then bring its Properties dialog and change its name to Icon2 .
With the
Icon2
still selected, click on the
Hierarchy Down
button to get down to the reference's template, the
IconGroup
object.
Click on the triangular polygon to select the group. Click on
Hierarchy Down
button again to go down into the group. Click on the triangle to select the
Polygon
object. Bring its Properties dialog, click on the ellipsis
button next to its
FillColor
resource and change the color to blue using a color palette.
Go up the hierarchy by clicking on the
Hierarchy Up
button twice to return back to the drawing, the
Icon2
object is selected.
Notice that the color of the triangle for both Icon and Icon2 objects has changed to blue, reflecting the change made to the template.
Let's try to change the template using resources. Bring the resource browser for the
Icon2
object and double-click on
Template
. Double-click on
Polygon
, then select
FillColor
and set it to green. Notice that the colors of references in the drawing did not change. That is because we changed the template, but the copies of it used for rendering by reference objects did not change. Click on the
Reset
toolbar button: this will reinitialize the drawing, recreating template instances by copying the template with the new color, which is now shown on the screen. When we edited the template using the
Hierarchy Down
button, the drawing was reset automatically when we returned back up, without the need to use the Reset button. Traversing the hierarchy is the preferred way of editing the template.
Change the color back to blue and reset the drawing.
Let's try to change attributes of a cloned template instance. The Instance is not persistent and is recreated from the template every time the drawing is loaded or reset, so it can not be edited by traversing down to it. The only way to access it is using resources. Bring the resource browser for the Icon2 object, double-click on Instance , then change Polygon/FillColor to red. The color of the triangle in the Icon2 object has changed to red, while the triangle of the Icon object remained unchanged. This is different from changing the template's color: changing the color in the template changes all instances, while changing the color of a particular instance (Icon2) affects only that instance.
When reference objects are used in an application to replicate some template, the application can change instance's attributes based on real-time data to implement icon dynamics. For example, if our template is used to represent an airplane, the LabelString and Angle attribute of each instance can be dynamically changed to indicate airplane's direction and flight number.
Now reset the drawing using the
Reset
button. The reference objects will recreate the displayed instances by copying the template, and any changes made to the instances will be discarded.
While all changes made to the objects in the template are permanent and saved in the drawing, changes made to the instances are volatile and are lost when the drawing is saved and then reloaded, or reset in the Builder.
Same as for containers, the FixedSize attribute of a reference object may be used to create icons of a fixed size. The fixed size references do not resize when the drawing is zoomed or resized, even if the drawing itself is resizable. However, a scale transformation can be attached to a reference template, and the scale factor of the transformation may be used to change the size of the reference instances. This technique is used in the AirTraffic Control and GIS demos to change the size of the fixed-size airplane icons.
All instances of a reference object in a drawing share the same template, causing them to be rendered using the same attribute values on initial appearance. There are cases, however, when it is desired that each reference's instance in the drawing has its own settings of certain resources, and that these settings are saved in the drawing. It would mean that when the drawing is loaded, these resource values are preserved and not overwritten by the template.
It can be achieved by using attribute rebinding. To make an attribute value of a reference instance persistent, that attribute has to be marked in a template by setting its Global flag value to Bound . Such marked attributes may have different settings for individual instances. The settings get saved in the drawing and restored when the drawing is loaded.
Let's see how to use this feature. Make sure the
Icon2
object is still selected, go down into it by clicking on the
Hierarchy Down
button. Select a group and go down into it as well. Select the triangle, bring its
Properties
dialog and click on the ellipsis
button next to its
FillColor
attribute.
In the Attribute Object dialog, change the Local setting to Bound . Bound attributes must be named, so name the attribute " IconColor " using the Name field.
Go up the hierarchy twice, so that the Icon2 object is selected again. Bring the Properties dialog for the Icon2 object, and notice that the Edit Bindings button is now enabled, providing an access to the binding array which holds values of rebound attributes.
Click on the button to see a list of bindings with the IconColor entry. Click on IconColor and change the color to yellow. The bindings array may also be accessed as the Bindings entry in the resource browser. Bring the resource browser for the reference object and double-click on Bindings : you'll see the same list of bound resources.
Please note that the rebound color attribute might have been accessed via the resource browser using a resource path containing any combination of default attribute names and named resources (for example, Icon2/Instance/IconColor or Icon1/IconGroup/Polygon/FillColor ) to achieve the same result, but editing bindings is more convenient, as it shows a single list of all bound attributes that can be assigned a custom value.
Reset the drawing using the
Reset
button. Since polygon's
FillColor
is now
Bound
, its value is taken from the bindings array and is not discarded as a result of the reset operation. Likewise, this setting will be preserved when the drawing is saved and reloaded.
In addition to altering appearance of individual instances in the drawing, the bindings may also be used for assigning unique tags to each instance. Since all instances are cloned from the same template, defining a tag in a template would result in the same tag being assigned to each instance. If different instances need to be connected to different data sources via tags, rebound attributes may be used, and unique tags may be assigned to each rebound attribute in the Bindings array.
The bindings may also be used to constrain attributes of each instance to attributes of other objects in the drawing, as well as assign new names to rebound attributes.
While some attribute settings, like airplane's icon Angle or LabelString , may need to be unique for each icon instance, other attributes, such as label color, may need to be constrained among all instances, so that the attribute's value can be changed in one place for all instances. To achieve this, the label's TextColor attribute must be defined as Global .
With the Icon2 object still selected, go down into it, then select the group and go down into it as well. Click on the text object to select the Label object. Bring its Properties dialog and click on the ellipsis button next to its TextColor . In the Attribute Object dialog, change the Local setting to Global .
Go up the hierarchy twice, so that Icon2 is selected again. Bring the resource browser, select IconGroup/Label/TextColor and change it to dark blue.
Notice that the label color for both icons has changed.
Attributes marked as Global are constrained among all instances, including the template. Resource values applied to Global attributes of one instance (or the template) are reflected in all other instances, as well as the template.
Reset the drawing. The label color remains dark blue for both icons. It is not discarded, unlike the case when the attribute was Local .
To summarize the attribute settings topic for a reference object, an attribute of a template can be marked as Local , Global or Bound . Each setting has the following meaning:
Local attributes are unique for each instance and their settings for individual instances are not saved in the drawing.
Global attributes are constrained among all instances. Their settings affect all instances, including the template.
Bound attributes are unique for each instance, and their settings for individual instances are saved with the drawing. The instance's Bindings property contains a list of all bound resources. Bound resources must be named.
To proceed with the tutorial for reference objects, we will continue working with the same drawing and modify it as necessary. Let's save the drawing as reference.g .
When the reference object was created, we used the default settings of the ObjectPath attribute. The ObjectPath attribute may be used to implement object dynamics, with a template containing several different objects to represent different states of an icon. The use of the ObjectPath attribute is discussed in Object Dynamics on page 65.
The reference object we used so far, the Template reference, replicates instances of a template in a drawing. This is different from a container object, which keeps an independent copy of a template for each of its instances.
There is another type of a reference object, called a subdrawing. While a template reference has a template saved in the current drawing, the subdrawing's template is saved in a separate file, allowing to share the template between multiple drawings. Changes applied to the template drawing will be reflected in all drawings that use it.
Steps below describe how to create a subdrawing object.
We will reuse the template of the icon we have already created. Select the
Icon
object, go down into it, select
IconGroup
and copy it by using either the
Edit, Copy
menu option or the
Copy
toolbar button.
Select File, New menu option to create a new drawing. Please notice the use of File, New instead of File, New Widget. Since we are going to use the drawing as a template, we do not need the $Widget viewport.
Select Edit, Paste to paste the IconGroup object, then save the drawing as icon.g .
Create a new drawing using the
File, New Widget
menu option. Click on the
Subdrawing
button to create a subdrawing object. Define subdrawing's position by clicking anywhere in the drawing. A
File Selection
dialog comes up asking to specify a subdrawing's filename. Enter
icon.g
and click on OK to use the saved template drawing. Another dialog comes up, asking to enter
ObjectPath
: enter
IconGroup
and press OK to use the
IconGroup
object from the template.
Bring the Properties dialog of the subdrawing object. Name it Icon and set its HasResources =YES. Notice that the subdrawing's properties are very similar to those of the reference, with an exception that Source = File , instead of Template , and the SourcePath defines a filename of the subdrawing's template.
The value of SourcePath is an absolute path from the File Selection dialog, and it is a good idea to change it to a relative path, relative to the directory of the drawing. This makes the project's directory self-contained, with all connections between the files being preserved when the whole directory is moved to another location or another machine. When SourcePath specifies a relative path, the template drawing file (subdrawing) is searched for relative to the directory of the drawing first, and then relative to the current directory. The GLG_PATH environment variable may also be set to define a list of directories to search for subdrawing files.
Let's remove the directory path portion of the SourcePath property, leaving only the " icon.g " filename.
Click on the Edit Bindings button in the Properties dialog. Click on IconColor in the list of bindings to select it and change its color to, let's say, pink.
Shift+ click on the subdrawing's control point and name it Position . In an application, the Icon/Position resource may be used to position the icon based on some values, for example latitude and longitude of an airplane represented by the icon.
Like references, subdrawings' instances are created dynamically during hierarchy setup. The attribute settings of bound attributes are saved in the drawing, and Global attributes are constrained among all instances of a subdrawing. Everything described above regarding attribute settings for references also applies to subdrawings. The only difference between a reference and a subdrawing is that for a reference, a template is saved in the current drawing, while for a subdrawing, a template is stored in a separate file that can be shared among multiple drawings.
The template of a subdrawing reference is loaded at the drawing setup time. The template is then copied to create an instance of it used for rendering the instance of the subdrawing reference object. Before the hierarchy setup, the value of both the Template and Instance resources of the subdrawing reference object is null .
The subdrawing's FixedSize attribute may be used to specify the subdrawing's resize policy. If the FixedSize is set to YES, the subdrawing will maintain a constant size when the drawing is zoomed or resized, which may be used to create dynamic icons of a fixed size, as shown in the AirTraffic Control and GIS demos.
In the Builder, the template drawing can be conveniently accessed by traversing down the subdrawing object. With the Icon object still selected, click on the Hierarchy Down button, to go down into the subdrawing's template. It will automatically attempt to load the subdrawing's template drawing, icon.g . The Builder will display the File Selection dialog, asking for confirmation to load this file. Press the OK button.
If desired, you can make changes to the template, or examine its objects and resources. For now, let's leave it the way it is and go up the hierarchy by clicking on the Hierarchy Up button. The File Selection dialog is displayed again, asking for confirmation to save icon.g . You may press OK to accept, or you may press Cancel to abort the save operation.
Since there were no changes, press Cancel , then press OK in the message dialog to confirm discarding any changes.
The file dynamics may be used to change the subdrawings template, so that different graphics is displayed when the state of the object changes.
Let's create another template drawing, so that we can alternate between two templates to see how file dynamics work.
Load
icon.g
drawing using the
File, Open
menu option. Select
IconGroup
and go down into it using the
Hierarchy Down
button. Click on the triangle to select the
Polygon
object and delete it using the
Cut
button. Create a filled circle in place of the polygon using the
Filled Circle
button. Bring its
Properties
dialog, name it "
Circle"
and leave its
HasResources
=NO. Go up the hierarchy, so that the
IconGroup
group is selected again.
Let's implement a file dynamics to alternate icon representation between the icon.g and icon2.g . You may think of it as the icon having two states, one state is represented by icon.g , and the other state is represented by icon2.g . The file dynamics is implemented by attaching a List transformation to the subdrawing's Source Path property.
Load subdrawing.g drawing. Select the $Widget viewport and go down into it. Select the Icon object and bring its Properties dialog.
In the Properties dialog, click on the ellipses button next to Source Path property to bring its Attribute Object dialog. Click on the Dynamics Add button at the bottom of the dialog and select List . Close the Properties dialog.
In the Edit Dynamics dialog for the list transformation, name the Value Index attribute " IconState ". The value of IconState is an index in a list of items, in this case a list of filenames to be used to draw the icon.
Click on the List Of Values button to display the list. In the List Dynamics dialog, select Item0 and notice that its value in the Attribute Object dialog has been already set to " icon.g ".
Select Item1 from the list and set its value to "icon2.g" in the Value field of the Attribute Object dialog.
Close all dialogs and bring the resource browser for the Icon object. Select the IconState resource and try alternating its value between 0 and 1. You'll see that when IconState =0, the icon.g file is used to represent the icon, and when IconState =1, the icon2.g file is used.
Save the drawing as subdrawing.g .
The file dynamics is similar to the image dynamics, used for image objects by applying a List transformation to the Image File attribute. An important difference is that the image dynamics switches static images, while the file dynamics switches dynamic graphical representations which may be further modified (by changing color, angle, label, etc.) based on real-time data.
As described in the previous chapter, file dynamics can be used to alternate the icon's appearance using different subdrawing files. While this is a powerful feature, its disadvantage is that a separate file should be supplied for each icon representation.
The Toolkit provides an alternative feature of Object Dynamics , where all possible representations of the icon are stored in a single drawing file.
Let's create a single template file that contains two versions of the icon: a triangle from the icon.g file and a circle from the icon2.g file.
Open the
icon2.g
drawing using
File, Open
, select the
IconGroup
object and copy it by using either the
Edit, Copy
menu option or the
Copy
toolbar button.
Open the
icon.g
file and paste previously copied object using either the
Edit, Paste
menu option or the
Paste
toolbar button. Move the template with a circle so that it does not intersect the other template with a triangle.
Select the
IconGroup
object with a circle, bring its
Properties
dialog and rename it to
Icon2
. Click on the
Select Next
toolbar button and click on the circle to select the
Circle
object (this is a shortcut to select individual objects in the group without going down into it).
The Shift +click on the control point in the center of the circle to brings its Control Point dialog and name the point " Anchor2 ". It will be used to define the icon's attachment point in the center of the circle.
Press the Escape key to get out of the group traversal mode.
Select the other
IconGroup
object containing a triangle. Bring its
Properties
dialog and rename it to
Icon1
. Since the triangle does not have a control point in its center we could use to define the icon's anchor point, we need to create one. Create a marker object using the
Marker
button and place it in the center of the triangle. Bring its
Properties
dialog and change its
FillColor
to red to make the marker more visible.
Shift
+click on the control point of the marker object and name it "
Anchor1
" in the
Control Point
dialog.
The Anchor1 and Anchor2 points will be used as origins (anchor points) for positioning the Icon1 and Icon2 templates in the drawing. We used two different methods to define an origin point. For Icon1 , we created a marker object at the desired location and named its control point Anchor1 . For Icon2 , we used the circle's control point, naming it Anchor2 , which will be visible as Icon2/Anchor2 resource.
We now have a composite template drawing, or a palette, containing multiple representations of an icon: Icon1 and Icon2 . Save the drawing as palette.g . Let's now use it to create a subdrawing with object dynamics.
Create a new drawing using
File, New Widget
. Create a subdrawing object by clicking on the Subdrawing
button. Define subdrawing's position by clicking anywhere in the drawing. In the
File Selection
dialog, select
palette.g
as a subdrawing file.
Type " Icon1:Anchor1 " in the Text Entry dialog for the ObjectPath and press OK. It directs the subdrawing to render the Icon1 object of the template and anchor it using the Anchor1 point.
Shift +click on the control point of the subdrawing and name it " Position " in the Control Point dialog. Click OK to close the dialog.
Bring the Properties dialog for the subdrawing object. Name it " Airplane " and set the HasResources =YES. The subdrawing's Source attribute is set to File , and its Source Path attribute points to the palette.g file. Change the SourcePath property so that it has only a filename (" palette.g" ), without the directory path. Using a relative file name without the path makes it easier to move the drawing to other machines and directories.
The subdrawing object with the file dynamics we created earlier in this chapter ( subdrawing.g ) used several templates, each containing a single graphical representation of the icon. The new subdrawing object we just created, Airplane , uses a template subdrawing ( palette.g ) which contains multiple objects, or multiple representations of an icon.
The ObjectPath property of the subdrawing object defines the name of an object in the template to use as an Instance for rendering the subdrawing. It also defines (after a colon) a name of the anchor point: this point of the template will be placed at the position of the subdrawing object's control point.
In our example, Icon1 is the object name (the resource path in the palette.g file) of the template object to be used as a graphical representation for the Airplane subdrawing object. Anchor1 is the resource path of the point to be used for "anchoring" the template object. This point will be placed (mapped) at the location of the subdrawing's Position point.
Now let's add object dynamics. Click on the ellipsis button next to the ObjectPath attribute to bring its Attribute Object dialog. Add List dynamics to the attribute by clicking on the Dynamics Add button and selecting the List transformation.
In the Edit Dynamics dialog of the list transformation, name the ValueIndex attribute " IconState ": its value will be used to select the list items. Click on the ellipsis button next to the List Of Values attribute to display the list. Select the Item0 list item to bring its Attribute Object dialog and notice that its value has been already set to " Icon1:Anchor1 ".
Select the Item1 list entry and type " Icon2:Icon2/Anchor2 " in the value field of the Attribute Object dialog. The Icon2 object and the Icon2/Anchor2 anchor point will be used to render the subdrawing when the list item is selected. Close all dialogs.
With the Airplane object still selected, display its resources using the resource browser. Select the IconState resource and alternate its value between 0 and 1: when IconState =0, the Icon1 object is used to represent the icon, and when IconState =1, the Icon2 object with a circle is displayed. The circular icon may be used when the airplane direction is not determined and there is no data to set its Angle attribute.
Object dynamics is used to alter the icon's appearance based on some value, indicating the icon's state. Object dynamics is implemented by attaching a list transformation to the ObjectPath attribute of a subdrawing object. The SourcePath attribute should point to a template drawing file containing multiple representations of the icon.
Unlike file dynamics, the object dynamics feature has an advantage of having a single drawing file (a palette file) that contains all representation of an icon, as opposed to having a separate file for each representation. The same palette file may be used across multiple drawings.
There is yet another type of a reference called a Palette Reference.
In some cases, it is not desirable to keep a palette of icon's representations in a separate file. The Toolkit provides an alternative method, where the palette is stored in the drawing.
Let's create a palette reference. Load the
palette.g
drawing. Create a group object enclosing both
Icon1
and
Icon2
. Make a copy of the group by using either the
Edit, Copy
menu option or the
Copy
toolbar button.
Create a new drawing using the File, New Widget . Go up the hierarchy, so that the $Widget viewport is selected.
Create a new viewport object by clicking on the
Viewport
button and selecting two points in the drawing to define its area. Bring the viewport's
Properties
dialog, name it "
$Palette
" and set its
HasResources
=YES. Close the
Properties
dialog.
$Palette is a predefined name, like $Drawing or $Widget . It is used as a default name of a palette viewport to create Palette Reference objects.
Use the
Hierarchy Down
button to go down into the
$Palette
viewport. Paste the previously copied template group with
Icon1
and
Icon2
objects using either the
Edit, Paste
menu option or the
Paste
toolbar button. Explode the group by using the
Explode
button, as the group is no longer needed.
Now we have a viewport named $Palette that contains two icon representations, Icon1 and Icon2 .
Go up the hierarchy. Select the $Widget viewport and go down into it.
Create a Palette Reference object by using the Object, Create, Reference, Palette Reference menu option.
Click anywhere in the drawing to define reference object's position. In the Text Entry dialog, type Icon1:Anchor1 as the value of the ObjectPath and press OK .
A " Missing <$Palette> palette object " error will be generated, and an " Unresolved reference object " text will be displayed in place of a newly created reference object. The error is generated because the $Palette object is outside of the scope of the current drawing. Ignore the error and click on the Hierarchy Up button to go to level where the palette object is visible. There will be no errors and the palette reference will be displayed properly, with a triangular icon and a label.
Click on Hierarchy Down again to go down into the $Widget viewport, and notice that the are no errors: once the palette object is resolved, its location is remembered. Select the reference object and bring its Properties dialog. Name the object " Airplane " and set its HasResources =YES. Notice that its Source = Palette (as opposed to File ) and the SourcePath is empty, causing the reference to use the default palette name: " $Palette" .
If the palette has a different name or located not at the top level of the drawing hierarchy, the SourcePath attribute defines the palette path. For example, for a palette named " MyPalette " located inside the $Widget viewport, the SourcePath may be set to " $Widget/MyPalette" . The palette resource path is resolved at the drawing loading time, so it may be necessary to save and load the drawing back to get rid of the initial error when the palette reference object is just created.
The value of the ObjectPath attribute of the palette reference object is " Icon1:Anchor1 ". It may be changed to "Icon2:Icon2/Anchor2" to display the second icon type with a circle. List dynamics may be attached to the attribute to switch icons based on the value of the list dynamic's ValueIndex attribute, as described in Object Dynamics above.