The GLG Graphics Builder is a flexible and powerful tool for the creation and animation of GLG drawings. The GLG Toolkit also provides a variety of ways to incorporate GLG drawings into your applications and supplies several facilities designed to draw and control a GLG drawing from within a user's application program at run time.
The steps required to operate a GLG drawing from a program are straightforward, and most of them are platform-independent:
Create a usable GLG widget . This is simply a GLG drawing that contains a viewport named $Widget , whose HasResources attribute is set to YES. This can be done interactively with the GLG Graphics Builder, or by a program, using the GLG Extended API Library .
Load the drawing into an application program, and display it in a window. This step often involves platform-specific accommodations. Under Microsoft Windows, you can use the GLG Custom Control , the GlgControlC MFC class or the GLG OCX Custom Control to display a drawing. The GLG Wrapper Widget is designed to work in the Unix and X Window environment, and the GLG Generic API Library is a platform-independent display solution for those who need the source code portability. For Java applications, GlgBean provides a GLG Java Bean for displaying the drawing, and GlgObject class provides a generic API for displaying the drawing.
Control the drawing by querying and setting resources. This is done with the GLG Standard API .
The following sections of this chapter provide details about each of these steps, and about issues important to GLG Toolkit programmers.
Most widgets are created with the GLG Graphics Builder. Any GLG drawing with a viewport at the top level of its resource hierarchy can become a GLG widget, simply by defining the name of that viewport to be $Widget . The viewport's HasResources attribute must be set to YES in order for its resources to appear inside the viewport.
A widget can also be created from a program, using the GLG Extended API, as long as it satisfies the restrictions noted above. The Extended API is described in detail in The GLG Extended API on page 97.
If you save a GLG drawing into a file, there are three different file formats it may use:
The binary format is the fastest format to use for loading drawing files, but not compatible between hardware platforms with different binary data representations. The binary format differs between the C/C++ and Java version of the Toolkit as well, since Java uses its own binary representation of data.
The ASCII format is slightly slower to load (though more compact) than the binary format and is compatible between different hardware platforms. Is is also compatible across the C/C++ and Java versions of the Toolkit. The ASCII format is the default save format and the preferred format for the Java version of the Toolkit.
The extended format is the slowest and the least compact but provides the ability to transfer drawing files between different versions of the Toolkit. It may be used to import the drawings saved using a newer release of the Toolkit into an older version (if the drawing uses the new features of the newer release, the conversion for these features or for the whole drawing may fail). The extended format is not supported in the Java version.
If the widget is to accept input from a user, some extra steps must be taken to build it. You may need to add interaction handlers to some of the viewport objects in the drawing, and equip the drawing with one or more callback functions . A callback function is supplied by the programmer, and is executed by the GLG Toolkit in response to various possible user actions. The considerations needed to construct an input widget are described in the Input Objects of the GLG User's Guide. Object selection and custom event handling is described in Integrated Features of the GLG Drawing of the GLG User's Guide.The structure of a callback function is described in Handling Input Events of this manual.
Displaying a widget is one of the few platform-dependent steps in the process of animating a GLG widget. The necessary steps for displaying a widget under X Windows or Microsoft Windows are both covered in Displaying a GLG Drawing on page 17. You only need to read the sections of that chapter that apply to the windowing environment and the version of the Toolkit you intend to use for your application (C/C++, ActiveX or Java).
Before a widget can be displayed by a program, it must be loaded into memory. There are three ways to do this:
A drawing may be stored in a separate file. This lets the user of an application customize the appearance of the widget by editing the file using the GLG Graphics Builder.This option is also very convenient in the development stage, allowing you to modify the drawing without additional compile/debug cycles.
A drawing may also be converted into a memory image in a C language format using the Toolkit's gcodegen utility. This allows you to compile and link the drawing directly into the program's executable. Embedding a drawing into the executable increases its size, and prevents users from modifying the drawing, but reduces the number of additional files needed by an application. See Code Generation Utility on page 262 in GLG Programming Tools and Utilities for more details. Memory images are not supported in the Java version of the Toolkit, where the drawing may be placed inside of the application's jar file.
A program may also generate a drawing from scratch using the GLG Extended API. Although this is possible, it is usually simpler to load a drawing template from a file and reserve these functions for modifying the template drawing and adding new objects to it. The Extended API is described in The GLG Extended API on page 97. The Extended API for the Java version of the Toolkit is described in Using the Java version of the GLG Toolkit.
A GLG widget is controlled from a program in the same way it is controlled from the GLG Graphics Builder: by setting and querying resources. An application program uses the GLG Standard API Library to query and modify a widget's resources. These functions are described in Animating a GLG Drawing Using the Standard API.
The Extended API (described in The GLG Extended API on page 97) may be used to add or delete objects, traverse the object hierarchy and implement custom object manipulation such as dragging an object with a mouse, constraining object attributes and attaching dynamics at run time.
In the static picture of the GLG drawing architecture that was sketched in the introductory chapters of this guide, all resources are of equal status. All resources are attributes of some object, and they can all be modified or created as the need arises. However, while a drawing is in flux (while it is being drawn, for example), some resources need to be treated differently than others. Because of this need, two different categories of resources exist: those that affect simple values and those that affect the resource hierarchy itself.
The H (hierarchy) and V (value) drawing resources differ in when they are processed by the widget. The H resources are processed before creating the drawing hierarchy, while the V resources are processed after it has been established. The H resources can affect the structure of the hierarchy itself, for example by controlling the number of objects in a series, while the V resources are processed after the specified number of objects in the drawing hierarchy have been created.
A series object, for example, replicates its template object to produce a number of instances. The series' factor defines how many objects appear in that series. Referencing the eighth object in a series makes no sense before the instances of objects are created. The value of the series factor is another example of an H resource. Setting the factor value with a V resource would work, but would introduce inefficiency, since the drawing hierarchy would first be created with the number of series instances defined by the old value, then destroyed and the new number of instances would be created. Other example of H resources are the non-global attributes of a series template. The template is replicated at the time of hierarchy setup, and its attributes have to be set before the hierarchy is set up in order for the instances to inherit the template's attribute values. All H resources are processed before the drawing hierarchy is created, which guarantees that all resources depending on the number of objects in the drawing hierarchy are accessible.
V resources are used for setting resources that depend on the structure of the drawing hierarchy or that do not exist or are inaccessible before creating the hierarchy. Consider an example where the GLG Toolkit, in a program called "example," reads a bar graph with 10 data samples from a drawing file. We'd like to change the number of data samples to 100 and to have the color of the 25th data sample appear red when the widget is displayed.
Let's start with setting the value of the "DataGroup/Factor" resource of the widget to 100. Because this resource affects the hierarchy of the drawing, we use an H resource. Using the X Windows protocol for setting resource values, we might use a line in the configuration file such as:
example*XtNglgHResource0 "DataGroup/Factor d 100"Using the OCX control for Microsoft Windows, it would be:
HProperty0: DataGroup/Factor d 100
Using a V resource to set this value would make the GLG Toolkit create a drawing with 10 data samples, discard it, and create another drawing with 100 data samples. Careful use of H and V resources can avoid this kind of inefficiency.
Now we want to set the color of the 25th data sample to be red. However, the original drawing has only 10 data samples; so the 25th data sample does not exist in the drawing. Because of the 25th data sample does not exist until all the H resources are processed, its color cannot be set using H resources. Trying to do so generates an error message saying that the resource cannot be accessed.
To change the color of a graphical object, you only change the value of a data object in the hierarchy; you do not change the hierarchy. Therefore, a V resource is appropriate for this purpose. These are treated after the specified data sample has been created and is accessible. The line in the configuration file for our example program would then look like this:
example*XtNglgVResource0 "DataGroup/DataSample24/FillColor g 1. 0. 0."Note that since the index is zero-based, the number 24 is used to access the 25th data sample.
Using the OCX control for Microsoft Windows, it would be:
VProperty0: DataGroup/DataSample24/FillColor g 1. 0. 0.
To set the resources that do not depend on the number of objects in the drawing hierarchy, you may use either H or V resources. For example, you can set a background color of the widget's drawing using either kind of resource. Note, however, that many resource names depend on the structure of the resource hierarchy to be accurately interpreted.
If you use functions from the GLG API to set drawing resources, the same considerations apply. You can dramatically increase the efficiency of your application program, and avoid introducing errors, by simply insuring that all the H resources that need setting are set first, before the V resources. In our example above, the Factor resource should be set first, then the GlgUpdate function should be called, and then the V resources set.
The GLG Toolkit contains a small number of utility programs for use by an application programmer:
datagen
Generates a variety of data streams used for testing and prototyping.
gcodegen
Creates a memory image of a GLG drawing in the C language format. The output of the utility is a file with .c extension, containing the image of the drawing in a form of the C source code. The output file can be compiled into the program's executable, saving users from having to supply a separate drawing file.
gconvert
A GLG drawing file may have one of three different formats: Binary, ASCII, or Extended. The Binary files are the fastest to load, but the Extended and ASCII files are more portable. The
gconvert
program converts drawing files from one format to another. The utility can also be used to change resources of a drawing in a batch mode using the script command option.
These tools are described in detail in GLG Programming Tools and Utilities on page 247.
The details of the process of linking an application program with the GLG Toolkit library depends on the operating system and windowing environment where the application will run.
The OpenGL libraries for the OpenGL renderer - libGL and libGLU - are dynamically loaded by the Toolkit and do not need to be linked in the application executable. If an application uses OpenGL calls itself, it can link the OpenGL libraries, and the Toolkit will use the linked-in libraries.
The same application executable may be run in either the OpenGL rendering mode or the native windowing system (GDI) mode. Refer to OpenGL or Native Windowing System Renderer of the GLG User's Guide and Builder Reference Manual for details.
The libglg.a library supplied with the GLG Toolkit contains all functions described in this guide, including the GLG Standard Library and GLG Generic API Library. The linking process also requires libz1 and libjpeg2 libraries, as well as the libglg_map Map Server library and libtiff3 and libfreetype4 libraries. All these libraries are provided in the lib subdirectory of the GLG Toolkit installation. The GLG libraries must be included in the link list before the X and Motif libraries. The following line shows a sample of the link statement for the GLG program using the Standard API and the Map Server on Solaris platform:
... -lglg -lglg_map -lz -ljpeg -ltiff -lfreetype -lXm -lXt -lX11 \If an application does not use the Map Server and GIS functionality, the libglg_map library may be replaced with the libglg_map_stub stub, and the libtiff and libfreetype libraries may be omitted. The following line shows a fragment of the link statement for the GLG program using the Standard API without the Map Server and GIS functionality:
... -lglg -lglg_map_stub -lz -ljpeg -lXm -lXt -lX11 \If the application uses the Map Server and GIS functionality, but does not need the TrueType font support in the Map Server, the libfreetype library may be replaced with libfreetype_stub.
The GLG Extended Library is called libglg_ext . It requires the Standard API library ( libglg ) as well as all libraries described above. The following two lines show examples of linking with and without the Map Server and GIS functionality:
... -lglg_ext -lglg -lglg_map -lz -ljpeg -ltiff -lfreetype \The GLG Extended Library can be omitted if an application does not use any of the Extended API functions.
Under Microsoft Windows, you can choose whether to use a static or dynamic library. The static version of the GLG Standard Library is called GlgLib.lib. The Toolkit uses the DLL by default. In order to use the static version of the GLG Standard Library, define GLG_STATIC in your code:
#define GLG_STATICThis must appear before the GlgApi.h file, or it may be specified as a preprocessor definition in the project's settings.
To use the static library, you must also call GlgInit , passing an explicit application instance as the application context parameter. (If the dynamic library is used, this happens automatically at the DllMain entry point.)
The static version of the library was compiled using the multi-threaded DLL compilation option. Your code must be compiled using the same option in order to link your application with the GLG static library.
The static version of the GLG Extended Library is called GlgExLib.lib . It requires linking with the static GLG Standard Library ( GlgLib.lib ).
The DLL version of the GLG library is called Glg.dll. To use it, you must link your program with the supplied Glg.lib library.
The GLG Extended API DLL is called GlgEx.dll and includes the GLG Standard API DLL. This means you don't have to link with the Glg.dll if using GlgEx.dll. Link only with the GlgEx.lib library to use the Extended Library DLL.
All GLG library errors are reported using the default error handler. In the X Windows environment, this prints an error message on the console, and under Microsoft Windows, displays a message box with an error message. On both platforms the default handler also beeps and logs the error into the glg_error.log file. The log file will be created in the directory specified by the GLG_LOG_DIR environment variable, or the GLG_DIR environment variable if the GLG_LOG_DIR variable is not set. If neither variable is defined, the current directory will be used. In the Java version, the errors are printed on the standard output stream, or in the Java Console when used inside of a web browser.
The Map Server errors are logged in the glm_error.log file, which will be created in the directory specified by the GLM_LOG_DIR environment variable. If GLM_LOG_DIR is not set, either GLG_LOG_DIR or GLG_DIR environment variable is used to determine the directory in which the Map Server log file will be created. If neither environment variable is defined, the current directory is used.
To intercept errors or to change this behavior, you may install a custom error handler using the GlgSetErrorHandler function. (This is part of the standard GLG API; see the Animating a GLG Drawing Using the Standard API.). Severe internal errors (like invalid object handles) will still be logged into the glg_error.log file, but errors involved with the use of the GLG Toolkit, like not being able to set or get a resource, will not.
In the X Windows environment, widget-related errors (such as an error setting the wrapper widget's resource) are reported using XtError function. You can use the XtSetErrorHandler function to install a custom Xt error handler.