diff --git a/Chapters/ch01-an-example-application.xml b/Chapters/ch01-an-example-application.xml index f50dc5e..faadb4b 100644 --- a/Chapters/ch01-an-example-application.xml +++ b/Chapters/ch01-an-example-application.xml @@ -98,7 +98,7 @@ ENDPROC
For now, we do very little in the way of initialisation. The global variable
The program indicates that it knows about Wimp version 310: whilst pane code will work on RISC OS 2, modern applications should use this as a minimum, since a lot of now-standard functionality such was interactive help in menus as introduced at this point. This means that
The program indicates that it knows about Wimp version 310: whilst pane code will work on RISC OS 2, modern applications should aim for RISC OS 3.1 as a minimum, since a lot of now-standard functionality such was interactive help in menus as introduced at this point. This means that
Error handling is looked after by
For now, there’s not much here: we’re only interested in
For now, there’s not much here: we’re only interested in
The BASIC program can be saved as
If "<PaneDemo$Dir>"="" Then Set PaneDemo$Dir <Obey$Dir>
-The
The
Set PaneDemo$Dir <Obey$Dir>
@@ -201,8 +201,8 @@ SYS "Wimp_OpenTemplate",,"<PaneDemo$Dir>.Templates"
PROCtemplate_load("Main", b%, buffer_size%, -1)
SYS "Wimp_CreateWindow",,b% TO MainWindow%
-WindowWidth% = b%!8 - b%!0 : REM Width is Visible Area Maximum X - Minimum X
-WindowHeight% = b%!12 - b%!4 : REM Height is Visible Area Maximum Y - Minimum Y
+WindowWidth% = b%!8 - b%!0 : REM Width is Visible Area X1 - X0
+WindowHeight% = b%!12 - b%!4 : REM Height is Visible Area Y1 - Y0
PROCtemplate_load("ProgInfo", b%, buffer_size%, -1)
SYS "Wimp_CreateWindow",,b% TO InfoWindow%
@@ -219,7 +219,7 @@ LOCAL templ_size%, indir_size%, workspace%
REM Find the size required for the template and indirected data.
$TemplateName%=LEFT$(name$ + STRING$(12, CHR$(13)), 12)
-SYS "Wimp_LoadTemplate",,,,, -1, TemplateName%, 0 TO ,templ_size%, indir_size%
+SYS "Wimp_LoadTemplate",,,,,-1, TemplateName%, 0 TO ,templ_size%, indir_size%
REM Return if the template won't fit in the buffer.
@@ -264,21 +264,22 @@ IF (q%!32 AND &10000) = 0 THEN
REM Update the window dimensions.
- q%!4 = (screen_width% - window_width%) / 2 : REM Visible Area Minimum X
- q%!8 = (screen_height% - window_height%) / 2 : REM Visible Area Minimum Y
+ q%!4 = (screen_width% - window_width%) / 2 : REM Visible Area X0
+ q%!8 = (screen_height% - window_height%) / 2 : REM Visible Area Y0
- q%!12 = q%!4 + window_width% : REM Visible Area Maximum X
- q%!16 = q%!8 + window_height% : REM Visible Area Maximum Y
+ q%!12 = q%!4 + window_width% : REM Visible Area X1
+ q%!16 = q%!8 + window_height% : REM Visible Area Y1
REM Reset the scroll offsets.
- q%!20 = 0
- q%!24 = 0
+ q%!20 = 0 : REM X Scroll Offset
+ q%!24 = 0 : REM Y Scroll Offset
ENDIF
REM Open the window at the top of the window stack.
-q%!28 = -1 : REM Open window at top of stack
+q%!28 = -1 : REM Window to open behind (-1 is top of stack)
+
SYS "Wimp_OpenWindow",,q%
ENDPROC
diff --git a/Chapters/ch02-a-side-toolbox.xml b/Chapters/ch02-a-side-toolbox.xml
index 6de3eb6..a556c5b 100644
--- a/Chapters/ch02-a-side-toolbox.xml
+++ b/Chapters/ch02-a-side-toolbox.xml
@@ -44,7 +44,7 @@
If one were to survey members of the RISC OS community to find out what a “toolbox” looked like, the answer which came back would probably be along the lines of “like the one in Draw”. Draw’s toolbox has been present as standard on all systems since the days of RISC OS 2, and is still functional to this day. It’s also one of the easiest panes to implement, so let’s start by making one of our own.
+If one were to survey members of the RISC OS community to find out what a “toolbox” looked like, the answer which would come back would probably be along the lines of “like the one in Draw”. Draw’s toolbox has been present as standard on all systems since RISC OS 2, and is still functional to this day. It’s also one of the easiest panes to implement, so let’s start by making one of our own.
The other flag which we have set is
The other flag which we have set is
Down at the bottom of the dialogue, all of the scroll events are off, since we don’t need the pane to scroll. In addition, all of the window colours have been left at their default, Style Guide compliant values.
@@ -82,7 +82,7 @@ SYS "Wimp_CreateWindow",,b% TO ToolBoxWindow%Handling panes is actually fairly straight-forward: it’s just the details which can seem confusing! It boils down to this: if the Wimp won’t do the work for us, we need to track movement of the main window and ensure that every time it moves, we also move the pane into the correct relative position. Fortunately, there are only two ways that a window can move: if we do it ourselves, or if it is done by something outside our application (such as the user, or another application). In the latter case, the request will arrive through the
Handling panes is actually fairly straight-forward: it’s just the details which can seem confusing at first sight! It boils down to this: if the Wimp won’t do the work for us, we need to track movement of the main window and ensure that every time it moves, we also move the pane into the correct relative position. Fortunately, there are only two ways that a window can move: if we do it ourselves, or if it is done by something outside our application (such as the user, or another application). In the latter case, the request will arrive through the
In our existing application, we have the following two lines in
Before either of these two new procedures will do anything, they will check the handle of the window to which the event applies. If it’s the handle of the main window, then they will need to do the work required to handle the pane as well; for any other window, they can simply call the appropriate Wimp SWI as before.
+Each of these event-handling procedures will need to check each incoming event, to see which window it applies to. If it’s the handle of the main window, then – in addition to calling the appropriate Wimp SWI as before – any additional work required to handle the pane will need to be performed as well.
-In the case of
In the case of
DEF PROCopen_window_request(b%)
-IF !b% = MainWindow% THEN
- PROChandle_pane_windows(b%)
-ELSE
- SYS "Wimp_OpenWindow",,b%
-ENDIF
+SYS "Wimp_OpenWindow",,b%
+IF !b% = MainWindow% THEN PROChandle_pane_windows(b%)
ENDPROC
-Of course, if the main window and its toolbox should be acting as one, then in addition to moving when the main window moves, the pane should be closed when the main window closes. We can look after this in a very similar way with our new
Of course, if the main window and its toolbox should be acting as one then, in addition to moving when the main window moves, the pane should be closed when the main window closes. We can look after this in a very similar way with our new
DEF PROCclose_window_request(b%)
IF !b% = MainWindow% THEN
@@ -128,14 +125,15 @@ ENDIF
SYS "Wimp_CloseWindow",,b%
ENDPROC
-These changes deal with things outside of our application moving the main window, but what about us doing it ourselves? Fortunately, there’s only one place where we do, which is at the end of
These changes deal with things outside of our application moving the main window, but what about when we change its position ourselves? Fortunately, there’s only one place where we do this, which is at the end of
REM Open the window at the top of the window stack.
-q%!28 = -1 : REM Open window at top of stack
+q%!28 = -1 : REM Window to open behind (-1 is top of stack)
+
SYS "Wimp_OpenWindow",,q%
-Fortunately, this is just another call to
This is just another call to
DEF PROCopen_main_window
LOCAL screen_width%, screen_height%, window_size%
@@ -162,16 +160,23 @@ IF (q%!32 AND &10000) = 0 THEN
REM Update the window dimensions.
- q%!4 = (screen_width% - window_size%) / 2 : REM Visible Area Minimum X
- q%!8 = (screen_height% - window_size%) / 2 : REM Visible Area Minimum Y
+ q%!4 = (screen_width% - window_width%) / 2 : REM Visible Area X0
+ q%!8 = (screen_height% - window_height%) / 2 : REM Visible Area Y0
+
+ q%!12 = q%!4 + window_width% : REM Visible Area X1
+ q%!16 = q%!8 + window_height% : REM Visible Area Y1
- q%!12 = q%!4 + window_size% : REM Visible Area Maximum X
- q%!16 = q%!8 + window_size% : REM Visible Area Maximum Y
+ REM Reset the scroll offsets.
+
+ q%!20 = 0 : REM X Scroll Offset
+ q%!24 = 0 : REM Y Scroll Offset
ENDIF
REM Open the window at the top of the window stack.
-q%!28 = -1 : REM Open window at top of stack
+q%!28 = -1 : REM Window to open behind (-1 is top of stack)
+
+SYS "Wimp_OpenWindow",,q%
PROChandle_pane_windows(q%)
ENDPROC
@@ -182,43 +187,46 @@ ENDPROC
Now that we have ensured that our
Now that we have ensured that our
Since the arrival of the Nested Wimp with RISC OS 4.02, the
The procedure takes a single parameter,
Thanks to this piece of retrospective documentation, it is safe for us to rely on this behaviour in new software. The
The first thing that we need to do is to create an equivalent window state block for the toolbox pane, which we can then update with the necessary values calculated from the main window’s position. Unfortunately we can’t use our usual scratch block of memory pointed to by
The first thing that we need to do is to create an equivalent window state block for the toolbox pane, which we can then update with the necessary values calculated from the main window’s position. Unfortunately we can’t use our usual scratch block of memory pointed to by
toolbox% = main% + 64
!toolbox% = ToolBoxWindow%
SYS "Wimp_GetWindowState",,toolbox%
-Since the pane can’t be resized by the user, we can be fairly confident that its width and height will still be as they were saved in the templates file. These can be used to give us the values for the pane’s width and height, saving us from having to use constants in the code. Before making any changes to the pane window state block’s contents, we therefore calculate the width and height of the pane’s visible area and store the two values for future use.
+Since the toolbox can’t be resized by the user, we can be fairly confident that its width and height will still be as they were saved in the templates file. These can be used to give us the values for the pane’s width and height, saving us from having to use constants in the code. Before making any changes to the toolbox’s window state block’s contents, we therefore calculate the width and height of the pane’s visible area and store the two values for future use.
-box_width% = toolbox%!12 - toolbox%!4 : REM Visible Area Maximum X - Minimum X
-box_height% = toolbox%!16 - toolbox%!8 : REM Visible Area Maximum Y - Minimum Y
+box_width% = toolbox%!12 - toolbox%!4 : REM Visible Area X1 - X0
+box_height% = toolbox%!16 - toolbox%!8 : REM Visible Area Y1 - Y0
-As already noted, we know where the main window should be on screen. We also know the relationship that we want to have between the main window and its pane, as shown in
As already noted, we know where the main window has ended up on screen. We also know the relationship that we want to have between the main window and its pane, as shown in
toolbox%!16 = main%!16 : REM Visible Area Maximum Y
-toolbox%!8 = main%!16 - box_height% : REM Visible Area Minimum Y
+toolbox%!16 = main%!16 : REM Visible Area Y1
+toolbox%!8 = main%!16 - box_height% : REM Visible Area Y0
In a similar way, the right-hand side of the pane (its
toolbox%!12 = main%!4 : REM Visible Area Maximum X
-toolbox%!4 = main%!4 - box_width% : REM Visible Area Minimum X
+toolbox%!12 = main%!4 : REM Visible Area X1
+toolbox%!4 = main%!4 - box_width% : REM Visible Area X0
The code above deals with the position of the pane in the
There's a very practical reason for this requirement. If something like a toolbar pane goes behind its parent window in the stack, then it will very likely be obscured by its parent. Even if the pane is in front, if it isn’t immediately in front, then it’s possible for other windows to get in between as seen in
There’s a very practical reason for this stacking requirement. If something like a toolbar pane goes behind its parent window in the stack, then it will very likely be obscured by its parent. Even if the pane is in front, if it isn’t immediately in front, then it’s possible for other windows to get in between as seen in
In a similar way, if a window with its pane flag set gains the caret, then the Wimp will give input focus to (and set the ‘window has input focus’ flag at bit 20 of the window flags for) the first window below it in the stack which is not a pane. Finally, when working out which bits of a window might need redrawing following a re-size, the Wimp will treat any panes immediately above it as being transparent – on the basis that the application may be about to move them anyway.
-Keeping the
Keeping the
IF main%!28 <> ToolBoxWindow% THEN toolbox%!28 = main%!28
+toolbox%!28 = main%!28
-There’s one exception to this, however. If the Wimp is already asking us to open the main window behind the pane, then both the pane and the main window must already be in the correct positions in the window stack. In this case, there’s no point attempting to open the pane behind itself, so we just leave things as they are. The pane is now ready to be opened in its new location, using a call to
Opening the toolbox pane directly behind the same window that the main window has been opened behind will result in the pane ending up in front of the main window – exactly where we need it to be. The pane is now ready to be opened in its new location, using a call to
SYS "Wimp_OpenWindow",,toolbox%
-With the pane open in the correct place, all that remains to do is to open the main window. This is done using the block from the
main%!28 = ToolBoxWindow%
-
-SYS "Wimp_OpenWindow",,main%
-
-Putting all of the code above together,
With the pane open in the correct place, there’s nothing else to be done! Putting all of the code above together,
DEF PROChandle_pane_windows(main%)
LOCAL toolbox%, box_width%, box_height%
-REM Get the Window State block for the pane, using some of the spare
-REM space above the data for the state of the main window.
+REM Get the Window State block for the toolbox pane, using some of the
+REM spare space above the data for the state of the main window.
+REM
+REM Note: ON RISC OS 5, we could more clearly use DIM toolbox% LOCAL 64
+REM here to allocate the required memory from the stack.
toolbox% = main% + 64
!toolbox% = ToolBoxWindow%
SYS "Wimp_GetWindowState",,toolbox%
-REM Find the width and height of the pane's visible area.
+REM Find the width and height of the toolbox pane's visible area.
-box_width% = toolbox%!12 - toolbox%!4 : REM Visible Area Maximum X - Minimum X
-box_height% = toolbox%!16 - toolbox%!8 : REM Visible Area Maximum Y - Minimum Y
+box_width% = toolbox%!12 - toolbox%!4 : REM Visible Area X1 - X0
+box_height% = toolbox%!16 - toolbox%!8 : REM Visible Area Y1 - Y0
-REM Move the pane so that it's in the correct X and Y position
+REM Move the toolbox pane so that it's in the correct X and Y position
REM relative to where the main window is to go.
-toolbox%!4 = main%!4 - box_width% : REM Visible Area Minimum X
-toolbox%!8 = main%!16 - box_height% : REM Visible Area Minimum Y
-toolbox%!12 = main%!4 : REM Visible Area Maximum X
-toolbox%!16 = main%!16 : REM Visible Area Maximum Y
+toolbox%!4 = main%!4 - box_width% : REM Visible Area X0
+toolbox%!8 = main%!16 - box_height% : REM Visible Area Y0
+toolbox%!12 = main%!4 : REM Visible Area X1
+toolbox%!16 = main%!16 : REM Visible Area Y1
-REM Unless the main window is to be opened behind the pane, meaning that the
-REM pane must already be in the correct place in the stack, set the pane's
-REM Open Behind so that it appears in the stack where the main window is to go.
+REM Open the toolbox pane behind the same window that the main window
+REM was opened behind. This will place it directly in front of the
+REM main window.
-IF main%!28 <> ToolBoxWindow% THEN toolbox%!28 = main%!28
+toolbox%!28 = main%!28
SYS "Wimp_OpenWindow",,toolbox%
-
-REM Set the main window's Open Behind so that it opens behind the pane.
-
-main%!28 = ToolBoxWindow%
-
-SYS "Wimp_OpenWindow",,main%
ENDPROC
Running our new application should reveal a main window similar to that shown in
REM Move the pane so that it's in the correct X and Y position
REM relative to where the main window is to go.
-toolbox%!4 = main%!4 - box_width% : REM Visible Area Minimum X
-toolbox%!8 = main%!16 - box_height% : REM Visible Area Minimum Y
-toolbox%!12 = main%!4 : REM Visible Area Maximum X
-toolbox%!16 = main%!16 : REM Visible Area Maximum Y
+toolbox%!4 = main%!4 - box_width% : REM Visible Area X0
+toolbox%!8 = main%!16 - box_height% : REM Visible Area Y0
+toolbox%!12 = main%!4 : REM Visible Area X1
+toolbox%!16 = main%!16 : REM Visible Area Y1
-We can replace this by testing the minimum
We can replace this by testing the minimum
With this in place, our own pane begins to behave in a more Draw-like way when it reaches the edge of the screen, as seen in
An alternative to a toolbox at the side of a window, as we
An alternative to a toolbox at the side of a window, as we
The height of the work area (
We have also adjusted the minimum sizes of the bar, although this is as much to keep WinEd happy: with the minimum
We have also adjusted the minimum sizes of the bar, although this is as much to keep WinEd happy as anything else: with the minimum
The window contains two action buttons and a writeable icon, so that we can easily see how the work area moves around in relation to its parent window. All three icons are 52 OS Units high, to match the standard height for a writeable icon, and there is a 4 OS Unit gap around the edges of the work area on all four sides.
@@ -104,7 +104,7 @@ SYS "Wimp_GetWindowState",,toolbar%The calculations for the position of the toolbox will remain as they are, before which we will insert in a similar set of calculations for the new toolbar. To be able to do this, we’ll need the height of the bar – which we can get from its visible area as before.
-box_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Maximum Y - Minimum Y
+bar_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Y1 - Y0
We don’t need the width of the bar, because that will be tied to the width of the main window’s visible area as shown in
The tops of the two windows (
toolbar%!8 = main%!16 - box_height% : REM Visible Area Minimum Y
-toolbar%!16 = main%!16 : REM Visible Area Maximum Y
+toolbar%!8 = main%!16 - bar_height% : REM Visible Area Y0
+toolbar%!16 = main%!16 : REM Visible Area Y1
The horizontal positioning of the toolbar is, if anything, easier than for the toolbox: it aligns completely with the visible area of the main window, so
toolbar%!4 = main%!4 : REM Visible Area Minimum X
-toolbar%!12 = main%!12 : REM Visible Area Maximum X
+toolbar%!4 = main%!4 : REM Visible Area X0
+toolbar%!12 = main%!12 : REM Visible Area X1
This is why the horizontal extent of the pane has to match that of the main window: if the main window is fully extended, the pane has to be able to follow suit.
Just as with our previous example, the two panes must appear directly in front of the main window in the window stack. The exact order doesn’t matter to the Wimp, so we will choose to put the toolbar in front of the main window, and the toolbox in front of the toolbar. When deciding, it pays to look at positions where the different panes might overlap, and consider which will look best to the user.
-As before, we start at the top of the pile of panes and work down towards the main window – so the first thing to open is the toolbox.
+As before, we start at the top of the pile of panes and work down towards the main window – so the first thing to open is the toolbox directly behind the window that’s in fronty of the main window – exactly as we did before.
-IF (main%!28 <> ToolBarWindow%) OR (toolbar%!28 <> ToolBoxWindow%) THEN toolbox%!28 = main%!28
+toolbox%!28 = main%!28
SYS "Wimp_OpenWindow",,toolbox%
-We still need to check to see if the windows are already in their correct places in the stack, but with two panes to consider we must now check both whether the main window is behind the toolbar, and whether the toolbar is behind the toolbox. If either isn’t in the correct place, then we will need to re-position the toolbox – as the top window of the pile – and work down from that.
-
-With the toolbox open, we can open the toolbar behind it...
+With the toolbox open in the correct place, we can open the toolbar behind it, which will mean that it will end up directly in front of the main window.
toolbar%!28 = ToolBoxWindow%
SYS "Wimp_OpenWindow",,toolbar%
-...and then, at the bottom of our little pile of windows, comes the main window itself.
-
-main%!28 = ToolBarWindow%
-
-SYS "Wimp_OpenWindow",,main%
-
Putting all of the new code together with the old, PROChandle_pane_windows() now looks as shown in .
DEF PROChandle_pane_windows(main%)
@@ -156,6 +148,9 @@ LOCAL toolbox%, toolbar%, box_width%, box_height%, bar_height%
REM Get the Window State block for the toolbox pane, using some of the
REM spare space above the data for the state of the main window.
+REM
+REM Note: ON RISC OS 5, we could more clearly use DIM toolbox% LOCAL 64
+REM here to allocate the required memory from the stack.
toolbox% = main% + 64
@@ -172,45 +167,44 @@ SYS "Wimp_GetWindowState",,toolbar%
REM Find the height of the toolbar pane's visible area.
-bar_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Maximum Y - Minimum Y
+bar_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Y1 - Y0
REM Move the toolbar pane so that it's in the correct X and Y position
REM relative to where the main window is to go.
-toolbar%!4 = main%!4 : REM Visible Area Minimum X
-toolbar%!8 = main%!16 - bar_height% : REM Visible Area Minimum Y
-toolbar%!12 = main%!12 : REM Visible Area Maximum X
-toolbar%!16 = main%!16 : REM Visible Area Maximum Y
+toolbar%!4 = main%!4 : REM Visible Area X0
+toolbar%!8 = main%!16 - bar_height% : REM Visible Area Y0
+toolbar%!12 = main%!12 : REM Visible Area X1
+toolbar%!16 = main%!16 : REM Visible Area Y1
REM Find the width and height of the toolbox pane's visible area.
-box_width% = toolbox%!12 - toolbox%!4 : REM Visible Area Maximum X - Minimum X
-box_height% = toolbox%!16 - toolbox%!8 : REM Visible Area Maximum Y - Minimum Y
+box_width% = toolbox%!12 - toolbox%!4 : REM Visible Area X1 - X0
+box_height% = toolbox%!16 - toolbox%!8 : REM Visible Area Y1 - Y0
REM Move the toolbox pane so that it's in the correct X and Y position
REM relative to where the main window is to go.
CASE TRUE OF
WHEN main%!4 > box_width%
- toolbox%!4 = main%!4 - box_width% : REM Visible Area Minimum X
- toolbox%!12 = main%!4 : REM Visible Area Maximum X
+ toolbox%!4 = main%!4 - box_width% : REM Visible Area X0
+ toolbox%!12 = main%!4 : REM Visible Area X1
WHEN main%!4 > 0
- toolbox%!4 = 0 : REM Visible Area Minimum X
- toolbox%!12 = box_width% : REM Visible Area Maximum X
+ toolbox%!4 = 0 : REM Visible Area X0
+ toolbox%!12 = box_width% : REM Visible Area X1
OTHERWISE
- toolbox%!4 = main%!4 : REM Visible Area Minimum X
- toolbox%!12 = main%!4 + box_width% : REM Visible Area Maximum X
+ toolbox%!4 = main%!4 : REM Visible Area X0
+ toolbox%!12 = main%!4 + box_width% : REM Visible Area X1
ENDCASE
-toolbox%!8 = main%!16 - box_height% : REM Visible Area Minimum Y
-toolbox%!16 = main%!16 : REM Visible Area Maximum Y
+toolbox%!8 = main%!16 - box_height% : REM Visible Area Y0
+toolbox%!16 = main%!16 : REM Visible Area Y1
-REM Unless the main window is to be opened behind the toolbar pane, and the
-REM toolbar pane is already behind the toolbox pane, meaning that all three
-REM windows must already be in the correct place in the stack, set the toolbox's
-REM Open Behind so that it appears in the stack where the main window is to go.
+REM Open the toolbox pane behind the same window that the main window
+REM was opened behind. This will place it directly in front of the
+REM main window.
-IF (main%!28 <> ToolBarWindow%) OR (toolbar%!28 <> ToolBoxWindow%) THEN toolbox%!28 = main%!28
+toolbox%!28 = main%!28
SYS "Wimp_OpenWindow",,toolbox%
@@ -219,12 +213,6 @@ REM Set the toolbar window's Open Behind so that it opens behind the toolbox.
toolbar%!28 = ToolBoxWindow%
SYS "Wimp_OpenWindow",,toolbar%
-
-REM Set the main window's Open Behind so that it opens behind the toolbar.
-
-main%!28 = ToolBarWindow%
-
-SYS "Wimp_OpenWindow",,main%
ENDPROC
Running the updated application should reveal a new toolbar attached to the top of the main window, as shown in . If resized or moved around the screen, both the toolbar and the original toolbox should move and adjust their sizes together. Note that if the caret is placed in the toolbar’s writeable icon, the main window is shown as having input focus: this is a result of the panes having their ‘window is a pane’ flags set.
@@ -268,8 +256,8 @@ ENDPROC
An alternative approach would be to push the toolbox down the side of the main window, so that it sits below the base of the toolbar. This is simple enough to do, and can be achieved by adding in the height of the toolbar to the calculation in
toolbox%!8 = main%!16 - (bar_height% + box_height%) : REM Visible Area Minimum Y
-toolbox%!16 = main%!16 - bar_height% : REM Visible Area Maximum Y
+toolbox%!8 = main%!16 - (bar_height% + box_height%) : REM Visible Area Y0
+toolbox%!16 = main%!16 - bar_height% : REM Visible Area Y1
With this small modification in place, the toolbar is now anchored lower down the side of the main window and slides in below the work area of the toolbar as seen in
However, if we’re happy to only support machines from the RiscPC onwards – which isn’t an unreasonable idea in modern software – then we can improve things more easily. RISC OS 3.5 introduced a new
To make the application as general as possible, we’ll start by adding the code shown in
To make the application as general as possible, we’ll start by adding the code shown in
SYS "XOS_SWINumberFromString",,"Wimp_ResizeIcon" TO ;flags%
ResizeIconAvailable% = ((flags% AND 1) = 0)
-This attempts to read the number for the
The code attempts to read the number for the
The resizing operation itself can be performed in IF ... ENDIF
statement, so that it will only be called if the
Finall,
Finally,
DEF PROChandle_pane_windows(main%)
LOCAL toolbar%, bar_height%
-REM Get the Window State block for the toolbar pane, using more of the
+REM Get the Window State block for the toolbar pane, using some of the
REM spare space above the data for the state of the main window.
+REM
+REM Note: ON RISC OS 5, we could more clearly use DIM toolbox% LOCAL 64
+REM here to allocate the required memory from the stack.
toolbar% = main% + 64
@@ -113,30 +116,23 @@ SYS "Wimp_GetWindowState",,toolbar%
REM Find the height of the toolbar pane's visible area.
-bar_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Maximum Y - Minimum Y
+bar_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Y1 - Y0
REM Move the toolbar pane so that it's in the correct X and Y position
REM relative to where the main window is to go.
-toolbar%!4 = main%!4 : REM Visible Area Minimum X
-toolbar%!8 = main%!16 - bar_height% : REM Visible Area Minimum Y
-toolbar%!12 = main%!12 : REM Visible Area Maximum X
-toolbar%!16 = main%!16 : REM Visible Area Maximum Y
+toolbar%!4 = main%!4 : REM Visible Area X0
+toolbar%!8 = main%!16 - bar_height% : REM Visible Area Y0
+toolbar%!12 = main%!12 : REM Visible Area X1
+toolbar%!16 = main%!16 : REM Visible Area Y1
-REM Unless the main window is to be opened behind the toolbar pane, and the
-REM toolbar pane is already behind the toolbox pane, meaning that all three
-REM windows must already be in the correct place in the stack, set the toolbox's
-REM Open Behind so that it appears in the stack where the main window is to go.
+REM Open the toolbar pane behind the same window that the main window
+REM was opened behind. This will place it directly in front of the
+REM main window.
-IF main%!28 <> ToolBarWindow% THEN toolbar%!28 = main%!28
+toolbar%!28 = main%!28
SYS "Wimp_OpenWindow",,toolbar%
-
-REM Set the main window's Open Behind so that it opens behind the toolbar.
-
-main%!28 = ToolBarWindow%
-
-SYS "Wimp_OpenWindow",,main%
ENDPROC
The code here should be comparable to that found in
toolbar%!20 = main%!20 : REM X Scroll Offset
-Things to consider here are that both the main window and the toolbar are the same width (we copy the
Things to consider here are that both the main window and the toolbar are the same width (we copy the
If the pane were up the side of the window instead of across the top, and the vertical extents were the same, it would be possible to copy the vertical scroll offset (at offset 24 into the window state block) across to the pane instead. This might be useful for a pane containing row numbers, as seen in the
DEF PROChandle_pane_windows(main%)
LOCAL toolbar%, bar_height%
-REM Get the Window State block for the toolbar pane, using more of the
+REM Get the Window State block for the toolbar pane, using some of the
REM spare space above the data for the state of the main window.
+REM
+REM Note: ON RISC OS 5, we could more clearly use DIM toolbox% LOCAL 64
+REM here to allocate the required memory from the stack.
toolbar% = main% + 64
@@ -181,34 +180,27 @@ SYS "Wimp_GetWindowState",,toolbar%
REM Find the height of the toolbar pane's visible area.
-bar_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Maximum Y - Minimum Y
+bar_height% = toolbar%!16 - toolbar%!8 : REM Visible Area Y1 - Y0
REM Move the toolbar pane so that it's in the correct X and Y position
REM relative to where the main window is to go.
-toolbar%!4 = main%!4 : REM Visible Area Minimum X
-toolbar%!8 = main%!16 - bar_height% : REM Visible Area Minimum Y
-toolbar%!12 = main%!12 : REM Visible Area Maximum X
-toolbar%!16 = main%!16 : REM Visible Area Maximum Y
+toolbar%!4 = main%!4 : REM Visible Area X0
+toolbar%!8 = main%!16 - bar_height% : REM Visible Area Y0
+toolbar%!12 = main%!12 : REM Visible Area X1
+toolbar%!16 = main%!16 : REM Visible Area Y1
REM Align the toolbar pane's scroll offset with the main window.
-toolbar%!20 = main%!20 : REM X Scroll Offset
+toolbar%!20 = main%!20 : REM X Scroll Offset
-REM Unless the main window is to be opened behind the toolbar pane, and the
-REM toolbar pane is already behind the toolbox pane, meaning that all three
-REM windows must already be in the correct place in the stack, set the toolbox's
-REM Open Behind so that it appears in the stack where the main window is to go.
+REM Open the toolbar pane behind the same window that the main window
+REM was opened behind. This will place it directly in front of the
+REM main window.
-IF main%!28 <> ToolBarWindow% THEN toolbar%!28 = main%!28
+toolbar%!28 = main%!28
SYS "Wimp_OpenWindow",,toolbar%
-
-REM Set the main window's Open Behind so that it opens behind the toolbar.
-
-main%!28 = ToolBarWindow%
-
-SYS "Wimp_OpenWindow",,main%
ENDPROC
Loading this version of the application, we can now scroll around the main window’s work area with the column headings in the toolbar remaining in step as seen in
The examples in this tutorial are written in BASIC, but the techniques are equally applicable to other languages such as C – I hope that I have managed to explain them in a way that allows them to be applied in your environment of choice. The example code is all licenced under the MIT No Attribution Licence, with the aim of making it as widely useful as possible.
-Many thanks to all those on the ROOL Forums who have offered suggestions while I’ve worked on this guide.
+Many thanks to all those on the ROOL Forums who have offered suggestions while I’ve worked on this guide; in particular Steve Drain, whose input helped to clarify some of my misunderstandings on the subject.