20002016
Ericsson AB. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Interface Functions
gs_chapter2.xml
Overview
The following interface functions are included with the graphics system:
- This function starts the graphics server and returns its object identifier. If the graphics server has already been started, it returns its original identifier.
- This function stops the graphics server and closes all windows which has launched. This function is not the opposite of because causes all applications to lose the graphics server and the objects created with the system.
- This function creates a new object of specified as a child to the specified . It configures the object with and returns the identifier for the object, or .
- This function is identical to the previously listed function, except that a is specified to reference the object. is an atom.
- This function destroys an object and all its children.
- This function configures an object with . It returns , or .
- This function reads the value of an object option. It returns the value, or .
The above list contains all the function which are needed with the graphics system. For convenience, the following aliases also exist:
These shorthands can be used as follows:
The function is useful for creating a large hierarchy of objects. It has the following syntax:
| {error,Reason}
]]>
is a list of , and is any of the following:
The following example constructs a window which contains two objects, a button and a frame with a label:
A First Example
The first action required is to start up the graphics server. This operation returns an identifier for the server process, which registers itself under the name . If a graphics server was already started, its identifier is returned. We can now create objects and configure the behavior and appearance of these objects. When all objects are created and configured in a top level window, we map it on the screen to make it visible. The example below shows how to create a window with a button that says "Press Me".
The following steps were completed in this code:
- start a graphics server
- create a window of specified width and height
- create a button with the text "Press Me"
- map the window on the screen
- enter the event loop.
The event loop is where we receive events from . In this case, we want to receive a click event from the button. This event is delivered when the user presses the button.
"Press Me" Button Example
The Erlang system includes many examples. All examples in this document can be found in the directory. In addition, there is an example directory which contains examples of fractal trees, bouncing balls, a color editor, and a couple of other applications.
Creating Objects
You create an object of a specified type with the or the function. The difference is that the function allows you to assign names to the objects. You can then refer to the object instead of using the object identifier. The two forms of the function look as follows:
Examples of built-in object types are:
- window
- frame
- menu
- button
- radio button
- list box.
Objects are created in a hierarchical order. The top level object is the window object which is a container object for most other object types.
Hierarchy of Objects
A frame object is like a sub-window but also a container object which can have children objects.
The or functions return an object identifier, or the tuple . The object identifier uniquely identifies the object within the system. The object identifier is used to:
- reconfigure an object
- identify events from a particular object.
Ownership
The process which creates an object is said to own the object. When a process dies, all objects owned by the process are destroyed. The ownership also means that all events generated by a specific object are delivered to the owner process. The graphics server keeps track of all Erlang processes that create objects. It is therefore able to take appropriate actions if a process should die.
Naming Objects
As shown previously, the function can be used to name objects. The name should be a unique atom which is used to reference the object. The advantage of naming objects is that we do not have to pass object identifiers as arguments to the event loop. Instead, we can use the object name in our code. To name objects in the following example, the code gives the name to the window, and to the button.
The name is local for the process which creates the object. This means that the name have a meaning only for one process. Different processes can give different objects the same name. When passing references to objects between processes, the object identifier has to be used because names only has a meaning in a process context. If necessary, the object identifier can be retrieved by reading the option.
When using distributed Erlang, objects should be named carefully. A named object always refers to an object in the graphics system on the node where it was created. The syntax should be used when referring to a named object on another node.
The following example receives a canvas object from another node and creates a line named that will appear in the canvas. Also, this example demonstrates how to configure the line using the special syntax.
receive
{gs_obj,Canvas,FromNode} -> ok
end,
gs:create(line,myline1,Canvas,[{coords,[{10,10},{20,20}]}]),
gs:config({myline1,FromNode},[{buttonpress,true}]).
]]>
Unnamed objects are transparent. For example, a line object can be created from a canvas on another node and then configured as any other object.
receive
{gs_obj,Canvas,_FromNode} -> ok
end,
L = gs:create(line,Canvas,[{coords,[{10,10},{20,20}]}]),
gs:config(L,[{buttonpress,true}]).
]]>