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

From wiki.visual-prolog.com

m (categorized)
Line 38: Line 38:
==Execute the Created Default 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.
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 '''Ctrl+F5''' key combination.


==How to Study the Generated Code==
==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:
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 '''Ctrl+Shift+B''' key combination). You will see in the '''Project''' window the following tree of the project files:


[[Image:GUI_Package_Project_tree0.png]]
[[Image:GUI_Package_Project_tree0.png]]
Line 48: Line 48:
You see that the root directory of your project contains the following files:
You see that the root directory of your project contains the following files:


*guiDemo.pack this is the main package of our application.
*main.pack this is the main package of our application.


*guiDemo.ph this is the header file of the application main package.
*main.ph this is the header file of the application main package.


*guiDemo.cl this class declares the application main predicate run.
*main.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.
*main.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.<br />
*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.<br />
*guiDemo.manifest this is the manifest file of the application. It contains some settings of the application in XML format.
Notice that you should not make any editing in it since any your changes will be overwritten while automatic update.
Notice that you should not make any editing in it since any your changes will be overwritten while automatic update.


Line 91: Line 94:
         applicationWindow::new(),
         applicationWindow::new(),
         generatedInitialize().
         generatedInitialize().
 
</vip>
<vip>
predicates
predicates
     generatedInitialize : ().
     generatedInitialize : ().
Line 97: Line 101:
     generatedInitialize():-
     generatedInitialize():-
         setText("guiDemo"),
         setText("guiDemo"),
         setDecoration(titlebar([closebutton(),
         setDecoration(titlebar([closebutton(),maximizebutton(),minimizebutton()])),
          maximizebutton(),minimizebutton()])),
         setBorder(sizeBorder()),
         setBorder(sizeBorder()),
         setState([wsf_ClipSiblings]),
         setState([wsf_ClipSiblings]),
         setMdiProperty(mdiProperty),
         setMdiProperty(mdiProperty),
         menuSet(resMenu(id_TaskMenu)),
         menuSet(resMenu(resourceIdentifiers::id_TaskMenu)),
         addCreateListener(generatedOnCreate),
         addShowListener(generatedOnShow),
         addCreateListener(onCreate),
         addShowListener(onShow),
         addSizeListener(onSizeChanged),
         addSizeListener(onSizeChanged),
         addDestroyListener(onDestroy),
         addDestroyListener(onDestroy),
         addMenuItemListener(id_help_about, onHelpAbout),
         addMenuItemListener(resourceIdentifiers::id_help_about, onHelpAbout),
         addMenuItemListener(id_file_exit, onFileExit).
         addMenuItemListener(resourceIdentifiers::id_file_exit, onFileExit).


     ...
     ...
Line 132: Line 135:
==How to Add New GUI Dialog==
==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''':
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 in Existing Package...''' . You will see the dialog, where it is necessary to select '''Dialog''' type and write a name. We have chosen the name '''firstDialog''':


[[Image:GUI_Package_firstDialog.png]]
[[Image:GUI_Package_firstDialog.png]]
Line 146: Line 149:
[[Image:GUI_Package_NewDlgEvent.png]]
[[Image:GUI_Package_NewDlgEvent.png]]


IDE generates a default code for '''onFileNewDialog''' event, which we modify by invocation of '''firstDialog''':
After pressing '''Add''' button the IDE will generate a default code for '''onFileNewDialog''' event. Let us modify it by invocation of '''firstDialog''':


<vip>predicates
<vip>predicates
Line 161: Line 164:
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'''.
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''':
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 choose '''Edit''':


[[Image:GUI_Package_EditModifyEvent.png]]
[[Image:GUI_Package_EditModifyEvent.png]]
Line 168: Line 171:


<vip>predicates
<vip>predicates
     onEdit_ctlModified : editControl::modifiedListener.
     onEditModified : editControl::modifiedListener.
clauses
clauses
     onEdit_ctlModified(_Source) :-
     onEditModified(_Source) :-
         editCopy_ctl:setText(edit_ctl:getText()).</vip>
         editCopy_ctl:setText(edit_ctl:getText()).</vip>


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.
Let us add a more complicated control now. Let us choose treeViewControl. IDE can insert automatically the necessary declarations, therefore we add '''pfc\gui\treeViewControl\treeViewControl.pack''' package and then build our project.


IDE can insert automatically the necessary declarations, therefore we add '''pfc\gui\treeViewControl\treeViewControl.pack''' package and then build our project.
In dialog editor we choose '''Controls | Custom''' command and select '''treeViewControl''' in the list.


You can run the project now and see that the tree is empty. We can add more code to initialize the tree view control:
You can run the project now and see that the tree is empty. Let us modify the implementation of the constructor '''new''' in the '''TaskWindow\firstDialog.pro''' file. Here, we can add more code to initialize the tree view control:


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


Now the program can show a simple tree.
Now the program can show a simple tree.

Revision as of 15:05, 30 September 2008

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 Ctrl+F5 key combination.

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 Ctrl+Shift+B 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:

  • main.pack this is the main package of our application.
  • main.ph this is the header file of the application main package.
  • main.cl this class declares the application main predicate run.
  • main.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.
  • guiDemo.manifest this is the manifest file of the application. It contains some settings of the application in XML format.

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(resourceIdentifiers::id_TaskMenu)),
        addShowListener(generatedOnShow),
        addShowListener(onShow),
        addSizeListener(onSizeChanged),
        addDestroyListener(onDestroy),
        addMenuItemListener(resourceIdentifiers::id_help_about, onHelpAbout),
        addMenuItemListener(resourceIdentifiers::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 in Existing Package... . 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

After pressing Add button the IDE will generate a default code for onFileNewDialog event. Let us modify it 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 choose Edit:

GUI Package EditModifyEvent.png

Then we can add the code to implement our intention:

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

Let us add a more complicated control now. Let us choose treeViewControl. IDE can insert automatically the necessary declarations, therefore we add pfc\gui\treeViewControl\treeViewControl.pack package and then build our project.

In dialog editor we choose Controls | Custom command and select treeViewControl in the list.

You can run the project now and see that the tree is empty. Let us modify the implementation of the constructor new in the TaskWindow\firstDialog.pro file. Here, we can add more code to initialize the tree view control:

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

Now the program can show a simple tree.

References