3-Lib banner

The Absolute Beginners Guide to OPL

P104 - OPL/16 - Status Symbols


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're looking this week at the Series 3 status window and how to implement it in an OPL program. Notice first how it's supposed to operate. Many people seem genuinely unaware of this window, merely assuming it's a part of some applications and not others. In fact, nearly all professionally written programs respond to the Control-Menu keystroke and 'do the right thing'. Try it on a few right now, especially the built-in ones. The status window is a three-way toggle, from full to mini to none, and should be remembered for each application.

Run the RMREvent example program and try the same keypress. Keep pressing it and notice that the status window behaves correctly. Mind you, this is only an example program and RMR haven't bothered putting in code to change the way the main screen is laid out, so the text etc stays put, with white space up to the status window or screen edge.

Screen shot

Open up the OPL editor as usual and note the global Statwin% near the top. This variable keeps track of the state of the window (0 being nominally set as 'off', with 1 meaning 'mini' and 2 meaning 'full' etc). You'll note from earlier sessions that procedure Init: is one of the first things done when RMREvent starts. Find the procedure now and note that its last line is to call another initialisation procedure, Initscn: , i.e. 'Initialise Screen'.

Let's take a look inside Initscn:

Screen shot

The SCREEN 0,0 command just sets the text window used by RMREvent to zero size. You may not have come across this concept before, but essentially there are two different ways a program can write to the screen in OPL. The text and graphic windows are roughly overlaid over the same area, the former displaying just ASCII characters and the latter able to be controlled at the level of individual pixels. Because of the greater flexibility of the graphics window, 99% of real-world programs tend to use it for all screen output. Setting the text window to zero size does two things: it is a way of saving a few bytes of memory by telling OPL not to bother even tracking what happens in this area, and it also lets system status information show through, but more of that below.

The rest of the procedure is largely an IF...ELSE...ENDIF structure, using gSETWIN to set up the size of the graphics window according to how big the status window is supposed to be. The full values of Width% and Height% are used if there is to be no window, with 32 or 64 pixels less set up for the graphic window width if need be. Within each clause, there's an additional command, STATUSWIN, which you'll hopefully find intuitive (especially after consulting your OPL manual!). It's this command which does the work of asking for a status window from the SIBO operating system.

One very important thing to notice is that if we hadn't reduced the size of our graphics window, the status window served up would be completely hidden. As a rough guide for any given application, the text window is on 'top', followed by the graphics window and then any system windows. It's up to you, the programmer, to manage the size of your windows to achieve the desired result for the user.

Having established a graphics window, it's up to you what you do with it. Simple programs (or games) might get away with only using this default window (with a graphics id of 0 if you're interested). RMREvent takes the more flexible approach of setting up an almost identical 'floating' window on top of the default one, with the presumed advantage that in a real application the windows can be cascaded or moved in front of or behind each other. Note the use of the *Statwin% multiplier in the two last graphics commands to make sure the right width value gets used.

So we've set up the initial screen. What happens when the user presses Control-Menu? You may remember from the event loop we looked at in a previous session, that Menu with the Control modifier calls a procedure called Status:, so let's move to this now.

Screen shot

The first few lines should hopefully be obvious. Statwin% is just toggled down by a single unit, resetting to 2 if taken below zero. Thus we have the logic for our status window toggle. gCLOSE is used to make sure our 'floating' graphics window is closed (prior to being recreated at the right size). InitScn: is then called again to do the resizing of the applications graphics window and the resizing of the SIBO status window in the same way as above.

I said earlier that it's important the user's status window preferences are saved, for each application. After all, some programs might deserve a clock and calendar more than others. Having made the changes to the window sizes, SaveCFG: is used (we'll look at how this works in a future session) to make sure the changes are remembered.

Finally (and importantly) Display: is called. In a real program, this would probably recalculate many aspects of the graphics display and redraw lines, tables, scroll bars etc to suit the new size. RMREvent just draws the same old thing, so this is a good place to start in customising what your own application shows the user.


Programming index