\chapter{Getting started} \label{sec:starting} This section introduces programming the \productpl{} environment: the entities (objects), referencing objects and manipulating objects. Most of the material is introduced with examples. A complete definition of the interface primitives is given in \appref{interface}. \section{Starting \productpl{}} \begin{xpceonly} \product{} is distributed as a library on top of the hosting Prolog system. For use with SWI-Prolog, this library is auto-loaded as soon as one of its predicates (such as new/2) is accessed or it can be loaded explicitly using \begin{code} :- use_module(library(pce)). \end{code} In Unix XPCE/SWI-Prolog distribution the program \program{xpce} is a symbolic link to \program{pl} and causes the system to pull in and announce the \product{} library with the banner: \begin{code} % xpce XPCE 6.0.0, February 2002 for i686-gnu-linux-gnu and X11R6 Copyright (C) 1993-2002 University of Amsterdam. XPCE comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. The host-language is SWI-Prolog version 5.0.0 For HELP on prolog, please type help. or apropos(topic). on xpce, please type manpce. 1 ?- \end{code} \index{version}% SWI-Prolog's prompt is `` ?-'' where is the history-number of the command. The banner indicates the \product{} version. The indicated version is 5.1 and the patch-level is 0. On MS-Windows, Prolog programs are normally loaded and started by double-clicking a \fileext{.pl} file. \product{}, being a normal library, does not change this. Note that \product{} can only be used fully with the GUI-based \program{swipl-win.exe}. Using the the console-based \program{swipl.exe} program only the non-GUI functionality of \product{} is accessible. \end{xpceonly} \begin{pwonly} \product{} is distributed as a \quintus{} library package, called \file{prowindows3.1}. This implies it may be loaded on top of the running \quintus{} Prolog system using: \begin{code} | ?- [library(pce)]. % loading file /usr/local/quintus/prowindows3.1/library/pce.qof ... \end{code} Regarding the size and loading time of \product{}, a separate executable named \program{pw3} is created that contains the \product{} kernel, and basic development and debugging libraries. This is the executable that is normally used for interactive development and debugging. \begin{code} % pw3 Quintus Prolog Release 3.3 (ProWindows 3.1) Originally developed by Quintus Corporation, USA. Copyright (C) 1996, AI International Ltd. All rights reserved. Castle Chambers, High Street, Berkhamsted, Herts, UK. +44 (0)1442 873873 Email: support@aiil.co.uk WWW: http://www.aiil.co.uk Licensed to University of Amsterdam Quintus ProWindows 3.1 (XPCE 4.9.3, April 1997) Interface Copyright (C) 1997, AIIL / University of Amsterdam. All Rights Reserved. | ?- \end{code} \end{pwonly} \section{Prolog ... and what?} This section describes the four basic Prolog predicates used to control \product{} from Prolog. These four predicates map onto the basic functions of \product{}'s virtual machine: creating, destroying, manipulating and querying {\em objects}, the basic entities of \product{}. For those not familiar with this jargon, an object is an entity with a state and associated procedures, called {\em methods}. Objects may represent just about anything. In \product{}'s world there are objects representing a position in a two-dimensional plane as well as an entire window on your screen. Each object belongs to a {\em class}. The class defines the constituents of the state as well as the procedures associated with the object. For example, a position in a two-dimensional plane is represented by an object of class \class{point}. The state of a point object consists of its X- and Y-coordinates. A point has methods to set the X- and Y-coordinate, mirror the point over a reference point, compute its distance to another point, etc. \subsection{Creating objects: new} \label{sec:new2} \index{object,reference}\index{reference, object} The predicate new/2 (new(?Reference,~+NewTerm)) {\em creates} an object in the \product{} world and either assigns the given {\em reference} to it or unifies the first argument with a \product{} generated reference. An (object-) reference is a unique handle used in further communication with the object. Below are some examples (\verb$?-$ is the Prolog prompt): \begin{code} 1 ?- new(P, point(10,20)). P = @772024 2 ?- new(@demo, dialog('Demo Window')). \end{code} The first example creates an instance of class point from the arguments `10' and `20'. The reference is represented in Prolog using the prefix operator \functor{@}{1}. For \product{} generated references the argument of this term is a \product{} generated integer value. These integers are guaranteed to be unique. The second example creates a dialog object. A dialog is a window that is specialised for displaying controllers such as buttons, text-entry-fields, etc. In this example we have specified the reference. Such a reference must be of the form @Atom. \product{} will associate the created object with this reference.% \footnote{Normal applications use almost exclusively \product{} generated references. Many of the examples in this manual are typed from the terminal and Prolog specified references are easier to type.} As illustrated by the examples above, the second argument to new/2 is a term. The principal functor denotes the name of the class of which an instance is created and the arguments are the initialisation parameters. The complete transformation rules are given in \appref{interface}. As stated before, an object has a state. At creation time, the initial state is defined by the class from which the object is created and the initialisation arguments. In our example, the point is assigned an x-value of 10 and and y-value of 20. The dialog is assigned the label `Demo Window'. A dialog window has many {\em slots}% \footnote{The attributes of an object state are called slots. In other languages they may be called {\em instance variables} or fields.} The example defines the `label'. All the other slots are set to the default value described in the class definition. \subsection{Modifying object state: send} The state of an object may be manipulated using the predicate send/2 (send(+Receiver, +Selector(...Args...))). The first argument of this predicate is an object reference. The second is a term. The principal functor of which is the name of the method to invoke ({\em selector}) and the arguments are arguments to the operation. \begin{code} 3 ?- send(@772024, x(15)). 4 ?- send(@demo, append(text_item(name))). \end{code} The first example invokes the {\em method} `x' of the point object. It sets the instance variable x of the corresponding point object to the argument value. The second example invokes the method `append' of class dialog. This method appends a UI component to the dialog window. The component is specified by the term `text_item(name)', which is converted into an object just as the second argument of new/2. The query below opens the dialog window. \begin{code} 5 ?- send(@demo, open). \end{code} If everything is ok, a window as shown in \figref{dialog} appears on your screen. The border (in the figure this is the title-bar displayed above the window) is determined by the window manager you are using. It should look the same as any other window on your terminal. If an error of any kind appears, please refer to \appref{trouble}. \postscriptfig{dialog}{Example Dialog Window} \subsection{Querying objects: get} The next fundamental interface predicate is get/3. It is used to obtain information on the state of objects. The first two arguments are the same as for send/2. The last argument is unified with the return-value. The return value is normally an object reference, except for \product{} \class{name} objects, that are returned as a Prolog \idx{atom}, \product{} integers (\idx{int}) that are translated to Prolog integers and \product{} \class{real} objects, that are translated to Prolog \idx{floating point} numbers. Examples: \begin{code} 6 ?- get(@772024, y, Y). Y = 20 7 ?- get(@demo, display, D). D = @display/display 8 ?- get(@772024, distance(point(100,100)), Distance). Distance = 117 \end{code} The first example just obtains the value of the `y' instance variable. The second example returns the display object on which @demo is displayed. This is the reference to an object of class display that represents your screen.% \footnote{Prolog would normally print `@display'. The \pllib{pce_portray} defines a clause for the Prolog predicate portray/1 that prints object references as `@Reference/Class'. This library is used throughout all the examples of this manual.} The last example again shows the creation of objects from the arguments to send/2 and get/3 and also shows that the returned value does not need to be a direct instance variable of the object. The return value is an integer representing the (rounded) distance between @772024 and point(100,100). The second example illustrates that get/3 returns objects by their reference. This reference may be used for further queries. The example below computes the width and height of your screen. \begin{code} 9 ?- get(@display, size, Size), get(Size, width, W), get(Size, height, H). Size = @4653322, W = 1152, H = 900 \end{code} As a final example, type something in the text entry field and try the following: \begin{code} 10 ?- get(@demo, member(name), TextItem), get(TextItem, selection, Text). TextItem = @573481/text_item, Text = hello \end{code} \index{graphical,finding}\index{finding,graphical} The first get operation requests a member of the dialog with the given name (`name'). This will return the object reference of the text_item object appended to the dialog. The next request obtains the `selection' of the text_item. This is the text typed in by the user. \subsection{Removing objects: free} \index{remove,objects}\index{object,remove} The final principal interface predicate is free/1. Its argument is an object reference as returned by new/2 or get/3. It will remove the object from the \product{} object base. Examples: \begin{code} 12 ?- free(@772024). 13 ?- free(@demo). 14 ?- free(@display). No \end{code} The second example not only removed the dialog window object from the \product{} object base, it also removes the associated window from the screen. The last example illustrates that certain system objects have been protected against freeing. \section{Optional arguments} \index{default arguments}\index{optional arguments}\index{argument,optional}% Arguments to \product{} methods are identified by their position. Many methods have both obligatory and optional arguments. If obligatory arguments are omitted \product{} will generate an error. If optional arguments are omitted \product{} fills the argument with the constant @default. The interpretation of @default is left to the implementation of the receiving method. See also \chapref{online}. \section{Named arguments} \label{sec:namedargs} \index{argument,named}\index{named argument} Some methods take a lot of arguments of which you generally only want to specify a few. A good example is the creation of a \class{style} object. A style is an object used to control the attributes of displayed text: font, fore- and background colour, underline, etc. Its ->initialise method, serving the same role the {\em \idx{constructor}} in \idx{C++}, takes 7 arguments. Both calls below create a style object representing an underlined text-fragment: \begin{code} 1 ?- new(X, style(@default, @default, @default, @default, @on)). 2 ?- new(X, style(underline := @on)). \end{code} The names of arguments are specified in the reference manual. For example, the method `area ->set', used to set one or more of the X-, Y-, H- and W-attributes of a rectangle, has the specification given below. For each argument that is specified as @default, the corresponding slot will not be changed. \begin{code} area->set: x=[int], y=[int], width=[int], height=[int] \end{code} The following example illustrates the usage of this method: \begin{code} 1 ?- new(A, area), send(A, set(y := 10, height := 50)). \end{code} \section{Argument conversion} \index{arguments,typed}\index{type}\index{type,conversion} Arguments to \product{} methods are {\em typed} and variables are dynamically typed. This combination is used for two purposes: automatic conversion and raising exceptions at the earliest possible point if conversion is not defined. For example, the send-method `colour' on class \class{graphical} specifies accepts a single argument of type `colour'. A colour in \product{} is represented by a colour {\em object}. Colour objects may be created from their name. The natural way to specify a box should be coloured `red' is: \begin{code} ..., send(Box, colour(colour(red))), ... \end{code} Because the ->colour method knows that it expects an instance of class colour, and because class colour defines the conversion from a name to a colour (see \secref{omsmethods}), the following message achieves the same goal: \begin{code} ..., send(Box, colour(red)), ... \end{code} Some other examples of classes defining type conversion are \class{font}, \class{image}, \class{name}, \class{string}, \class{real} and the non-object data item {\em int}. The following messages are thus valid: \begin{code} ..., send(Box, x('10')), % atom --> int send(Box, selected(true)), % atom --> boolean send(Text, font(bold)), % atom --> font send(Text, string(10)), % int --> string ... \end{code} \section{Send and get with more arguments} \label{sec:sendmanyargs} Though the principal predicates for invoking behaviour are send/2 and get/3, \product{} provides an alternative using send/[2-12] and get/[3-13]. The following goals are all identical. \begin{center} \begin{tabular}{ll} \tt send(Box, width(100)) & \tt send(Box, width, 100) \\ \tt get(Point, distance(point(10,10), D) & \tt get(Point, distance, point(10,1), D) \\ \end{tabular} \end{center} This alternative is provided for compatibility to pre-5.0 versions as well as to support users that dislike the new-style send/2 and get/3. It is realised using goal_expansion/2 and thus poses only a small compile-time overhead. \section{Notation} \index{notation,in this manual} This manual, as well as all other \product{} documentation both printed and online uses some notational conventions. Instead of speaking of `the send-method colour of class box', we write \begin{quote} `box ->colour' \end{quote} \noindent Similar, instead of `the get-method height of class window', we write \begin{quote} `window <-height' \end{quote} \noindent In some cases, the arguments and/or the return type of the method are specified: \begin{quote} `box ->colour: colour'\\ `window <-height ==>int' \end{quote} \section{Example: show files in directory} \label{sec:fileviewer} In this section we illustrate the above with some simple examples. We also show how the GUI can call procedures in the Prolog system. The demo creates a list of files from a given directory and allows the user to view a file. \Figref{fileviewer} shows the result. \postscriptfig[width=\textwidth]{fileviewer}{The FileViewer demo} \begin{pcecode} fileviewer(Dir) :- new(DirObj, directory(Dir)), new(F, frame('File Viewer')), send(F, append(new(B, browser))), send(new(D, dialog), below(B)), send(D, append(button(view, message(@prolog, view, DirObj, B?selection?key)))), send(D, append(button(quit, message(F, destroy)))), send(B, members(DirObj?files)), send(F, open). view(DirObj, F) :- send(new(V, view(F)), open), get(DirObj, file(F), FileObj), send(V, load(FileObj)). \end{pcecode} The main window of the application consists of a \class{frame} holding two specialised \class{window} instances. A \class{frame} is a collection of {\em tiled} windows. Any opened window in \product{} is enclosed in a \class{frame}. The windows are positioned using the methods ->above, ->below, ->right and ->left. The frame ensures that its member windows are properly aligned and handles resizing of the frame. See also \secref{framelayout}. In line 3, a \class{browser} is ->append{}ed to the frame object. A browser is a window specialised for displaying a list of objects. Next, a \class{dialog} is positioned below the browser. A dialog is a window specialised in handling the layout of controllers, or \class{dialog_item} objects as \product{} calls them. Line 5 adds a \class{button} to the dialog. `view' specifies the {\em name} of the button. \product{} defines a central mapping from `dialog_item <->name' to the label displayed. The default mapping capitalises the name and replaces underscores with spaces. In \secref{mlingual}, we describe how this can be used to realise multi-lingual applications. The second argument of the button specifies the {\em action} associated with the button. A \class{message} is a dormant send-operation. When pressed, the button executes \begin{code} send(@prolog, view, DirObj, B?selection?key) \end{code} If a message is sent to @prolog, this calls a predicate with the name of the {\em selector} of the message and an arity that equals the number of arguments to the message (2 here). The second argument is a term with principal functor \class{?} and defines an `obtainer', a dormant get-operation. It is defined as a Prolog infix operator of type {\tt yfx}, priority 500. This implies that \mbox{\tt B?selection?key} should be read as% \footnote{Initial versions of \product{} lacked the obtainer. In this case the browser {\em B} would be passed to the predicate view/1, which would extract the current filename from the browser. Obtainers improve the readability and avoid the need to mix UI related code with application code.} \begin{code} ?(?(B, selection), key) \end{code} The result of the get-operation <-selection on a browser returns the \class{dict_item} object currently selected. Dict-items are the elements of a \class{dict}, the underlying data object of a browser. A \class{dict_item} consists of a <-key (its identifier), a <-label (the visual text) and optionally an associated <-object. Line 8 appends a second button to the dialog window. The dialog window will automatically align this one to the right of the first. The action sends a message directly to another \product{} object and ->destroys the frame object if the quit button is pressed. Note that this will erase all UI objects associated with the frame. The garbage collector destroys all related objects. Line 10 fills the \class{browser} with the files from the specified directory. The expression \mbox{\tt DirObj?files} defines an obtainer operating on an instance of class \class{directory}. The obtainer evaluates to a \class{chain}, \product{}'s notion of a list, holding the names of all files in the directory. This chain is sent to the members-method of the browser \arg{B}. Again, the garbage collector takes care of the directory and chain objects. The browser automatically converts the given names to \class{dict_item} objects.% \footnote{This conversion is implemented with class \class{dict_item}. In fact, the browser just specifies the desired type and the message passing kernel invokes the conversion method of class \class{dict_item}.} Finally, the frame is ->open{}ed. This will cause the frame to ask each of the windows to compute its desired size, after which the frame aligns the windows, decides on their final geometry and creates the Window-system counterpart. The view/2 callback predicate opens an instance of \class{view}, a window specialised in text-editing, gets the file-object for the given filename F. and loads the file into the view. The method `view ->load' expects an instance of class \class{file}. Again, the type-conversion will deal with this. \section{Summary} \product{}'s world consists of objects. An object is an entity with persistent state that belongs to a class. The \productpl{} interface defines four basic predicates, new/2 to create objects from a description and returns an object reference, send/[2-12] to change the state of an object and succeeds if the requested change could be made, get/[3-13] to request an object to compute a value and return it, and free/1 to remove objects from the \product{} database. Objects of the \class{message} are `dormant' send operations. They may be activated by other objects (button, text_item, ...). In this case a send operation is started. Objects of class \class{?} are called {\em \idx{obtainer}} and represent `dormant' get operations. The `?' sign is defined as a prolog infix operator, allowing for constructs as: \begin{code} send(Frame, height, Frame?display?height) \end{code} The object @prolog (class \class{host}) allows calling Prolog predicates from the \product{} environment.