Difference between revisions of "How to use GUI Package in Visual Prolog"

From wiki.visual-prolog.com

(Move from WEB)
(No difference)

Revision as of 00:32, 26 August 2007

A sample Graphical User Interface (GUI) application can be created by Integrated Development Environment (IDE) as a default project. In this tutorial, we will explain how to develop such application further. We will learn how to create and edit GUI components of GUI style programs directly within the Visual Prolog IDE (Visual Development Environment). We will learn principles of handling GUI package events (like clicking buttons, activating menu items, etc.), and how these are implemented within GUI style Visual Prolog programs. We will learn how to program dialogs, etc.

The GUI package presents object-oriented windows, dialogs, and controls handling. This package is built on top of the VPI package and delivers a new level of abstraction and ease of use. When using the GUI package, you can also use the VPI package.

Introduction to the GUI Package

If you have read our previous GUI programming tutorials "Fundamental Visual Prolog - Conventional GUI" and "Fundamental Visual Prolog - the Business Logical Layer", then you already knew that Visual Prolog PFC packages contain the VPI package, which can be used to program Graphical User Interface applications. But VPI package classes do not produce GUI objects. Therefore VPI does not supply the power of state handling via interface predicates.

The GUI package provides an object oriented style for working with windows, dialogs, controls, events, and other GUI features. The GUI package provides the following window system components, which supports programming of your application presentation layer (GUI of your application):

  • Basic window components: windows, dialogs, controls (check buttons, edit controls, icon controls, list boxes, list buttons, list edit controls, push buttons, radio buttons, horizontal and vertical scroll controls, static text controls, custom controls, and some more complex controls like the editor, tree view and list view controls, etc. ).
  • Containers - objects to which you can add controls (these are dialogs, container controls, form windows, etc.).
  • Layout management system that supports sizing, positioning, and moving of GUI objects.
  • The GUI package event handling system. It notices when the user interacts with one of GUI components and pass this information to the application.
  • Graphic operations: draw arcs, fill polygons, clip a rectangle, etc.


Creating a New GUI Style Project

Now let us start creating a GUI style project from the very beginning.

First of all, you need to run the IDE. At this point we expect that you had already read the Environment Overview tutorial and know how to do this.

Then you should initiate creation of a new project selecting the Project | New menu command. The Project Settings dialog appears. In the Project Name edit control you should type-in the project name, in this example we use guiDemo. Keep the settings (UI Strategy, Target Type, Linker Name) in their default state. You can also select the Base Directory, which will serve as the default root directory to all your new projects. The default Sub-Directory name will be generated automatically, as you will type-in the Project Name (of course, you can manually modify this name). So we have:

  • Project Name = guiDemo
  • UI Strategy = Object-oriented GUI
  • Target Type = EXE

Click Create to create the default project. After this the IDE will generate the initial set of project files required to a GUI style project.

Execute the Created Default Project '

As you can expect the default project creates a trivial but working application, to check this let us run the generated default application. You can run it directly from the IDE using the Build | Execute command or simply press the F9 key.

How to Study the Generated Code

All components of your application are registered in the Project window. Here you can see the initial set of project files generated by the IDE to a default GUI style project in the IDE Project window (remember that previously you need to build the project using, for example, the Build | Build command or simply press the Alt+F9 key combination). You will see in the Project window the following tree of the project files:

GUI Package Project tree0.png

You see that the root directory of your project contains the following files:

  • guiDemo.pack this is the main package of our application.
  • guiDemo.ph this is the header file of the application main package.
  • guiDemo.cl this class declares the application main predicate run.
  • guiDemo.pro this file implements the application main predicate run and declares the standard application goal.
  • resourceidentifiers.i this file is automatically updated by the IDE after any changes of project resource identifiers. It contains definitions of symbolic constants specified for GUI components in the IDE resource editors.

Notice that you should not make any editing in it since any your changes will be overwritten while automatic update.

The $(ProDir)\PFC subdirectory contains that Prolog Foundation Classes (PFC) packages, which are used by the default GUI style applications. Each package is in a separate subdirectory. For example, the gui subdirectory contains GUI package source files and you can see implementation details of GUI package itself here. Source files of these packages will be compiled and the obtained OBJect files will be linked into the target application.

In the first step we will modify Task Window, therefore let us see which files are generated in the taskWindow package. Simply click on the '+' box before the taskWindow subdirectory and then click on the '+' box before the appeared Toolbar subdirectory. You will see the following files:

GUI Package Project tree2.png

At this picture you see that the IDE generates files containing the following GUI components:

  • the main Task window of the application (stored in the .\TaskWindow\TaskWindow.win file);
  • the main application menu (stored in the .\TaskWindow\TaskWindow.mnu file);
  • one top toolbar (stored in the .\TaskWindow\Toolbars\ProjectToolbar.tb file);
  • one bottom status bar or status line (stored in the .\TaskWindow\Toolbars\StatusLine.tb file);
  • the About dialog (in the .\TaskWindow\AboutDialog.dlg file).

These are text format files store resources describing GUI components generated for the project. Text descriptions stored in these files hold full information about correspondent GUI components, including resource attributes, resource layout, and settings for Code Experts. The resource files for GUI components are stored in files with .win, .frm, .ctl, .mnu, .dlg, .tb, .bmp, .ico, and .cur filename extensions.

Let us investigate contents of the TaskWindow.i file. You see that except for other code it contains the following line:

interface taskWindow supports applicationWindow

This means that the taskWindow interface supports the applicationWindow interface declared in the GUI package. Select applicationWindow and press the F1 key, the IDE will activate the Visual Prolog help and open the topic describing the applicationWindow interface. In this help you can read that the applicationWindow::new/0 predicate creates an applicationWindow type object correspondent to the Task windows of an application. Notice that the only one applicationWindow type object can be created during an application execution.

Now open the TaskWindow.pro file. You see the following clauses for the new/0:

clauses
    new():-
        applicationWindow::new(),
        generatedInitialize().
 
predicates
    generatedInitialize : ().
clauses
    generatedInitialize():-
        setText("guiDemo"),
        setDecoration(titlebar([closebutton(),
          maximizebutton(),minimizebutton()])),
        setBorder(sizeBorder()),
        setState([wsf_ClipSiblings]),
        setMdiProperty(mdiProperty),
        menuSet(resMenu(id_TaskMenu)),
        addCreateListener(generatedOnCreate),
        addCreateListener(onCreate),
        addSizeListener(onSizeChanged),
        addDestroyListener(onDestroy),
        addMenuItemListener(id_help_about, onHelpAbout),
        addMenuItemListener(id_file_exit, onFileExit).
 
    ...
 
 % end of automatic code

You see that the clauses of the new/0 constructor are splitted onto two parts. The clause of the new/0 constructor itself and the generatedInitialize/0 predicate, which is declared privately in the taskWindow class implementation. You can ask - "What for the extra the generatedInitialize/0 predicate is declared?" The answer to this question is in the lines:

% This code is maintained. Do not update it manually    ... end of automatic code

The IDE need them to be able to automatically change parameters, which corresponds to the settings in Code Experts.

How to Modify the Default Task Window

Before we start to add any new user defined GUI components to this default project, let us look how we can modify its default task window parameters. In the project file tree click the right mouse button on the TaskWindow.win file. In the appeared popup menu select the Attribute item. The Window Attributes dialog appears:

GUI Package WindowAttributes.png

In this dialog you see attributes of the task window. The Title field specifies the application title (name) guiDemo, which is displayed at run time in the application title bar. Let us modify it to GUI Demo Title.

The Style Flags group of check boxes contains the style flags, which will control the look of the window. Let us set Maximized to ON. If you run the application now, then you will see that it is maximized initially and has got the title GUI Demo Title.

How to Add New GUI Dialog

Let us create a new GUI dialog in TaskWindow package. You can of course use any package for this purpose. To create the dialog it is necessary to put focus on the necessary package in Project window and choose menu command File | New . You will see the dialog, where it is necessary to select Dialog type and write a name. We have chosen the name firstDialog:

GUI Package firstDialog.png

After pressing Create button you will be prompted to set attributes for the new dialog. You can keep default initial attributes at creation time and change the necessary attributes later.

The new dialog should be invoked on some event, therefore we modify TaskMenu menu by changing File | New text and making it enabled:

GUI Package TaskMenu.png

Now we should put focus on the TaskWindow\TaskWindow.win window in Project window and activate Code Experts:

GUI Package NewDlgEvent.png

IDE generates a default code for onFileNewDialog event, which we modify by invocation of firstDialog:

predicates
    onFileNew : window::menuItemListener.
clauses
    onFileNew(_Source, _MenuTag):-
        FirstGuiDialog = firstDialog::new(This),
        FirstGuiDialog:show().

You can run the application now and see that the firstDialog can be invoked.

How to Manipulate Controls in GUI Dialog or Form

Let us create two edit controls Edit and EditCopy in firstDialog and update the contents of EditCopy on all changes in the contents of Edit.

We should also add event handling for onModify event of Edit control. To do this we put focus on the TaskWindow\firstDialog.dlg dialog in Project window and activate Code Experts:

GUI Package EditModifyEvent.png

Then we can add the code to implement our intention:

predicates
    onEdit_ctlModified : editControl::modifiedListener.
clauses
    onEdit_ctlModified(_Source) :-
        editCopy_ctl:setText(edit_ctl:getText()).

Let us add a more complicated control now. Let us choose treeViewControl. In dialog editor we choose Controls | Custom command and write treeViewControl in the class name.

IDE can insert automatically the necessary declarations, therefore we add pfc\gui\treeViewControl\treeViewControl.pack package and then build our project.

You can run the project now and see that the tree is empty. We can add more code to initialize the tree view control:

constants
    myItemId = 10.
    myItemIdChild = 11.
clauses
    new(Parent) :-
        dialog::new(Parent),
        generatedInitialize(),
        my_ctl:insertItem(myItemId, treeViewControl::wcc_null,
           treeViewControl::sorted(),
           "Root",
           [], resId(idb_HelpBitmap), resId(idb_HelpBitmap)),
        my_ctl:insertItem(myItemIdChild, myItemId,
           treeViewControl::sorted(),
           "Child",
           [], resId(idb_HelpBitmap), resId(idb_HelpBitmap)).

Now the program can show a simple tree.

References