The Absolute Beginners Guide to OPL
P103 - OPL/16 - Menus for real
These tutorials use the 16-bit version of
RMR Software's excellent
"RMREvent" example
program, disecting it bit by bit to show you how and why it works. Make
sure you've got the latest
version, v1.00.
We detected the [Menu] keypress last time, simply calling a procedure
called Menu: . One of the trickiest parts of setting up a professional
OPL program is always giving the user as consistent an interface as possible.
For example, he or she should always have the choice of using menu options or
corresponding [Psion][key] hotkeys and wherever possible these hotkeys should
match similar functions in the built-in applications (e.g. [Psion]-[N] for 'New
file'). Let's look at RMREvent's menu system. Find the Menu: procedure:
Short, isn't it? The user's asked for a menu so that's exactly what we
give them. Note a few points in particular:
- Some hotkeys are quoted with a minus sign in front - this just tells
OPL to insert a horizontal dividing line after the menu option, a facility
which helps divide up long menu cards and make them more intuitive.
- Some hotkeys are quoted with an uppercase letter, e.g. "%Z",
meaning that the they'll appear as [shift][Psion][key] on the actual menu. Try
to keep your use of shifted hotkeys to a minimum as they're fiddlier to use at
the end of the day, but there will always be occasions when you want to use a
particular letter and find the unshifted version has already been taken.
- The third menu card starts with a single control character. Psion
thoughtfully included the 'diamond' character in the control character set of
the Series 3 range and CHR$(4) is the way to display it. Each Series 3
program should make an effort to support the diamond key, perhaps to switch
between views or tables inside the application.
- The results of the user's spell inside the menu are returned back to
the main program using the global key%, but 512 is added to the hotkey
value before doing so. This is to make it seem to the main program that the
user had pressed [Psion][key] after all, simplifying what RMREvent has to do to
just handling one method of selecting the next action. Notice that it would
have been just as easy to leave the menu returns as 'plain' hotkey values and
instead strip off the '512' bit from [Psion][hotkey] combinations pressed
directly elsewhere in the application. Either way, the aim is to reduce one
alternative control method to the form of the other, giving us less to do in
the code.
- Finally, note that OPL itself handles the user pressing [Psion][key]
while the menu is displayed, returning just the bare hotkey rather than 512
plus the hotkey. This again helps and is one less thing you have to watch out
for.
Being able to use an application framework like RMREvent is at its most
useful when setting up code to handle keys and menus. By simply replacing
RMREvent's menu options with your own and then calling your custom procedures,
it should be possible to produce a working real-world program in a small
fraction of the time it would take to write it from scratch, even as an
experienced user.
Note as well that in a real-world program you'll also want to have a
third way of interacting with the program, i.e. the use of the cursor keys,
[Tab], [Enter] etc. to allow navigation round your application's screens. Each
of these keypresses is just trapped in the way already described, inside the
main event loop, and custom procedures and commands called as appropriate.
So where have we got to? We've seen how to trap keypresses directly and
to determine from the user what he or she wants to happen next. Let's look at a
typical example. Say the user presses [Psion][N] or selects 'New file' from the
RMREvent menu. Our event loop then calls the procedure Newfile:
Like many of your own custom procedures, this is just a short routine to
do a specific job. Here we want to ask for a new file name and, if one is
supplied, to create it. There are a few bits to note especially:
- The structure of the IF DIALOG bit is very elegant. RMREvent
is using the fact that pressing [Esc] when a dialog is shown returns zero, i.e.
a logical 'False'. Thus if the user changes their mind and presses [Esc], the
bit inside the IF....ENDIF section doesn't get executed.
- RMREvent puts up a flashing BUSY message before going off to
create its new file and then cancels the BUSY afterwards. This,
although not strictly necessary here, demonstrates a very important principle
in programming. Never leave the user unsure what's happening for longer
than a second or so. If something your program is doing is liable to take
longer than that, make sure you tell the user. If you don't, they'll
start pressing keys etc. to try and wake the program up, whereupon those key
presses will get acted on next and potentially cause much confusion.
- RMREvent is careful here to cross every 't' and dot every 'i'. By
using PARSE$ here (see your OPL manual) it is making sure that the
file specification in File$ is absolutely correct as far as OPL's
concerned. Although you can do a lot of checks yourself in OPL and can
concatenate strings of text that are to make up a file specification, it makes
efficient sense to use functions that are already present in the language.
Having finished its file creation job, the procedure then returns
control back to the all-powerful event loop described earlier. At which point
the whole cycle starts again.
See you next week, when we'll be looking at handling the Series 3 status
window and zoom functions.
Go to next lesson |
Programming index