<< Prev | - Up - | Next >> |
The example given in this chapter describes how a user interface is built using the QHTML module. The creation of the widgets, their geometry inside the window and their interaction with Mozart are described.
The example application will consist of a window composed by
A toolbar with the following buttons : Save, Load, a file selection button and Quit.
A main area where the user can type the text.
The construction of a window is completely described by a record. This record defines the widgets that compose the window, how these widgets must be placed and what is their behaviour upon window resizing. The label of the record defines the widget that must be placed. The content of the record defines the parameters of the widget. Some widgets act as containers for other widgets. The two main containers are :
td : all widgets contained in this one are placed top to down
lr : all widgets contained in this one are placed left to right
The toolbar is composed of button widgets and a file selection widget. The value parameter defines the text of the button.
The toolbar is described by :
Toolbar=lr(button(value:"Save")
button(value:"Load")
file
button(value:"Quit"))
which literally means : place these four widgets buttons respectively from left to right, each widget taking the size it needs to display itself. Combining with the textarea widget, we obtain :
Desc=toplevel(td(Toolbar
textarea))
which literally means : inside the main window (toplevel
widget), place the toolbar and the textarea
respectively from top to bottom, each widget taking the size it needs to display itself.
Now we can build a window from this description by the command :
Window={QHTML.build Desc}
This window is not displayed inside any Internet Browser by default. To open a new IE window and display the QHTML components inside it, execute :
{Window show}
The result so far is not very good : widgets have a fixed size upon window resizing and don't fit as wanted.
One expects the toolbar to stick itself to the top left of the window, and the text widget to take all remaining available size below. All widgets have a glue parameter that allow to specify contraints to the geometry manager. Valid values for the glue parameters are atoms that are combinations of n
, s
, w
and e
. By default a widget takes as much place as it needs to draw itself, and if the area in which it is drawed is bigger than that size, the widget is centered inside. By specifying n
(resp s
, w
, e
) you enforce the north (resp south, west and east) border of the widget to glue to its top (resp down, left, right) neighboor. If you specify both ns
(resp we
) you enforce both opposite border to stick to their respective neighboor, resulting in the widget taking all the vertical (resp horizontal) space available.
Using the glue
parameter we define :
Toolbar=lr(glue:nwe
button(value:"Save" glue:w)
button(value:"Load" glue:w)
file(glue:w)
button(value:"Quit" glue:e))
and also
Desc=toplevel(td(glue:nswe
Toolbar
textarea(glue:nswe)))
Rebuilding and showing the window, we obtain an application that has a complete graphical user interface, except that it is an empty shell.
An action can be associated to buttons. It is executed when the user clicks the button :
button(value:"Click" action:OzProcedure)
We can define procedures for the three buttons of the application. The Load
and Save
procedures will take the name selected in the file
widget and load it into the textarea
widget or save its content.
We need a way to dynamically get the state of the file
widget to get the selected name, and a way to change or get the contents of the textarea
widget. This can be achieved by using handle
parameters : when the window is built, variables specified as handle
parameters are bound to Oz objects controlling the corresponding widget. The modified code now looks like :
FH % FileHandler
TAH % TextAreaHandler
Toolbar=lr(glue:nwe
button(value:"Save" glue:w action:Save)
button(value:"Load" glue:w action:Load)
file(glue:w handle:FH)
button(value:"Quit" glue:e action:Quit))
Desc=toplevel(td(glue:nswe
Toolbar
textarea(glue:nswe handle:TAH)))
When the window is built, the contents of the textarea widget can be obtained by :
{TAH get(value:$)}
and set by :
{TAH set($)}
The selected file in the file
widget can be obtained by :
{FH get($)}
Here are the definitions of the three procedures defined as action
by the buttons :
proc{Save}
try
File={New Open.file init(name:{FH get(value:$)}
flags:[write create truncate])}
{File write(vs:{TAH get(value:$)})}
in
{File close}
{Window alert("File successfully saved.")}
catch _ then
{Window alert("Unable to save file.")}
end
end
proc{Load}
try
File={New Open.file init(name:{FH get(value:$)})}
Data={File read(list:$ size:all)}
{File close}
in
{TAH set(value:Data)}
catch _ then
{Window alert("Unable to load file. Check if specified file exists.")}
end
end
proc{Quit}
{Window close}
end
The application is now complete ! Here is the full code.
<< Prev | - Up - | Next >> |