diff --git a/Chapters/ch05-the-nested-wimp.xml b/Chapters/ch05-the-nested-wimp.xml index 9c5182a..bf7ff91 100644 --- a/Chapters/ch05-the-nested-wimp.xml +++ b/Chapters/ch05-the-nested-wimp.xml @@ -46,7 +46,7 @@

Over the past few chapters, we have explored how to use pane windows to add toolboxes and toolbars to our small application. It has been a fairly manual process: setting the windows up and then keeping everything in step whenever things move on screen.

-

If we’re willing to forego compatibility back to RISC OS 2, then there is another way. The Nested Window Manager (or Nested Wimp, as we’ll call it from now on) was introduced by Acorn back in the late 1990s, as an add-on for the RiscPC-era systems. Intended to support things like web browsers with complex framesets and embedded objects, it is included as a standard part of the OS in RISC OS 4, 5 and Six.

+

If we’re willing to forego compatibility back to RISC OS 2, then there is another way. The Nested Window Manager (or Nested Wimp, as we’ll call it from now on) was introduced by Acorn back in the late 1990s, as an add-on for the RiscPC-era systems. Intended to support things like web browsers with complex framesets and embedded objects, it is included as a standard part of the OS in RISC OS 4, 5 and Six. Documentation was initially provided in the Nested Window Manager Functional Specification, although these days many of the details can be found in the standard documentation.

@@ -59,15 +59,17 @@
Re-creating our toolbar -

To see how the Nested Wimp works, we’ll re-create our column-heading toolbar from the last chapter using its functionality – it looked as seen in . We will take as our base.

+

To see how the Nested Wimp works, we will re-create our column-heading toolbar from the last chapter using parent and child windows instead of panes. In its previous incarnation of , which we will use as our base, it looked as seen in .

-

Starting with the Templates file, we will need to make a small change to the toolbar window: it is not necessary to set the ‘window is a pane’ flag for nested windows, as the behaviour is implicit in the nesting, so we will untick Pane in the Toolbar window’s flags as seen in . The Moveable flag remains unset; there are no other changes.

+

Starting with the Templates file, we will need to make a small change to the toolbar window. Moving to the Nested Wimp sees a change in terminology and approach: the toolbar is no longer a pane, but a child window, nested into the main or parent window. In practical terms, this means that we should no longer set the ‘window is a pane’ flag for the toolbar, as the reqired effects will instead be obtained when we nest it into the main window. In fact, leaving the ‘window is a pane’ flag set for child windows can cause the two approaches to clash – with some undesirable effects on the Wimp’s stability.

+ +

For this reason, we will untick Pane in the Toolbar window’s flags as seen in . The Moveable flag remains unset, and there are no other changes to make.

-

The next thing that we will need to change is our application’s !Run file. Since we will be using the Nested Wimp, we need to check that it is actually present on the system – which we do as seen in .

+

The next thing that we will need to change is our application’s !Run file. Since we will be using the Nested Wimp, we need to check that it is actually present on the system before our application tries to start – which we do as seen in .

Set PaneDemo$Dir <Obey$Dir> @@ -76,7 +78,7 @@ RMEnsure WindowManager 3.80 Error PaneDemo requires the Nested Window Manager. WimpSlot -min 96K -max 96K Run <PaneDemo$Dir>.!RunImage -

Since the Window Manager can’t be replaced whilst the system is running, all that we can do is test for it and refuse to start up if it isn’t present. If this happens, the user will need to install an update in !Boot – although as already noted, a suitable version of the Window Manager is present in ROM with RISC OS 4, 5 and Six.

+

Since the Window Manager can’t be replaced whilst the system is running, all that we can do is test for it and refuse to start if it isn’t present. If this happens, the user will need to install an update in !Boot – although as already noted, a suitable version of the Window Manager is present in ROM with RISC OS 4, 5 and Six.

We will also need to update our call to Wimp_Initialise in PROCinitialise. Instead of passing 310 in R0 to indicate that we wish to use the features of RISC OS 3.1, we must now pass 380 as shown in , to tell the Wimp that we want its nested functionality to be available to us.

@@ -153,11 +155,11 @@ REM Open the window at the top of the window stack. main%!28 = -1 : REM Window to open behind (-1 is top of stack) -

The first difference from our previous examples comes with the call to Wimp_OpenWindow – instead of simply passing a pointer to the main window’s state block in R1, we’re using the so-called “extended syntax” of the SWI.

+

The first difference from our previous examples comes with the call to Wimp_OpenWindow – instead of simply passing a pointer to the main window’s state block in R1, we will use the so-called “extended syntax” of the SWI.

SYS "Wimp_OpenWindow",,main%, &4B534154, -1, &0 -

It still takes a pointer to the window state block, but now R2 contains the familiar Wimp magic constant of &4B534154 – or ‘TASK’ in ASCII. If present, this unlocks more functionality from the call: R3 will then take the handle of this window’s parent window, while R4 takes the nesting flags.

+

This extended form still takes a pointer to the window state block, but now R2 contains the familiar Wimp magic constant of &4B534154 – or ‘TASK’ in ASCII. If present, this unlocks more functionality from the call: R3 will then take the handle of this window’s parent window, while R4 takes the nesting flags.

For the main window, we supply a parent window handle of −1 to indicate that it will be a top level window – that it is not to be treated as being nested within any other window. This makes it exactly the same as a window opened using the conventional version of the SWI. None of the nesting flags apply, so they are set to &0.

@@ -254,9 +256,9 @@ toolbar%!16 = main%!16 : REM Visible Area Y1

As can be seen from the first two columns, the anchor points in the nesting flags directly correspond to the four visible area coordinates stored at offsets 4 to 16 of the pane’s window state block. In each case, when setting up the pane’s visible area, we assign a value based on one of the visible area coordinates in the main window’s state block, as shown in column three. This is the key to working out the anchoring: if we look at the value which we assign in each case, it will tell us where we have anchored that side of the pane window.

-

Take the visible area X0 value at toolbox%!4, for example: we assign this from main%!4, which is the visible area X0 of the main window. This tells us that the visible area X0 of the pane (the left edge of the child window) is attached to the visible area X0 of the main window. If we look at the options in , we can see this gives us a flag value of %01 – “Link to the left or bottom (X0 or Y0) of the parent’s visible area”.

+

Take the visible area X0 value at toolbox%!4, for example: we copy this from main%!4, which is the visible area X0 of the main window. This tells us that the visible area X0 of the pane (the left edge of the child window) is attached to the visible area X0 of the main window. If we look at the options in , we can see this gives us a flag value of %01 – “Link to the left or bottom (X0 or Y0) of the parent’s visible area”.

-

Similarly, the visible area X1 value at toolbox%!12 is being assigned from main%!12, which is the visible area X1 of the main window. From this, we can tell that the right edge of the pane will be attached to the visible area X1 of the main window, giving us a value of %10 – “Link to the right or top (X1 or Y1) of the parent’s visible area” – from .

+

Similarly, the visible area X1 value at toolbox%!12 is being copied from main%!12, which is the visible area X1 of the main window. From this, we can tell that the right edge of the pane will be attached to the visible area X1 of the main window, giving us a value of %10 – “Link to the right or top (X1 or Y1) of the parent’s visible area” – from .

For the visible area Y0 value at toolbox%!8, we assign main%!16 - bar_height%; this is referencing main!%16, or the visible area Y1 of the main window. The visible area Y1 at toolbar%!16 is assigned main%!16, which is again the visible area Y1 of the main window. Consequently, we can tell that both the bottom and top edges of the pane will use values of %10 – “Link to the right or top (X1 or Y1) of the parent’s visible area” – from .