EPOC   SDK Home Glossary   Previous   Up

Friendlier interaction


Contents


Introduction

Everyday OPL programs can use the same graphical interface seen throughout the system:

Menu keywords begin with an M, and dialog keywords with a D. In this manual a lower case is used for these letters for example, mINIT and dEDIT but you can type them using upper or lower case letters.


Menus

Section Contents

Menus provide a simple way for any reasonably complex OPL program to let you choose from its various options.

To display menus in OPL generally takes three basic steps:

You use the displayed menus like any others on the system. Use the arrow keys or the pen to move around the menus. Tap an option, press Enter when it is selected, or press the option’s shortcut key to use it, or press Esc or Menu again to cancel the menus without making a choice. In either case, the menus are removed, the screen redrawn as it was, and MENU returns a value to indicate the selection made.


Defining the menus

The first argument to mCARD is the name of the menu. This will appear at the top of the menu; the names of all of the menus form a bar across the top of the screen.

Any number of options on the menu may be defined, each specified by two arguments. If there are more items than can be displayed on the screen at once, then the menu is displayed with a scroll bar. It is recommended that the number of menu items on a menu does not exceed the maximum number displayable at once on the screen of the target device; keeping the number of menu items small means that the user can select the menu item without having to scroll the menu.

The first argument in a menu item pair is the option name, and the second is the keycode for a shortcut key. This specifies a key which when pressed together with the Ctrl key should select the option. (Your program must still handle shortcut keys which are pressed without using the menu.) It is easiest to specify the shortcut key with % e.g. %a gives the value for a.

If an upper case character is used for the shortcut key keycode, the Shift key must be pressed as well to select the option; this will appear as ‘Shift+Ctrl+A’ in the menu. If you supply a keycode for a lower case character, the option is selected only without the Shift key pressed. Both upper and lower case keycodes for the same character can be used in the same menu (or set of menus). This feature may be used to increase the total number of shortcut keys available, and is also commonly used for related menu options e.g. %m might be used for zooming to a larger font and %M for zooming to a smaller font (as in the built-in applications).

For example,

    mCARD "Comms","Setup",%s,"Transfer",%t

defines a menu with the title Comms. When you move to this menu, you’ll see it has the two options Setup and Transfer, with shortcut keys Ctrl+S and Ctrl+T respectively (and no Shift key required). On the other hand,

    mCARD "Comms","Setup",%S,"Transfer",%T

would give these options the shortcut keys Shift+Ctrl+S and Shift+Ctrl+T.

The options on a large menu may be divided into logical groups (as seen in many of the menus for the built-in applications) by displaying a line under the final option in a group. To do this, you must pass the negative value corresponding to the shortcut key keycode for the final option in the group. For example, -%A specifies shortcut key Shift+Ctrl+A and displays a grey line under the associated option in the menu.

Each subsequent mCARD defines the next menu to the right. A large OPL application might use mCARD like this:

    mCARD "File","New",%n,"Open",%o,"Save",%s
    mCARD "Edit","Cut",%x,"Copy",%c,"Paste",-%v,"Eval",%e
    mCARD "Search","First",%f,"Next",%g,"Previous",%p

Menu flags

It is possible to have menu items without shortcuts, by specifying shortcut values between 1 and 32. The value specified is still returned if the item is selected.

Dimming, checkboxes and option buttons are controlled by adding the following values to the shortcut keycode (the constants are found in Const.oph.):

KMenuDimmed%

$1000

item dimmed

KMenuCheckBox%

$0800

item has checkbox

KMenuOptionStart%

$0900

item starts option button list

KMenuOptionMiddle%

$0A00

item in middle of option button list

KMenuOptionEnd%

$0B00

item ends option button list

KMenuSymbolOn%

$2000

symbol on (checkbox/option button)

KMenuSymbolIndeterminate%

$4000

symbol indeterminate

Dimming a menu item makes it unavailable and on trying to select it, the info print ‘This item is not available’ is automatically displayed. Items with checkboxes have a tick symbol on or off on their left hand side to show whether or not they have been selected. The start, middle and end option buttons are for specifying a group of related items that can be selected exclusively (i.e. if one item is selected then the others are deselected). The number of middle option buttons is variable.

Adding in the KMenuSymbolOn% flag sets the tick on a checkbox or the button on an option button item on. The display of ticks and option buttons is automatically changed appropriately when you select one of these items, but your program needs to maintain the state of any checkbox or option button between displays of the menu.

A single menu card can have more than one set of option buttons and checkboxes, but option buttons in a set should be kept together. For speed, OPL does not check the consistency of these items’ specification.

Cascaded items on which less important menu items can be displayed may also be created. The cascade must be defined before use in a menu cascade card. The following is an example of a ‘Bitmap’ cascade under the File menu of a possible OPL drawing application.

    mCASC "Bitmap","Load",%L,"Merge",%M
    mCARD "File","New",%n,"Open",%o,"Save",%s,"Bitmap>",16,"Exit",%e

The trailing > character specifies that a previously defined cascade item is to be used in the menu at this point: it is not displayed in the menu item. A cascade has a filled arrow head displayed along side it in the menu. The cascade title in mCASC is also used only for identification purposes and is not displayed in the cascade itself. This title needs to be identical to the menu item text apart from the >. For efficiency, OPL doesn’t check that a defined cascade has been used in a menu and an unused cascade will simply be ignored.

Shortcut keys used in cascades may be added with the appropriate constant values to enable checkboxes, option buttons and dimming of cascade items.

As is typical for cascade titles, a shortcut value of 16 is used in the example above. This prevents the display or specification of any shortcut key. However, it is possible to define a shortcut key for a cascade title if required, for example to cycle through the options available in a cascade.


Displaying the menus

The MENU function displays the menus defined by mINIT and mCARD, and waits for you to select an option. It returns the shortcut key keycode of the option selected, in the case supplied by you, whether you used the pen or Enter or the shortcut key itself to select it. If you supplied a negative shortcut key keycode for an underlined option, it is converted to its positive equivalent.

If you cancel the menus by pressing Esc, MENU returns 0.

Displaying a popup menu

A popup menu which appears at a specified point on the screen, may also be defined and drawn using mPOPUP. Note that popup menus have only one pane and need not and should not be within the mINIT...MENU structure. mPOPUP returns the value of the shortcut code in the same way as MENU. For example,

    mPOPUP(0,0,KMPopupPosTopLeft%,"Continue",%c,"Exit",%e)

The first two arguments specify the position of one corner and the third argument specifies which corner this is. This third argument takes values as follows,

KMPopupPosTopLeft%

0

Top left.

KMPopupPosTopRight%

1

Top right.

KMPopupPosBottomLeft%

2

Bottom left.

KMPopupPosBottomRight%

3

Bottom right.

Thus, the example above specifies a popup menu with 0,0 as its top left-hand corner and with the items ‘Continue’ and ‘Exit’, with the shortcuts Ctrl+C and Ctrl+E respectively.

You can add the same values to the shortcut key keycode as those used with mCARD and mCASC to display dimmed items, checkboxes and option buttons. Note, however, that cascades in popup menus are not supported. For example,

    mPOPUP(0,0,KMPopupPosTopLeft%,"View1",%v OR $2900,"View2",%b OR $A00,"View3",%n OR $B00)

would display a popup menu with option buttons, with the symbol initially set on on the View1 item ($2000 is ORed into it as well as $900).


Problems with menus

You must ensure that you do not use the same shortcut key twice when defining the menus, as OPL does not check for this.

Each menu definition uses some memory, so ‘No system memory’ errors are possible.

Don’t forget to use mINIT before you begin defining the menus.

If the menu titles defined by mCARD are wider than 40 characters, MENU will raise a ‘Too wide’ error.

Shortcut values must be alphabetic character codes or numbers between the values of 1 and 32. Any other values will raise an ‘Invalid arguments’ error.

Note also that a menu is discarded when an item fails to be added successfully. In effect the previous mINIT statement is discarded together with any previous mCARD statements. This avoids the problem of trying to use a badly constructed menu item.

It is therefore incorrect to ignore mCARD errors by having an ONERR label around an mCARD call (see Error Handling for more details). If you do, the menu is discarded and a ‘Structure fault’ will then be raised on using mCARD or MENU without first using mINIT again.


A menu example

This procedure allows you to press the Menu key and see a menu. You might instead be typing a number or some text into the program, or moving around in some way with the arrow keys, and this procedure returns any such keypresses. You could use this procedure instead of a simple GET whenever you want to allow a menu to be shown, and its shortcut keys to work.

Each of the options in the menus have a corresponding procedure named proc plus the shortcut key letter so for example, the option with shortcut key Ctrl+N (Psion-N) is handled by the procedure procn.

This procedure uses the technique of calling procedures by strings, as described in Advanced Topics. For example:

    PROC kget%:
          LOCAL k%,h$(9),a$(5)
          h$="nosciefgd"              REM our shortcut keys
          WHILE 1
              k%=GET
              IF k%=$122        REM Menu key
                  mINIT
                  mCARD "File","New",%n,"Open",%o,"Save",%s
                  mCARD "Edit","Copy",%c,"Insert",-%i,"Eval",%e
                  mCARD "Search","First",%f,"Next",%g,"Previous",%d
                  k%=MENU
                  IF k% AND (LOC(h$,CHR$(k%))<>0)    REM MENU CHECK
                      a$="proc"+CHR$(k%)
                      @(a$):       REM procn:, proco:, ...
                  ENDIF            REM END OF MENU CHECK
              ELSEIF KMOD AND $4   REM shortcut key pressed directly?
                  k%=k%+$40        REM remove Ctrl modification
                  IF LOC(h$,CHR$(k%)) REM DIRECT SHORTCUT KEY CHECK
                      a$="proc"+CHR$(k%)
                      @(a$):       REM procn:, proco:, ...
                  ENDIF     REM END OF DIRECT SHORTCUT KEY CHECK
              ELSE                 REM some other key
                      RETURN k%
                ENDIF
          ENDWH
    ENDP

procn:, proco:, etc. would need to be specified to use this example in practice on any of the machines:

    PROC procn:
          ...
    ENDP
    
    PROC proco:
          ...
    ENDP
    ...

Note that this procedure allows you to press a shortcut key with or without the Shift key. So Ctrl+Shift+N would be treated the same as Ctrl+N.

Neither LOC nor the @ operator (for calling procedures by strings) differentiate between upper and lower case. If you have Shifted shortcut keys you will need to compare against two sets of shortcut key lists. For example, with shortcut keys %A, %C, %a and %d, you would have upper/lowercase shortcut key lists like hu$="AC" and hl$="ad", and the "MENU CHECK" section becomes:

    IF k%<=%Z                   REM if upper case shortcut key
        IF LOC(hu$,CHR$(k%))
        a$="procu"+CHR$(k%)
            @(a$):              REM procua:, procuc:, ...
        ENDIF
    ELSE                        REM else lower case shortcut key
        IF LOC(hl$,CHR$(k%))
            a$="procl"+CHR$(k%)
            @(a$)               REM procla:, procld:, ...
        ENDIF
    ENDIF

(This calls procedures procua:, procuc:, procla: and procld:). If a shortcut key was pressed directly you cannot tell from k% whether Shift was used; so make the same change to the "DIRECT SHORTCUT KEY CHECK" section, but use IF KMOD AND 2 instead of IF k%<=%Z.


Dialogs

Section Contents

In OPL, dialogs are constructed in a similar way to menus:

Use the up and down arrows to move from line to line, and enter the relevant information, as in any other dialog. You can even press Tab to produce vertical lists of options when appropriate.

Each of the commands like dEDIT and dDATE specifies a variable to take the information you type in. If you press Enter to complete the dialog, the information is saved in those variables. The dialog is then removed, and the screen redrawn as it was.

You can press Esc to abandon the dialog without making any changes to the variables.

If you enter information which is not valid for the particular line of the dialog, you will be asked to enter different information.

Here is a simple example. It assumes a global variable name$ exists:

    PROC getname:
          dINIT "Who are you?"
          dEDIT name$,"Name:"
          DIALOG
    ENDP

This procedure displays a dialog with Who are you? as its top-line title, and an edit box for typing in your name. If you end by pressing Enter, the name you have typed will be saved in name$; if you press Esc, name$ is not changed.

When the dialog is first displayed, the existing contents of name$ are used as the string to edit.

Note that the dialog is automatically created with a width suitable for the item(s) you defined, and is centred in the screen.


Lines you can use in dialogs

This section describes the various commands that can define a line of a dialog. In all cases:

Although examples are given using each group of commands, you can mix commands of any type to make up your dialog.

More details of the commands may be found in Keyword Reference.


Strings, secret strings and filenames

    dEDIT var str$,prompt$,len%

defines a string edit box.

len% is an optional argument. If supplied, it gives the width of the edit box (allowing for the widest possible character in the font). The string will scroll inside the edit box, if necessary. If len% is not supplied, the edit box is made wide enough for the maximum width str$ could be. (You may wish to set a suitably small len% to stop some dialogs being drawn all the way across the screen)

    dXINPUT var str$,prompt$

defines a secret string edit box, such as for a password. A special symbol will be displayed for each character you type, to preserve the secrecy of the string.

    dFILE var str$,prompt$,f%,Uid1&,Uid2&,Uid3&

defines a filename editor or selector box. dFILE automatically has ‘Folder’ and ‘Disk’ selectors on the lines below it. f% controls whether you have a file editor or selector in your dialog, and the kind of input allowed. Files selected may also be restricted by UID. See dFILE in Keyword Reference for full details of how to do this.

Here is an example dialog using these commands:

    PROC info:
          LOCAL n$(30),pw$(16),f$(255)
          dINIT "Your personal info"
          dEDIT n$,"Name:",15
          dXINPUT pw$,"Password:"
          dFILE f$,"Log file,Folder,Disk",0
          RETURN DIALOG
    ENDP

This procedure returns ‘True’ if Enter was used, indicating that the GLOBAL variables n$, pw$ and f$ have been updated.

dEDITMULTI var pData&,p$,widthInChars%,numLines%,maxLen%
defines a multi-line edit box to go into a dialog. Normally the resulting text would be used in a subsequent dialog, saved to file or printed using the Printer OPX (see About OPXs). The use of this dialog command is more complicated than the others (see Keyword Reference for full details).


Choosing one of a list

    dCHOICE var choice%,prompt$,list$

defines a choice list. list$ should contain the possible choices, separated by commas for example, "Yes,No". The choice% variable specifies which choice should initially be shown 1 for the first choice, 2 for the second, and so on.

For example, here is a simple choice dialog:

    PROC dcheck:
          LOCAL c%
          c%=2                              REM default to "View2"
          dINIT "Change View"
          dCHOICE c%,"View:","View1,View2,View3"
          IF DIALOG                   REM returns 0 if cancelled
                ...                         REM change view
          ENDIF
    ENDP

Extended choice lists may also be defined by using more than one dCHOICE statement (see Keyword Reference for full details of how to do this).

    dCHECKBOX chk%,prompt$

creates a checkbox entry. This is similar to a choice list with two items, except that the list is replaced by a checkbox with the tick either on or off. The state of the checkbox is maintained across calls to the dialog. Initially you should set the live variable chk% to 0 to set the tick symbol off and to any other value to set it on. chk% is then automatically set to 0 if the box is unchecked or -1 if it is checked when the dialog is closed.


Numbers, dates and times

    dLONG var long&,prompt$,min&,max&

and

    dFLOAT var fp,prompt$,min,max

define edit boxes for long integers and floating-point numbers respectively. Use dFLOAT to allow fractions, and dLONG to disallow them. min(&) and max(&) give the minimum and maximum values which are to be allowed. There is no separate command for ordinary integers use dLONG with suitable min& and max& values.

    dDATE var long&,prompt$,min&,max&

and

    dTIME var long&,prompt$,type%,min&,max&

define edit boxes for dates and times. min& and max& give the minimum and maximum values which are to be allowed.

For dDATE, long&, min& and max& are specified in "days since 1/1/1900". The DAYS function is useful for converting to "days since 1/1/1900".

For dTIME, long&, min& and max& are in "seconds since 00:00". The DATETOSECS and SECSTODATE functions are useful for converting to and from "seconds since midnight" (they actually use "seconds since 00:00 on 1/1/1970").

dTIME also has a type% argument. This specifies the type of display required:

0

absolute time without seconds

1

absolute time with seconds

2

duration without seconds

3

duration with seconds

4

absolute times in 24 hour clock

8

time not displaying hours

Constants for these values are defined in Const.oph.

For example, 03:45 is an absolute time, while 3 hours 45 minutes is a duration.

This procedure creates a dialog, using these commands:

    PROC delivery:
          LOCAL d&,t&,num&,wt
          d&=DAYS(DAY,MONTH,YEAR)
          DO
                t&=secs&:
          UNTIL t&=secs&:
          num&=1 :wt=10
          dINIT "Delivery"
          dLONG num&,"Boxes",1,1000
          dFLOAT wt,"Weight (kg)",0,10000
          dDATE d&,"Date",d&,DAYS(31,12,1999)
          dTIME t&,"Time",0,0,DATETOSECS(1970,1,1,23,59,59)
          IF DIALOG                              REM returns 0 if cancelled
                ...                               REM rest of code
          ENDIF
    ENDP
    
    PROC secs&:
          RETURN HOUR*INT(3600)+MINUTE*60
    ENDP

The secs&: procedure uses the HOUR and MINUTE functions, which return the time as kept by the machine. It is called twice to guard against an incorrect result, in the (albeit rare) case where the time ticks past the hour between calling HOUR and calling MINUTE.

The INT function is used in secs&: to force OPL to use long integer arithmetic, avoiding the danger of an ‘Overflow’ error.

d& and t& are set up to give the current date and time when the dialog is first displayed. The value in d& is also used as the minimum value for dDATE, so that in this example you cannot set a date before the current date.

DATETOSECS is used to give the number of seconds representing the time 23:59. The first three arguments, 1970, 1 and 1, represent the first day from which DATETOSECS begins calculating.


Results from dDATE

dDATE returns a value as a number of days

To convert this to a date use DAYSTODATE which converts a number of days since 1/1/1990, to the corresponding date. See ref.toc for full details.


Displaying text

    dTEXT prompt$,body$,type%

defines prompt$ to be displayed on the left side of the line, and body$ on the right. There is no variable associated with dTEXT. If you use a null string ("") for prompt$, body$ is displayed across the whole width of the dialog.

type% is an optional argument. If specified, it controls the alignment of body$:

0

left align body$

1

right align body$

2

centre body$

Note that alignment of body$ is only supported when prompt$ is null, with the body being left aligned otherwise.

In addition, you can add any or all of the following three values to type%, for these effects:

$200

draw a line below this item.

$400

make the prompt (not the body) selectable.

$800

make this item a text separator

dTEXT is not just for displaying information. Since DIALOG returns a number indicating the line you were on when you pressed Enter (or 0 if you pressed Esc), you can use dTEXT to offer a choice of options, rather like a menu:

    PROC selact:
          dINIT "Select action"
          dTEXT "Add","",$402
          dTEXT "Copy","",$402
          dTEXT "Review","",$402
          dTEXT "Delete","",$402
          RETURN DIALOG
    ENDP

In each case type% is $402 ($400+2). The $400 makes each prompt selectable, allowing you to move the cursor on to it. Note that only the prompts are selectable. However, the items will be centre aligned in the dialog.

See the Keyword Reference for full details of dTEXT.


Displaying exit keys

Most dialogs are completed by pressing Enter to confirm the information typed, or Esc to cancel the dialog. These keys are not usually displayed as part of the dialog.

However, some dialogs offer you a simple choice, by showing pictures of the keys you can press. A simple "Are you sure?" dialog might, for example, show the two keys ‘Y’ and ‘N’, and indicate the one you press.

If you want to display a message and offer Enter, Esc and/or Space as the exit keys, you can display the entire dialog with the ALERT function.

If you want to use other keys, such as Y and N, or display the keys below other dialog items such as dEDIT, create the dialog as normal and use the dBUTTONS command to define the keys.

ALERT and dBUTTONS are explained in detail in Keyword Reference.


Other dialog information


Positioning dialogs

If a dialog overwrites important information on the screen, you can position it with the dPOSITION command. Use dPOSITION at any time between dINIT and DIALOG.

dPOSITION uses two integer values. The first specifies the horizontal position, and the second, the vertical. dPOSITION -1,-1 positions to the top left of the screen; dPOSITION 1,1 to the bottom right; dPOSITION 0,0 to the centre, the usual position for dialogs.

dPOSITION 1,0, for example, positions to the right-hand edge of the screen, and centres the dialog half way up the screen.


Other dialog features

dINIT can take a second optional parameter to specify additional dialog features. This may be any ORed combination of the following constants,:

value

effect

1

buttons positioned on the right rather than at the bottom

2

no title bar (any title in dINIT is ignored)

4

use the full screen

8

don’t allow the dialog box to be dragged

16

pack the dialog densely (not buttons though)

Constants for these flags are supplied in Const.oph.

It should be noted that dialogs without titles cannot be dragged regardless of the "No drag" setting. Dense packing enables more lines to fit on the screen for larger dialogs.

For example, the following could be used for a large dialog:

    dINIT "Big Dialog",$15

so that the dialog covers the full screen, has buttons (as defined by dBUTTONS) on the right and has items densely packed.


Restrictions on dialogs

The following general restrictions apply to all dialogs:


Toolbars

Section Contents

All OPL programs should use the ROM module Z:\System\Opl\Toolbar.opo to create a toolbar window with a title, four buttons and a clock.

The public interface to Toolbar.opo is supplied in Z:\System\Opl\Toolbar.oph which is reproduced below. The procedures and their usage are then discussed in detail.


Toolbar.oph

    rem Toolbar.oph
    rem Header file for OPL's toolbar
    rem Copyright (c) 1997-1998 Symbian Ltd. All rights reserved.
    
    external TBarLink:(appLink$)
    external TBarInit:(title$,scrW%,scrH%)
    external TBarInitC:(title$,scrW%,scrH%,winMode%)
    external TBarInitNonStd:(name$,scrW%,scrH%,width%)
    external TBarSetTitle:(name$)
    external TBarButt:(shortCut$,pos%,text$,state%,bit&,mask&,flags%)
    external TBarOffer%:(winId&,ptrType&,ptrX&,ptrY&)
    external TBarLatch:(comp%)
    external TBarShow:
    external TBarHide:
    external TBarColor:(fgR%,fgG%,fgB%,bgR%,bgG%,bgB%)
    
    rem The following are global toolbar variables usable by Opl programs
    rem or libraries: usable after toolbar initialisation:
    rem   TbWidth%         the pixel width of the toolbar
    rem   TbVis%           -1 if visible and otherwise 0
    rem   TbMenuSym%       the current 'Show toolbar' menu
    rem                    symbol (to be ORed with shortcut
    rem                    letter)
    rem Flags for toolbar buttons
    
    const KTbFlgCmdOnPtrDown%=$01
    
    rem The order and values of the following are significant so don't change without due care
    
    const KTbFlgLatchStart%=$12            rem start of latchable set
    const KTbFlgLatchMiddle%=$22      rem middle of latchable set
    const KTbFlgLatchEnd%=$32                  rem end of latchable set
    const KTbFlgLatched%=$04                  rem set for current latched item in set
    
    rem End of Toolbar.oph

Typical Toolbar.opo usage

Typically a program would use Toolbar.opo in the following way:


TBarLink:

Usage: TBarLink:(appLink$)

TBarLink: provides all toolbar globals required in your application. It has to be called before TBarInit: and from a higher level procedure in your application than the one in which the globals are used.

appLink$ is the name of the so-called continuation procedure in your main application. TBarLink: calls this procedure, which should then go on to run the rest of your program. This allows the globals declared in TBarLink: to exist until the application exits. appLink$ must represent a procedure with name and parameters like:

    PROC appContTBarLink:
          REM Continue after ‘linking’ toolbar globals
          myAppInit:            REM run rest of program
          ...
    ENDP

i.e. taking no parameters and with no return-type specification character, so that it can be called using @(appLink$):.


TBarColor:

Usage: TBarColor:(foreR%,foreG%,foreB%,backR%,backG%,backB%)

Within the toolbar, the colours for the title text, title background and the clock border background default to black ($00,$00,$00) for the foreground and white ($ff,$ff,$ff) for the background.

TBarColor: sets the RGB values for the foreground colour, and the RGB values for the background colour.

Note: in order to set the colours, the TBarColor: procedure should be called before initialising the toolbar with TBarInit: or TBarInitC: (below).


TBarInit:

Usage: TBarInit:(title$,scrW%,scrH%)

Called at start of application only, this procedure creates the toolbar window, which guarantees that there will be sufficient memory available to display the toolbar at any subsequent time. The toolbar is made invisible when not shown. This procedure also draws all toolbar components except the buttons.

Note that, for speed, TBarInit: turns graphics auto-updating off (using gUPDATE OFF). If automatic updating is required, use gUPDATE ON after TBarInit: returns.

Note also that TBarInit: sets compute mode off (see SETCOMPUTEMODE: in System.opx — EPOC system functions) allowing the program to run at foreground priority when in foreground. By default OPL programs have compute mode on (i.e. they run at background priority even when in foreground).

Note: The toolbar needs a minimum of 4 greys to display the buttons and clock correctly. You should ensure the mode is at least 2-bit (KColorDefWin4GrayMode%) if using TBarInit.

See also TBarInitC:, below.


TBarInitC:

Usage:      TBarInitC:(title$,scrW%,scrH%,winMode%)

Initialises the toolbar in colour mode. TBarInitC: is based on TBarInit: but takes an additional parameter winMode% which defines the window mode used to create the toolbar. You should use at least 4 grey mode (KColorgCreate4GrayMode%) for the window mode as explained above.

See gCREATE for the possible values of winMode%.


TBarSetTitle:

Usage: TBarSetTitle:(name$)

Sets the title in the toolbar.

name$ is the name of your current file for file-based applications (i.e. applications with the APP...ENDA construct containing FLAGS 1), or the name of your application for non-file applications.


TBarButt:

Usage: TBarButt:(shortcut$,pos%,text$,state%,bit&,mask&,flags%)

Adds a button to the previously initialised toolbar.

shortcut$ is the command shortcut for your application, which is used by Toolbar.opo to perform the command when a toolbar button is selected. On selecting the toolbar button, Toolbar.opo calls your procedure to perform the required command or action. shortcut$ is case sensitive in the sense that Toolbar.opo calls your procedure named:

For example, if you have the following two commands that also have associated toolbar buttons:

    mCARD "View","DoXXX",%x,"DoYYY",%Y
    REM shortcuts Ctrl+X,Shift+Ctrl+Y

you would need to provide command-handling procedures:

and you would create buttons using, e.g.

pos% is the button position, with pos%=1 for the top button.

text$ and state% take values as required for gBUTTON.

bit& and mask& are the button’s icon bitmap and mask, used in in the same way as for gBUTTON. Note that a button is a purely graphical entity and so doesn't own the bitmaps. Therefore the bitmap may not be unloaded while the button is still in use.

flags% lets you control how the button is used in two distinct and mutually exclusive ways, as follows:

Two latchable buttons are often used by the built-in applications to indicate the current view. For an example, see the latchable ‘Desk’ and ‘Sci’ buttons in the built-in Calc application.
A set of latchable toolbar buttons can be specified in TBarButt: by setting flags% to one of:

To latch a button down initially to represent the initial setting, OR KTbFlgLatched% with one of the above settings. E.g.

    TBarButt:(sh1$,pos%,txt1$,st%,bit1&,msk1&,
              KTbFlgLatchStart%)
    TBarButt:(sh2$,pos%,txt2$,st%,bit2&,msk2&,
              KTbFlgLatchEnd% OR TbFlgLatched%)

will latch down the second button in the set initially.

In the toolbar window, the button with KTbFlgLatchStart% set must be above the buttons (if any) with KTbFlgLatchMiddle% set, and these in turn must be above the button with KTbFlgLatchEnd%.

Only one button in a set is ever latched and pressing another button unlatches the one that was previously set. After pressing and releasing a previously unlatched button in a latchable set, Toolbar.opo will, as usual, call your command-handling procedure. When the command has succeeded in changing view, this procedure should set the new state of the button by calling TBarLatch:(comp%) where comp% is the button number to be latched. This will also unlatch any button that was previously latched. The example below shows how a ‘View1’ button press, with ‘v’ as shortcut, should be handled. The other latchable button in this set might be ‘View2’ with shortcut ‘w’:

    PROC cmdV%:
          IF SetView1%:=0         REM if no error
                TBarLatch:(KView1TbarButton%)
                REM your CONST KView1TBarButton%
                CurrentView%=1
          ENDIF
    ENDP
    
    PROC cmdW%:
          IF SetView2%:=0                     REM if no error
                TBarLatch:(KView2TbarButton%)      
                REM your const KView2TBarButton%
                CurrentView%=2
          ENDIF
    ENDP

You should call the same command-procedures when the command is performed via a menu or via a keyboard shortcut. This will ensure that the button is latched as required.

A setting of flags% can also be used to specify that your procedure should be called when the toolbar button is tapped (rather than when the button is released, which is the default). The ‘Go to’ button in the Program editor works in this way, displaying the popup list of procedures when the button is touched. To implement this using TBarButt:, pass flags%=KTbFlgCmdOnPtrDown% and provide a procedure named:

    "cmdTbDown"+shortcut$+%:

which could provide a popup menu, as follows:

    PROC cmdTbDownC%:
        REM popup next to button, with point specifying
        REM top right corner of popup
        IF mPOPUP(ScrWid%-TbWidth%,97,KMPopupPosTopRight%,
                                   "Cancel",0,"Clear",%c)
            cmdC%:    REM Do the command itself
        ENDIF
    ENDP

In this case the shortcut is not case-sensitive. Note that when this flag is used, the menu command-procedure is not used directly because a popup is not required when the command is invoked via the menu or via a keyboard shortcut.


TBarOffer%:

Usage: TBarOffer%:(winId&,ptrType&,ptrX&,ptrY&)

Offers a pointer event to the toolbar, returning -1 if used and 0 if not used. If not used, the event is available for use by your application.

It is important to call this procedure whenever you receive a pointer event, even when the event is not in the toolbar window, thus enabling Toolbar.opo to release the current button, both visually and otherwise.

TBarOffer%: handles:

As usual, the word ‘pointer’ indicates a pen.

winId& is the ID of the window that received the pointer event.

ptrType& is pointer event type as returned by GETEVENT32 (pen up, pen down or drag).

ptrX&,ptrY& is co-ordinate of pointer event.


TBarLatch:

Usage: TBarLatch:(button%)

Latches down a toolbar button, where button%=1 for the top button in the toolbar. TBarLatch: also unlatches any button in the latchable set that was previously latched. See TBarButt: for further details on latching buttons.


TBarShow:

Usage: TBarShow:

Makes the toolbar visible. The toolbar must exist before calling this procedure. Use TBarInit: to create an invisible toolbar with no buttons. Use TBarButt: to add buttons.


TBarHide:

Usage: TBarHide:

Makes the toolbar invisible.


Public Toolbar globals

The following toolbar globals, provided by TBarLink:, may be used inOPL applications:


Giving information

Section Contents


Information messages

GIPRINT displays an information message for 2 seconds, in the bottom right corner of the screen. For example, GIPRINT "Not Found" displays Not Found. If a string is too long for the screen, it will be clipped.

You can add an integer argument to control the corner in which the message appears:

value

corner

0

top left

1

bottom left

2

top right

3

bottom right

Constants for these corner values are supplied in Const.oph.

For example, GIPRINT "Who?",0 prints Who? in the top left corner.

Only one message can be shown at a time. You can make the message go away for example, if a key has been pressed with GIPRINT "".


‘Busy’ messages

Messages which say a program is temporarily busy, or cannot respond for some reason, are by convention shown in the bottom left corner. The BUSY command lets you display your own messages of this sort. Use BUSY OFF to remove it.

BUSY "Paused...", for example, displays Paused... in the bottom left corner. This remains shown until BUSY OFF is used.

You can control the corner used in the same way as for GIPRINT.

You can also add a third argument, to specify a delay time (in half seconds) before the message should be shown. Use this to prevent BUSY messages from continually appearing very briefly on the screen.

For example, BUSY "Wait:",1,4 will display Wait: in the bottom left corner after a delay of 2 seconds. As soon as your program becomes responsive to the keyboard, it should use BUSY OFF. If this occurs within two seconds of the original BUSY, no message is seen.

The maximum string length of a BUSY message is 80 characters and an ‘Invalid argument’ error is returned for any value in excess of this.

Only one message can be shown at a time.

EPOC       SDK Home Glossary   Previous   Up