Windows on the World

Just before I diverted onto MessageTrans and errors, I made a start on windows (part 5 - see the Acorn Education website or order a copy of the Archive CD for this article). However, looking at the contents of my inbox, it seems that I need to explain more about windows than I did.

In part 5, I discussed the basics of creating a window - now on with the story....

Resizing

As you know, the RISC OS window has the ability to be resized by dragging the resize icon (bottom right of the window, under a scrollbar). When this is performed, you are changing the visible are to within the minimum size as defined at offset 68 and 70 (unfortunately, these are 2 bytes each. While this is not a problem for GCC, LCC or Norcroft, it is for EasyC. In all but EasyC, the short type is two bytes, in EasyC, it is 4 - this is not an error in EasyC, but in that the ISO standards for C say that a short can be any value upto and including an int, but must be more than a char). In the header file (window.h) supplied on the cover disc, these two variables are defined as

short int win_min_width;
short int win_min_height;

If these are set to zero, the minimum width is taken as the window's title and height as the size required for any scrollbars and arrows.

It is possible to set both of these parameters in one go (good news for EasyC people!). If the header file is altered to say instead of the above the following, we can do something quite fun...

int window_params;

Now, if we pass into this something like 300 + 400 << 16, it will pass 300 into the offset at +68 and 400 into offset +70 (the <<16 shifts the value 16 bits to the left).

Scroll Offsets

int scroll_x and int scroll_y are the two parameters used by the window.h header file for setting the scroll offset. These two values basically set the part of the total work area of the window currently visible. Setting these at zero results in the top left corner of the visible area co-inciding with the origin of the work area. !Part2a on the cover disc shows this. It is confirmed by the position of the scroll bars - both are at their extreme positions (hard left and hard top).

Normally, the work area or the window is larger than the visible area, we can therefore set these values to be in a different position of the window. The x parameter must be positive (since you can only scroll to the right of the work area, while y must be negative as you can only ever scroll below the origin. For amusement, change the scroll_x and scroll_y to be 100 and -200 respectively, recompile and see the difference.

Window colours

Defined as the char variables between signed int flags and int workarea_min_x, these single byte values define the colour of the window. !Part2a when run shows the normal RISC OS colours while !Part2b shows what can happen when these values are changed (parental advisory warning should be observed when run though!)

Window flags

These are really important as they set what window can do and what the WIMP has to do to handle the window. In window.h, this is defined as signed int flags;. It is a 32 bit word. Each flag can be considered as either on (1, otherwise called set) or off (unset, 0). The window flags are given below.

Bit zero is the least significant bit with bit 31 the most. All this means is that when you write it down, bit zero is the number furthest to the right.

You can see though that it can be a major problem to calculate these values by hand. To get around that problem, you can use something like !Toolkit (from the CBSA website) or roll your own simple command line program (it can be done very simply, you should have already performed a similar task when I covered the Wimp_Poll SWI).

A program (such as !Toolkit) comes in very handy for the calculation of these values. There are other programs out there which do a similar job - the Nutshell CD (from R-Comp, which also contains the original version of the book these tutorials are based on) has such a program which does the same sort of job.

Flag 4 should only be set if the window does not contain elements such as graphics which the WIMP cannot update automatically when redrawing the window. As we are yet to put anything into our applications which contains icons or graphics, then this flag must be set.

Flag 5 (pane) is set if the window is a pane. You will have seen panes if you have ever used !Draw - the pane is the window attached to the main window containing various drawing icons.

Flags 8 and 9 are set if you need to respond to a scroll request. Most of the time, this is not necessary as the WIMP can handle these. Sometimes though, they need to be set if the program has to respond to it (such as in !Edit - here the application wants to ensure that the top or bottom of the visible area always coincides with the start of the text).

Flag 10 sets how colours are handled. There are two methods of colour handling here - GCOL (colours 0 to 254; 255 is not used as it is a flag) or the WIMP colours. Depending on your machine depends on which is the more limited. Modern machines are capable of displaying up 16 million colours, while the old machines (such as the A300s, 440, 540 and 3000) don't. The advantage of using the GCOL colours is that colour 15 is always colour 15 irrespective of screen mode, however if you use the WIMP colours and decide on something in the 32K colour mode then swap down, the WIMP will use the nearest colour to the original. This can lead to very messy windows!

Hot keys are the likes of F3 to save and work when flag 12 is set. When set and a hot key is pressed, the poll routine is notified of this. Remember though, when a hot key is pressed, it is the task which "owns" the caret which recieves the hot key request - this may not be your task. Assuming that it your application which owns the caret, then what will be passed is a key code (which I covered in the Wimp_Poll tutorials) for the application to do as it will with.

For the moment, we shall just ensure that this is unset.

The flags really worth toying around with are those at 1, 6 and 24 to 30. Replace the flags value in main to any of the following and see what happens...

0xff000010 (bit 1 unset)		0xff000052 (bit 6 set)
0x8f000012		0xd6000012
0x80000010 (you will need to reset your machine if you use this one - why?)

Window title

The title of a window can be displayed in the standard system font (default in the ARM 3 machines), anti-aliased (default from OS 3.5 on) or can be a sprite. The only constraint is that it must fit between the horizontal bounding lines of the titlebar in the window. In window.h, this is represented by int titlebar_icon_flags; with the details (if text) passed into either char title, or indirected if it is longer than 12 characters. For now, I'll stick with titles under 12 characters. As the name implies, this variable contains flags, but thankfully, we only really need be concerned with 4 of them.

If we want a simple piece of text, very little has to be done to achieve it. To give full centreing text, we pass in a value of 11001 (0x19) and strcpy into char title the text. What could be simpler?

Work area flags

These are slightly unusual in that a full 32 bit word (int) is used, but of this only bits 12 - 15 are utilised. The flag values were described in C the WIMP 8 (The reason why II).

It is very important to note that in contrast to the other sets of flags, the 4 bits used are treated as a single 4 bit word which can take any one of the 16 unique and mutually exclusive values (that is, any integer in the range 0 to 15).

As we are using a 4 bit integer, it has to be moved into the correct position by shifting the value 12 bits left (<< 12). Therefore if we used a value of 3 (click notifies task), this will become 3 << 12 (or 0x3000) in the work area flags.

Misc...

And finally we have the loose ends section. In create.c the line window->open_handle = -1; is used. This tells the WIMP where in the stack of windows the window from our task is to be placed. By supplying it with -1, we tell the WIMP that we want our window to be the top window when the application is opened. If we supplied -2, this does the reverse.

The line window->sprite_area_ctrl_block = 0; (also in create.c) is there so we can insert a pointer to a sprite area. It is set if the window contains sprites by themselves or as icons.

window->no_icons = 0; tells the application how many icons are being defined for this window within the window block. As for most of the time this will be dealt with separately, it can be safely ignored. However for completeness, these sprites are held in icon blocks after the window->no_icons parameter (offset start + 88). These blocks are all 32 bytes long. I will be dealing with icons next time.

Okay, there has been a lot to look at this time. Feel free to play around with !Part2a and !Part2b on the cover disc this month and have a go at writing the window flag program.

Acorn education site : http://www.acornusers.org/education/C.html
CBSA site : http://www.acornusers.org/cbsa/index.html