18 Graphical User Interface

In this section we will show how to use the device independent library called GUIEnv.

18.1 GUIEnv

GUIEnv is a device independent graphical user interface library, intended for making applications with graphical user interfaces running on:

GUIenv realizes user interfaces of many different look-and-feels. GUIenv allows construction of portable user interfaces in such a way that the look-and-feel of the applications, will conform to the standardized look-and-feel of the specific platform.

The basic GUI library is defined in the file '~beta/guienv/guienv'. An application with a graphical user interface, thus must have origin in this file. The guienv library defines a pattern also called guienv in which all the user interface attributes, operations, and patterns are available. So every GUIEnv application typically has the following outline:

ORIGIN  '~beta/guienv/guienv';
-- program: descriptor --
guienv
  (# (* write GUI code here *)
  #)

Our task will be to develop a simple texteditor that can open a text file, edit the file and save the file. We would like an application that looks like the following (Motif version):

We will need a window to display the text in. guienv defines a window pattern, that we can use. We would like that this window is opened when the application starts up, so in the do part of the specialization of guienv we open the window.

guienv
(# theWindow: @window
     (# ...
      #);
do theWindow.open;
#);

Inside the window we want a texteditor that can contain the text from the file. guienv supplies a textEditor for this purpose:

theWindow: @window
  (# thetextEditor: @textEditor
       (# open:: 
            (# 
            do theWindow.size -> Size; 
               True -> bindBottom; True -> bindRight 
            #)
       #);
     open::(# do thetextEditor.open #);
  #);
do theWindow.open;

The lines:

open:: 
  (#
  do theWindow.size -> Size; 
     True -> bindBottom; True -> bindRight 
  #);

means that we extend the open virtual of textEditor, set the size of the textEditor to be same size as the window, and bind the textEditor to the bottom and right corners of the window.

The next thing we need to do, to complete the user interface is to make a menu. The application should have a menu with three items: open a file, save the file, and quit the application. guienv supplies a standard menubar on each window for this purpose. We extend the standard menubar with one menu called File, and we make three items in this menu called Open, Save, and Quit.

menubarType::
  (# fileMenu: @menu
       (# openItem: @menuitem
            (# ... #);
          saveItem: @menuitem
            (# ... #);
          quitItem: @menuitem
            (# ... #);
          open::
            (# 
            do 'File' -> name;
               openItem.open; openItem[] -> append;
               saveItem.open; saveItem[] -> append;
               quitItem.open; quitItem[] -> append;
       #)#);
     open::(# do fileMenu.open; fileMenu[] -> append #);
  #);

Like the textEditor, we extend the open virtual of the File menu to open and append the three items and to give the menu a title.

Each menuitem has two virtuals that needs to be extended: eventHandler and open. For the quit item we do the following:

quitItem: @menuitem
  (# eventHandler:: 
       (# onSelect::(# do Terminate #)
       #);
     open::(# do 'Quit' -> name #);
  #);

The eventHandler has a virtual called onSelect that is invoked whenever this menuitem is selected. We call Terminate (defined in guienv) to stop execution. The open virtual is extended to give the item a name.

Finally, we need to do some file handling in the open and save items. The open item does the following when selected

onSelect::
  (# theText: @StyledText;
  do theWindow[] -> fileSelectionDialog -> textFile.name;
     textFile.openRead;
     textFile.scan
       (# while:: (# do true->value #);
       do ch -> theText.put
       #);
     theText[]->theTextEditor.contents.contents;
     textFile.close;
  #)

First we call fileSelectionDialog that opens a standard file open dialog and returns a name of a file that we can open (we ignore errors, pressing cancel, etc.). We open the file, read all the file content into a StyledText and sets the StyledText as the content of the textEditor. StyledText is a specialization of Text with specification of face, font, size, etc.

The save item does the following when selected:

onSelect::
  (# theText: @Text;
  do textFile.openWrite;
     theTextEditor.contents.contents->textFile.puttext;
     textFile.close;
  #)

Because StyledText is a specialization of Text we can write the StyledText contents of the TextEditor directly to the file using the puttext operation.

We open the same file, write the textEditor content into the file and close the file.

The complete code needed for this application is shown below.

Program 25: TextEditor.bet

ORIGIN '~beta/guienv/guienv';
INCLUDE '~beta/guienv/fields'
        '~beta/guienv/stddialogs'
        '~beta/basiclib/file'
-- program: descriptor --
guienv (* inherit from guienv *)
(# theWindow: @window (* make a window *)
     (# menubarType:: (* extend the menubar *)
          (# fileMenu: @menu (* make a file menu *)
               (# textFile: @file; (* the file we open and save *)
                  openItem: @menuitem (* make an open item *)
                    (# eventHandler:: (* extend the virtual that is called *)
                         (# onSelect:: (* this menu item is selected *)
                              (# theText: @StyledText;
                              do theWindow[]->fileSelectionDialog 
                                   -> textFile.name;
                                 textFile.openRead;
                                 textFile.scan
                                 (# while:: (# do true->value #);
                                 do ch->theText.put
                                 #);
                                 theText[]->theTextEditor.contents.contents;
                                 textFile.close;
                         #)#);
                       open:: (# do 'Open'->name #);
                    #);
                  saveItem: @menuitem (* make a save item *)
                    (# eventHandler:: (* extend the virtual that is called *)
                         (# onSelect:: (* this menu itme is selected *)
                              (# theText: @Text;
                              do textFile.openWrite;
                                 theTextEditor.contents.contents->textFile.puttext;
                                 textFile.close;
                         #)#);
                       open:: (# do 'Save'->name #);
                    #);
                  quitItem: @menuitem (* make a quit item *)
                    (# eventHandler:: (# onSelect:: (# do Terminate #) #);
                       open:: (# do 'Quit'->name #);
                    #);
                  open:: (* extend the open virtual of filemenu to open the items *)
                    (# 
                    do 'File'->name;
                       openItem.open; openItem[]->append;
                       saveItem.open; saveItem[]->append;
                       quitItem.open; quitItem[]->append;
               #)#);
             open:: (* extend the open virtual of the menubar to open the filemenu *) 
               (# do fileMenu.open; fileMenu[]->append #);
          #);
        thetextEditor: @textEditor (* our text editor *)
          (# open:: (* extend the open virtual to set the size and the placement *)
               (# 
               do theWindow.size->Size;
                  True->bindBottom; True->bindRight 
               #);
          #);
        open:: (* extend the window open virtual to open the textEditor *)
          (# 
          do thetextEditor.open;
          #);
     #);
do theWindow.open; (* open the window when the application start up *)
#)

The two screen snapshots following below show how this application appears on Windows NT and Macintosh after the program has loaded its own source code for editing, and with the menu opened. The Motif version was shown above.

Windows NT

X Window System - Motif

Macintosh

More details and examples about the GUIEnv libraries can be found in [MIA 94-27].


Libraries Tutorial
© 1994-2002 Mjølner Informatics
[Modified: Monday November 12th 2001 at 20:38]