trainer notes

26
PML2 Training Notes What’s New in PML2 Objects and Object methods Form names are now preceded with !! i.e. setup form _fred followed by : setup form !!fred results in an error because !!fred was already defined in the previous assignment Forms are now loaded dynamically return error noalert allows an error to be returned without any messages What to avoid in PML2 Commands with dollars in $m- $m+ $W25 Numbered variables $v1-120 The var command var !x name var !x read Synonyms Global variables What to avoid in forms and menus Dots in gadget names selector gadgets Userdata Pixmap views

Upload: merzeba

Post on 18-Nov-2014

162 views

Category:

Documents


6 download

TRANSCRIPT

PML2 Training Notes

What’s New in PML2

Objects and Object methods

Form names are now preceded with !!

i.e. setup form _fredfollowed by : setup form !!fredresults in an error because !!fred was already defined in the previous assignment

Forms are now loaded dynamically

return error noalert allows an error to be returned without any messages

What to avoid in PML2

Commands with dollars in $m- $m+ $W25Numbered variables $v1-120The var command var !x name var !x readSynonymsGlobal variables

What to avoid in forms and menus

Dots in gadget namesselector gadgetsUserdataPixmap viewsAlert gadgetsRadiogroupsSimple Textin gadgetsNumbers at the beginning of gadget namesWaiton to show formsDo list/pane/sel

What’s not changed in PML2

In theory, all old PML should work in PDMS11.1. Very little of the old appware has been converted because this would be a waste of resources. Cadcentre policy on converting appware to use new facilities is to only upgrade appware when modifications are being made in that area.

The only exception to this, is where new facilities in core code supersede or improve functionality and it is necessary to write new code to use the extra functionality.

New Environment Variables

PMLLIB /DIRECTORYNAME

This is a directory which is searched when the system looks for functions and forms

PMLTRACE ON/OFF

When set to ON, PMLTRACE will display a trace of all macros called in the unix command shell. This can also be switched on or off on the command line, so it is probably better to set the variable to off and use commands to control trace as before.

The command in PDMS is - PML TRACE ON/OFF

PMLCOMPILE ON/OFF

Environment variable PMLDEBUG ON will write a trace file

Available variable types

$v1 old style not recommended!a Named variables both global and local !!global !localNOTE: !a is evaluated as text automatically by using $!A (early evaluation)

Named variables are now typed variables as one of the following

STRING ‘Text in quotes or vertical bars up to a Max of 254? char’REAL Any numberBOOLEAN TRUE,FALSE These are not text i.e. ‘TRUE’,’FALSE’ARRAY Any type including arrays of arrays of anythingOBJECTS A collection of different variables under a user defined type

Variables can be predefined as a particular type or revert to type when they are set

There are two ways of setting variables

Var !a (25) !a is a string

2

!a = 25 !a is a real

!a = ‘xyz’ !a is a string

!a[1] = 75 !a[1] is a real element of array !a Note: other elements in the same array can be of any type

!a = TRUE !a is BOOLEAN

Beware Pre version 11 the var command was used to set all variables and it produced a string. Now we don’t use var apart from collections.

Variables may also be created before they are used using Methods

!!Answer = real()!textline = String()!test = boolean()!squares = array()

All of the above have the value ‘unset’

There are various ways of testing whether a variable exists or is set:

If(undefined(!x))thenIf(defined(!x))then

If(unset(!x))thenIf(!x.unset())thenIf(set(!x))thenIf(!x.set())then

To make a variable undefined i.e. empty it.

!x.delete()var !x delete

Arrays

arrays may be sparse i.e. you can set in index order Negative subscripts are not permittedA subscript of zero can be used but is not adviseddo loop from and to variables can now include expressions and even functions

Array methods

!arraysize = !arraything.size() Replaces var !arraysisze (arraysize(!arraything))

3

Sets the variable arraysize to the number of elements in the array

!testarray.clear() Deletes all elements from !testarray

!test.removefrom(5, 20) Removes 20 elements from element number 5

!new = !test.removefrom(5,20) Removes 20 elements as above and creates a new

array with the 20 elements inside.

!myarray.append(!newdata) acts like var !array append ‘fhjffj’

!myarray.[27].delete() Deletes element 27 of the array the array still exists

!myarray.delete() Deletes the array entirely

!line = ‘ this is a line of text with some funny spaces ‘!line = !line.trim(‘lrm’)

trims the spaces from the variable called !line!line = ‘ this is a line of text with some funny spaces ‘!lines = !line.split(!line)

Splits the string !line into an array of strings called !lines.Note: we could not use the same variable name because it is a different type

!a = !lines.size() gives the number of elements in the array!a = !lines.width() gives the number of characters in the longest word of the array

No result methods.

!lines.sort() sorts the array !lines and returns the array in its sorted form!lines.invert() inverts the array order first to last etc. These methods work only

on the original array. Attempts to set another array results in an error.

i.e. !new = !lines.sort() Gives an error

The old method.

!ind = !lines.sortedindices() Produces a sorted index without changing the original array. This can be used to sort parallel arrays in the same way as before.

!lines = !lines.relindex(!ind) Re-orders an array according to the order of array !ind

4

If applied to the original array, it would have the same effect as a simple sort, its use is to sort parallel arrays.

The Current Element variable

There is one global variable which is always set by the system to be the element you are positioned at in the database - this is called !!CE. !!CE is an object of type DBREF. Its attributes are described as members of the object. e.g.

!tem = !!ce $* creates a variable which is a copy of !!ce1q var !tem $* Queries the attributes of the DBREF pointed to by !item

<DBREF> =8196/8 NAME <DBATTT> -> <STRING> ‘DA/2000’ TYPE <DBATTT> -> <STRING> ‘SITE’ LOCK <DBATTT> -> <BOOLEAN> FALSE OWNER <DBATTT> -> <DBREF> =8196/0 DESC <DBATTT> -> <STRING> ‘MAIN REACTOR AREA’ FUNC <DBATTT> -> <STRING> ‘’ PURP <DBATTT> -> <STRING> ‘’ NUMB <DBATTT> -> <REAL> 0 AREA <DBATTT> -> <REAL> 0 POS <DBATTT> -> <POSITION> E 0mm N 0mm U 0mm WRT /* ORI <DBATTT> -> <ORIENTATION> Y is N AND Z is U WRT /* MODU <DBATTT> -> <STRING> ‘’ ORRF <DBATTT> -> <DBREF> Unset STMF <DBATTT> -> <DBREF> Unset :MATERIAL <DBATTT> -> <STRING> ‘Carbon Steel’

q var !item $* gives/DA/2000 $* without all of the other stuff

!item $* as a command, does nothing

$!item $* navigates to /DA/2000

Querying attributes

q var !item.pos $* gives

<POSITION> E 0mm N 0mm U 0mm WRT /* ORIGIN <DBREF> =8196/0 UP <REAL> 0 EAST <REAL> 0 NORTH <REAL> 0

5

q var !item.e $*query the east position<REAL> 0

q var !item.pos.origin $* gives all of the attributes of =8196/0 q var !item.pos.origin.lock $* gives the lock of =8196/0

q var !item.pos.wrt(=8196/32) $* uses the method WRT(DBREF) to extract a $*position relative to some other database

$*reference

METHODS/FUNCTIONS

Different data types in pml have associated built in ‘methods’ which may be used to convert or read data in a particular way. Some methods are similar to the built in functions pre version 11.1 as in the example below:

!NCHARS = !MYSTRING.LENGTH() $* THIS IS A METHOD

!NCHARS = LENGTH(!MYSTRING) $* THIS IS A FUNCTION CALL

The pre version 11.1 syntax for the function call would have been as follows:

VAR !NCHARS LENGTH(|$!MYSTRING|) $* THIS IS A 10.5 FUNCTION CALL

The difference between the 10.5 example and the 11.1 example is that version 11 now returns a typed variable (REAL) where version 10.5 would have returned a string.

Methods are built in for various data types and are listed in appendix A of the Customisation guide.

Block evaluation of arrays

Block evaluation is a method of stepping through each element of an array and performing some action. In effect, it is like a single command do loop.

To perform block evaluation, there are two stages:

First you need to define the expression which will operate on the array elements Second, you need to apply the expression to an array

The expression is stored in a variable and is defined as follows:

!EXPRESSIONVAR = OBJECT BLOCK (‘!!ARRAYNAME[!EVALINDEX] * 2’)

6

the !!arrayname[!evalindex] bit is effectively the name of the variable being operated on by the expression. In the example above, the result would be to multiply all of the numbers in the input array by 2. The variable !evalindex is a special variable used in block evaluation. Any other variable name will not work!

To apply the expression is as follows:

!!newarray = !!arrayname.evaluate(!expressionvar)

This creates an array called !!newarray containing the numbers of the original array multiplied by 2. The original array can also be modified using this method:

!!arrayname = !!arrayname.evaluate(!expressionvar)

Here are some simple examples

!text = 'this is a line of text'!myarray = !text.split()

This creates an array called !!myarray with six elements

!myarray[1] = ‘this’!myarray[2] = ‘is’!myarray[3] = ‘a’!myarray[4] = ‘line’!myarray[5] = ‘of’!myarray[6] = ‘text’

Now we can define some blocks

!extractchar1 = object block ('subs(!myarray[!evalindex],1,1)')!new = !myarray.evaluate(!extractchar1)

This extracts the first character of each word into and array called !newgiving the following:

!new[1] = ‘t’!new[2] = ‘i’!new[3] = ‘a’!new[4] = ‘l’!new[5] = ‘o’!new[6] = ‘t’

!extractchar1 = object block ('upcase(subs(!myarray[!evalindex],1,1))')!new = ! myarray.evaluate(!!extractchar1)

This does the same as before, but also changes the letters to upper case

!new[1] = ‘T’

7

!new[2] = ‘I’!new[3] = ‘A’ !new[4] = ‘L’!new[5] = ‘O’!new[6] = ‘T’

!extractchar1 = object block ('upcase(subs(!myarray[!evalindex],1,1)) & |fred|')!new = !myarray.evaluate(!extractchar1)

This does as before, but uses the & character to append the string fred to the result

!new[1] = ‘Tfred’!new[2] = ‘Ifred’!new[3] = ‘Afred’!new[4] = ‘Lfred’!new[5] = ‘Ofred’!new[6] = ‘Tfred’

!extractchar1 = object block ('!!testfunc(!myarray[!evalindex])')!myarray.evaluate(!extractchar1)

This example passes the evaluation into a function called !!testfunc, resulting in the function being run on each element of the array. More on functions later!

8

Objects

define object COMPONENT member .detail is string member .material is string member .bore is real member .position is positionendobject

To use this object

!x = object COMPONENT()!x.detail = !!ce.dtxr!x.material = !!ce.mtxx!x.bore = !!ce.pbor1!.pos = !ce.pos

External Functions

The new environment variable PMLLIB points to an area where both forms and functions(macros) can be dynamically loaded according to name. PML functions are macros which may or may not return a value. They must be named with a suffix of “.pmlfrm” , “pmlobj” & “pmlfnc” and they are called as follows:

Officially:

call !!functionname()

Unofficially:

!!functionname()

e.g a function definition

define function !!dir_to_next(!comp is dbref) $!comp -- go to component passed dir to next next if (!!ce.type eq ‘ELBO’)then back dir to next endif nextforwreturn

To run this function on the current element, type:

9

!!dir_to_next

or

call !!dir_to_next

This would result in the system searching for a file called “dir_to_next.pmlfnc” and if found, running it as a macro.

To get all of the text of the selected elements in a list would require a simple function as follows:

-- Function to get all selected text items in a list gadget-- Pass the name of the list gadget is the input parameterdefine function !!textlist(!input is gadget)is array!selected = !input.val!expression = object block(‘!input.rtext[!selected[!evalindex]]’)!x = !selected.evaluate(!expression)return !xendfunction

to run this

!!text = !!textlist(!!myform.members)

Alert Views

Alert views are slightly different to pre version 11. They are treated as functions and called in the same way

!!Alert.Error(‘This is an error message’)

!!Alert.warning(‘This is a warning message’)

!!Alert.Message(‘This is a message’)

!answer = !!Alert.confirm(‘Do you want to savework’)

This returns ‘YES’ or ‘NO’

!answer = !!alert.question(‘ok to delete world’)

This returns ‘YES’ ‘NO’ or ‘CANCEL’

10

Forms and Menus

setup form !!myform Paragraph .message text ‘Press goodbye button to close’ button .goodbye okexit!!myform.show()

by convention, all form definition macros have the extension .frmto load the form type $m/myform.frm

In the above example the button has no display text. In fact the display text is taken from the name and made upper case.

The method !!myform.show() is the equivalent of show _myform

Querying the form

q var !!myform would give something like the following:

<FORM> MYFORM GOODBYE <GADGET> MESSAGE <GADGET> Press goodbye button to close AUTOCALL <FMPROP> -> <STRING> ‘ ‘ CALLBACK <FMPROP> -> <STRING> ‘ ‘ USERDATA <GADGET> FORMTITLE <FMPROP> -> <STRING> ‘ ‘ ICONTITLE <FMPROP> -> <STRING> ‘ ‘ FORMREVISION <FMPROP> -> <STRING> ‘ ‘ KEYBOARDFOCUS <FMPROP> -> <GADGET> Unset

The important form properties are :

AUTOCALL

What is autocall?

CALLBACK

This is in fact the initialisation callIt can be set as follows

!!MYFORM.CALLBACK = ‘$$P ABOUT TO SHOW MYFORM’

or as part of the original macro

INIT ‘$$P ABOUT TO SHOW MYFORM’

11

USERDATA

Userdata seems to work as before i.e. VAR USER _MYFORM ADD |FRED|

Adds the text FRED to the userdata area of the form

NOTE: userdata is sort of superseded by new variables called form members which will be discussed later

FORMTITLE

FORMTITLE is a text string which is shown across the top border of the form

it can be set in two ways as before:

as part of the form definition

TITLE | My Demonstration Form|

Or as a change to an existing form

!!MYFORM.FORMTITLE = | My Demonstration Form|

ICONTITLE

This is the text displayed on the forms icon. It is set in the same way as above but the keyword ICONTITLE replaces TITLE and FORMTITLE in the syntax

FORMREVISION

this is an optional revision text which again is set in a similar way

KEYBOARDFOCUS

Keyboardfocus is meant to set the focus point to one of the form gadgets so that the user is positioned in the right place when a form is shown. The syntax is as follows:

!!myform.keyboardfocus = !!myform.textpane!!myform.show

If the form is visible on the screen, the focus will not changeCurrently, Focus only applies to text input gadgets, textpanesand alpha displays

12

General Form features

Only one OK button allowed per form

Pressing OK on a parent form actions the OK gadgets of all child forms (youngest first)

Pressing Cancel on a parent form effectively presses cancel on all child forms as well.

In both cases the parent and child forms are removed from the screen

This “Form Family” effect does not apply to RESET and APPLY buttons

Each form has a show/hide method associated with it. these are slightly enhanced on what went before.

!!MYFORM.SHOW() shows the form in its default state

!!MYFORM.SHOW(‘AT’,0.5,0.5) positions the form origin half way across the screen and half way down

!!MYFORM.SHOW(‘CEN’,0.5,0.5) positions the form centre point half way across the screen and half way down

If a form is shown by some other form, it joins the form family of the parent. Exceptions to this are:

The form is shown in an explicit positionThe form is shown by an OK or CANCEL gadgetThe parent form is a FREE form

To show a form as a FREE form use

!!MYFORM.SHOW(‘FREE’)

Forms can still be setup as blocking or resizable using:

SETUP FORM !!MYFORM BLOCKING

SETUP FORM !!MYFORM RESIZABLE

to hide a form use:

!!MYFORM.HIDE()

13

Gadgets

Gadgets are stored in a similar way to forms. The command:

Q VAR !!MYFORM.MESSAGE

results in the following:

<GADGET> Press goodbye button to closeVAL <FMPROP> -> <STRING> ‘Press goodbye button to close’ACTIVE <FMPROP> -> <BOOLEAN> TRUECALLBACK <FMPROP> -> <STRING> ‘’BACKGROUND <FMPROP> -> <REAL> 255

All of these values can be changed by a function or macro although on this gadget, callback seems to be a little pointless.

To set the variables is as follows:

!!MYFORM.MESSAGE.VAL = ‘This is a different piece of text’

sets the text part - using the old syntax is as follows:

var !! MYFORM.MESSAGE ‘This is a different piece of text’

!!MYFORM.MESSAGE.ACTIVE = FALSE

Makes the gadget inactive (greys it out)

!!MYFORM.MESSAGE.BACKGROUND = 22Sets the text background colour to colour number 22 (RED). The text changes colour to be a suitable contrast if necessary

14

Members of forms

Instead of assigning userdata to forms, it is now possible to set a series of dedicated form variables for use by the appware writer. These can be any variable type including arrays. To define form member variables is as follows:

SETUP FORM !!MYFORM . .MEMBER .MYNUMBER IS REALMEMBER .MYTEXT IS STRINGMEMBER .MYARRAY IS ARRAYMEMBER .MYOBJECT IS POSITION . .EXIT

These variables can be used and set in exactly the same way as any other global variables.

!!MYFORM.MYARRAY.APPEND(‘THIS IS SOME TEXT’)!!MYFORM.MYARRAY.APPEND(53)!!MYFORM.MYARRAY.APPEND(TRUE)

!!MYFORM.MYOBJECT = !!CE.POS

To query what the form contains:

Q VAR !!MYFORM.MEMBERS()

Paragraph Gadgets

examples

PARAGRAPH .MESSAGE TEXT ‘This is some text’PARAGRAPH .MESSAGE AT X2 Y2 TEXT ‘Optional starting text’ WIDTH 16 LINES 2PARAGRAPH .MESSAGE TEXT AT X2 Y2 BACKGROUND 22 TEXT ‘This is some text’PARAGRAPH .MESSAGE TEXT PIXMAP /FILENAMEPARAGRAPH .MESSAGE TEXT PIXMAP /FILENAME WIDTH 256 ASPECT 2

15

Button Gadgets

Button gadgets are defined as follows:

BUTTON .BUTTON1 ‘SHOW DATA’ FORM !!DATAFORM

This is a simple button which shows a form when pressed

BUTTON .OK ‘OK’ AT X2 Y3 CALBACK ‘!!MYOKCALLBACK()’ OK

This is a button which runs a function when pressed. It is also an OK button which means the form will automatically be removed from the screen when the button is pressed.

There are 5 types of button which have different effects on how the button behaves:

OK As described aboveCANCEL Removes the form from the screen and resets the form variables to the

state when the form was shown or the status after the last APPLY. APPLY This activates the callback, but the form is not hiddenRESET This works like CANCEL but the form is not hiddenHELP Invokes form specific help

BUTTON .BUTTON2 AT Y2 X4 PIXMAP /FILENAME FORM !!DATAFORM

This is a button which contains a single pixmap view. In fact, a button may have up to three pixmaps associated with it. These represent three possibilities:

The button is in it’s normal stateThe button is pressedThe button is inactive(greyed out)

The syntax for defining these is as follows:

BUTTON .BUTTONNAME PIXMAP UNSELECTED /PIX1 WIDTH 26 HEIGHT 26 SELECTED /PIX2 INACTIVE /PIX3 CALLBACK ‘CALLBACK TEXT’

Frame Gadgets

Frame gadgets are new gadgets which produce an enclosing frame around other gadgets. They are used to group gadgets together and are described by a title text in the top left corner.

16

They are defined as follows:

frame .framename ‘Title’ at x2 y4 width 10 height gadget1 gadget2exit

Gadgets within a frame are positioned relative to the frame origin.If you wanted to put in a four line paragraph gadget, specifying the text during definition has the effect of resizing the frame to suit the text. To get a paragraph gadget to fit into the frame, the text must be specified afterwards.

Toggle Gadgets

Toggle gadgets are now very simple. They have two states true or false and are treated as a simple boolean variable.

TOGGLE .INSULATION ‘INSULATION’TOGGLE .GRID PIXMAP /FILENAME WIDTH 64 HEIGHT 64 CALLBACK ‘ ‘

to set toggle gadgets

!!MYFORM.INSULATION.VAL = TRUE

to use

IF(!!MYFORM.INSULATION.VAL)THEN....

Rgroup Gadgets

Rgroup gadgets are a new type of radio group. It is defined as follows:

RGROUP .STYLE ‘STYLE’ AT X2 Y3 CALLBACK ‘ ‘ VERTICAL ADD TAG ‘Bold Text’ SELECT ‘BOLD’ ADD TAG ‘Italic Text’ SELECT ‘ITALIC’ ADD TAG ‘Underline’ SELECT ‘UNDERLINE’EXIT

When the group appears, item one is selected.The text in the RGROUP line is the title of the rgroup

To select any other item it is done by number

!!MYFORM.STYLE.VAL = 2

17

This selects item 2 in the group

Two other methods are available to operate on rgroup gadgets

!STYLETEXT = !!MYFORM.STYLE.SELECTION()

This gets the text of the gadget - in this case ‘BOLD’

!!MYFORM.STYLE.SELECTI(‘UNDERLINE’)

This sets the toggle by selecting the toggle with the select text equal to ‘UNDERLINE’

Querying:

Q VAR !!MYFORM.STYLE

<GADGET> BOLD VAL <FMPROP> -> <REAL> 1 ACTIVE <FMPROP> -> <BOOLEAN> TRUE CALLBACK <FMPROP> -> <STRING> ‘ ‘

$P $!!MYFORM.STYLE BOLD

Option Gadgets

Option Gadgets are compact lists which look like buttons. they have two sets of text:Display text which what appears on the gadget and replacement text which is stored in the background.

OPTION .COLOPT ‘Text Colour’ AT X6 Y6 CALL ‘!!function()’

Setting the options is simply an array assignment using a method.

!!MYFORM.COLOPT.DTEX = !COLARRAY

!!MYFORM.COLOPT.DTEX = !NUMARRAY

Both arrays must be STRINGS

Options can also use pixmap views whose file names are inserted into the display text of the option. All of the pixmap views must be the same size and the width and height must be part of the declaration.

OPTION .COLOPT ‘Text Colour’ CALL ‘ ‘ PIXMAP WIDTH 64 HEIGHT 64

18

List Gadgets

List Gadgets are either single or multiple choice gadgets which again use display and replacement texts like option gadgets. The list area is defined as an area on a form but the text in a list can be very large.

LIST .MEMBERS AT X5 Y6 MULTIPLE WIDTH 20 LENGTH 6

LIST .MEMBERS AT X5 Y6 SINGLE WIDTH 20 LENGTH 6

Assigning values to a list is a matter of setting the dtext and rtext fields as in options

!!MYFORM.MEMBERS.DTEXT = !VARNAME!!MYFORM.MEMBERS.RTEXT = !OTHERVARNAME

Note: Setting the DTEXT only causes the RTEXT to have the same value.

List Gadget Manipulation

There are a number of ways of extracting and manipulating the data from a list:

To get the list positions of any currently selected elements

!SELECTED = !!MYFORM.MEMBERS.VAL

For a multiple form, !SELECTED would be an array of real. For a single choice list it would be a single real.

to get all of the text of the selected elements in a list would require a simple command as follows:

!NEWARRAY = !!MYFORM.MEMBERS.SELECTION

To get all of the text of a list:

!NEWARRAY = !!MYFORM.MEMBERS.RTEXT

copies all of the replacement text into !newarray

!NEWARRAY = !!MYFORM.MEMBERS.DTEXT

does the same for the display text

to clear all selections

19

!!MYFORM.MEMBERS.CLEARSELECTION()

to select items in the list

!!MYFORM.MEMBERS.SELECT(‘DTEXT’,’/FRED’)

Note: There are no facilities to match just part of the string.

to select all items in a list

!!MYFORM.MEMBERS.SELECT(‘DTEXT’,!!MYFORM.MEMBERS.DTEXT)

to clear selections

!!MYFORM.CLEARSELECT()

to clear the list entirely

!!MYFORM.CLEAR()

Text Input Gadgets

Text input gadgets allow text to be entered into a variable. The width of the text is described by the width command the maximum text size is determined by the scroll command

to create a text gadget

TEXT .MYTEXT AT X2 Y 2 ‘NAME’ CALLBACK | | WIDTH 10 SCROLL 20 IS STRING

The types of variable now available are: IS STRINGIS REALIS BOOLEANIS word ?

to maintain compatibility with old PML

ISOUNITNAMENUMERICINTEGERSTRINGISOBORE

To set an initial value

20

!!myform.mytext.val = |insert text here|

T0 set focus

!!myform.mytext.focus()

NOTE: it is only possible to set the focus to text gadgets

To enable the entry of passwords into a gadget, it is possible to set NOECHOon a text input gadget so that the input is not shown to the screen.

It is also possible to set the format of a gadget to be in a format which can be defined by a FORMAT object.

TEXT .MYTEXT AT X2 Y 2 ‘NAME’ WIDTH 10 FORMAT IS !!FORMATBORE

Where !!FORMATBORE is a FORMAT object

These are defined as follows:

!!FORMATBORE = FORMAT()!!FORMATBORE.UNITS = ‘FINCH’!!FORMATBORE.FRACTION = TRUE!!FORMATBORE.DENOMINATOR = 16

Textpanes

Textpanes are like editable notepads the occupy an area on the screen and can have text associated with them. TEXTPANES HAVE NO CALLBACK

they are defined as follows:

TEXTPANE .TEXTP AT X3 Y4 WIDT 20 HEIGHT 5

You can add text by typing it in or it can be inserted from an array as follows:

!!MYFORM.TEXTP = !ARRAYNAME

There are methods for making the text editable or not

!!MYFORM.TEXTP.SETEDITABLE(TRUE)

!!MYFORM.TEXTP.SETEDITABLE(FALSE)

21