In
In
Those familiar with RISC OS will know that some applications handle their toolbars slightly differently, however. NetSurf is one such application, as seen in
To show how this works, we will take the responsive toolbar that we created in the
The first thing that we will need to do is make a couple of small changes to the window templates. The toolbar will need to be wide enough to span the full width of the main window and its furniture (the vertical scroll bar on the right), so we will need to increase the toolbar’s work area by the width of that furniture. However, the Nested Wimp constrains child windows to the work area of their parent by default, so even if we did this, the toolbar would still be clipped such that it didn’s obscure the main window’s scroll bar.
+The first thing that we will need to do is to make a couple of small changes to the window templates. The toolbar will need to be wide enough to span the full width of the main window and its furniture (the vertical scroll bar on the right), so we will need to increase the toolbar’s work area by the width of that furniture. However, the Nested Wimp constrains child windows to the work area of their parent by default so, even if we do this, the toolbar would still be clipped such that it doesn’t obscure the main window’s scroll bar unless we also make a second change.
-To get around this, we need to designate the toolbar as being a
To make the design work, we will also need to designate the toolbar as being a
The documentation notes that this flag “has no meaning for top-level windows, so the bit should always be cleared in such cases to allow for future expansion”.
+The documentation notes that this flag “has no meaning for top-level windows, so the bit should always be cleared in such cases to allow for future expansion”. Our toolbar is a child window, so this isn’t a problem.
-The width of the toolbar work area is currently set to be the same as that of the main window work area, so this will need to be increased to allow the toolbar to extend over the space taken up by the vertical scroll bar. The problem is deciding how much to increase it by: we could simply add on the width of the scroll bar, but this isn’t a fixed value under RISC OS because it depends on the toolsprites which are currently in use. We could guess at a number and double it, but that doesn’t feel very satisfactory; a better option would be to leave the width the same as the main window, and adjust it when the windows are opened. As a result, with the ‘furniture’ flag set, we can save the templates and move on to updating the program itself.
+The width of the toolbar work area is currently set to be the same as that of the main window work area, so this will need to be increased to allow the toolbar to extend over the space taken up by the vertical scroll bar. The problem is in deciding how much to increase it by: we could simply add on the width of the scroll bar, but this isn’t a fixed value under RISC OS because it depends on the toolsprites which are currently in use. We could guess at a number and double it, but that doesn’t feel very satisfactory; a better option would be to leave the width the same as the main window, and adjust it when the windows are opened. As a result, with the ‘furniture’ flag set, we can save the templates and move on to updating the program itself.
Note that in both cases we set bit 0 of the address passed in
Note that in both cases we set bit 0 of the address that we pass in
With the returned blocks now being 92 bytes long, instead of the 36 bytes from
With the returned blocks now being 92 bytes long, instead of the 36 bytes from
main% = q%
toolbar% = q% + 100
@@ -103,7 +103,7 @@ toolbar% = q% + 100
The outline of a window is something that we don't often see, since the Wimp usually works in terms of the visible area, but fortunately the
The outline of a window is something that we don't often see, since the Wimp usually works in terms of the visible area; fortunately, the
main% = q%
toolbar% = q% + 100
@@ -127,9 +127,9 @@ toolbar%!16 = main%!16 : REM Visible Area Y1
In practice, this specific instance does not matter too much: we’re still using visible area for aligning the
In practice, it does not matter too much in this specific instance: we’re still using visible area for aligning the
Before we call main%!52 - main%!44
), then add on the width of the main window outline (main_outline%!12 - main_outline%!4
) less the width of its visible area (main%!12 - main%!4)
). This gives us the required horizontal extent.
Before we call main%!52 - main%!44
), then add on the width of the main window outline (main_outline%!12 - main_outline%!4
) less the width of its visible area (main%!12 - main%!4
). This gives us the required horizontal extent.
The final step is to calculate the
At the time, Ovation’s author created this effect using three windows, which are all interleaved carefully. These days, the effect can be achieved more easily using the Nested Wimp, and in previous chapters we have already seen examples from Paint (
As with the full-width toolbar that we created in
As with the full-width toolbar that we created in
With these changes in place, we can now close the templates and move on to updating the program itself. We’ll need to update
With these changes in place, we can now save and close the templates, then move on to updating the program itself. We’ll need to update
PROCtemplate_load("Embedded", b%, buffer_size%, -1)
+PROCtemplate_load("Embedded", b%, buffer_size%, -1)
SYS "Wimp_CreateWindow",,b% TO ToolBoxWindow%
-We can also simplify the Open_Window_Request event handler in PROCpoll again. We will no longer need to make any adjustments to the contents of the toolbox, so we can delete PROCopen_window_request completely and just call Wimp_OpenWindow in the CASE statement once again.
+We can also simplify the Open_Window_Request event handler in PROCpoll again. We will no longer need to make any adjustments to the contents of the toolbox, so we can delete PROCopen_window_request completely and just call Wimp_OpenWindow in the CASE statement once again as seen in .
-CASE reason% OF
+CASE reason% OF
WHEN 2 : SYS "Wimp_OpenWindow",,b%
WHEN 3 : SYS "Wimp_CloseWindow",,b%
WHEN 6 : PROCmouse_click(b%)
@@ -104,33 +104,33 @@ SYS "Wimp_GetWindowInfo",,toolbox% OR %1
-As we currently have nothing to go into the toolbox, the width is largely immaterial and so for now we will set it to 200 OS Units.
+As we currently have nothing to go into the toolbox, the width is largely immaterial and so for now we will set it to 200 OS Units. Later on, when we have some content for the toolbox, we can calculate the width to contain this neatly.
-box_width% = 200
+Horizontally, the toolbox should align with the left-hand edge of the main window’s work area, which we achieve by aligning the X0 extents of the two windows’s visible areas. As the toolbox is a fixed width, its X1 extent is offset from the main window’s X0 extent by that width.
-Horizontally, the toolbox should align with the left-hand edge of the main window’s work area, which we achieve in the usual way. The X0 extent remains relative to the visible area of the main window, but the X1 extent is offset from the main window’s X0 extent by the calculated width.
+box_width% = 200
-toolbox%!4 = main%!4 : REM Visible Area X0
+toolbox%!4 = main%!4 : REM Visible Area X0
toolbox%!12 = main%!4 + box_width% : REM Visible Area X1
-Positioning the toolbox in the vertical dimension, however, is more tricky than anything which we have encountered up to now. As can be seen in , we need to ensure that the top and bottom outlines of the toolbox line up with the top and bottom outlines of the main window’s horizontal scroll bar.
+Positioning the toolbox in the vertical dimension, however, is more tricky than anything which we have encountered up to this point. As can be seen in , we need to ensure that the top and bottom outlines of the toolbox line up with the top and bottom outlines of the main window’s horizontal scroll bar.
-The Y0 coordinate for the toolbox visible area must line up with the Y0 coordinate of the main window’s outline. As we saw in the previous chapter , the outline includes the window border, and so its X0 is one pixel further down the screen than the X0 of the visible area will be.
+The Y0 coordinate for the visible area of the toolbox must line up with the Y0 coordinate of the main window’s outline. As we saw in the previous chapter , the outline includes the window border, and so its X0 is one pixel further down the screen than the X0 of the visible area will be.
-However, unlike last time, we can no longer rely on the Wimp clipping the visible area of the toolbox for us. If we look at the Y1 coordinate of the toolbox visible area, we can see that it must be aligned to the Y0 coordinate of the main window’s visible area. The Y1 is exclusive, while the Y0 is inclusive, so we’re actually aligning the border of the toolbox with the bottom pixel of the main window’s visible area – again, we’re a pixel adrift!
+On this occasion, however, we can no longer rely on the Wimp clipping the visible area of the toolbox for us. If we look at the Y1 coordinate of the toolbox visible area, we can see that it must be aligned to the Y0 coordinate of the main window’s visible area. The Y1 is exclusive, while the Y0 is inclusive, so we’re actually aligning the border of the toolbox with the bottom pixel of the main window’s visible area – again, we’re a pixel adrift!
From this, we can see that the height of the toolbox visible area will be
box_height% = (main%!8 - pixel_height%) - (main_outline%!8 + pixel_height%)
-where pixel_height% is a variable holding the number of OS Units which represent the height of a pixel in the current screen mode. This will vary between modes, but as we saw when we created our simple application , we can read the information in the form of the vertical eigenfactor and then convert that in to OS Units by raising 2 to its power.
+where pixel_height% is a variable holding the number of OS Units which represent the height of a pixel in the current screen mode. This will vary between modes but, as we saw when we created our simple application , we can read the information in the form of the vertical eigenfactor and then convert that in to OS Units by raising 2 to its power.
SYS "OS_ReadModeVariable", -1, 5 TO ,,eigenfactor%
pixel_height% = 2 ^ eigenfactor%
-With the toolbox positioned, the final thing to do before opening it as a child window is to use Wimp_SetExtent to ensure that the extent is sufficient to cover the whole visible area.
+With the toolbox positioned, the final thing to do before opening it as a child window is to use Wimp_SetExtent to ensure that its extent is sufficient to cover the whole visible area.
toolbox%!52 = toolbox%!44 + box_width%
toolbox%!48 = toolbox%!56 - box_height%
@@ -244,7 +244,7 @@ toolbox%!28 = -1
SYS "Wimp_OpenWindow",,toolbox%, &4B534154, !main%, &05550000
ENDPROC
-Running the application will produce a window with a toolbox embedded into the horizontal scroll bar, as seen in .
+Running the application will produce a window with an empty toolbox embedded into the horizontal scroll bar, as seen in .
@@ -257,7 +257,7 @@ ENDPROC
Adding some icons
-A toolbox isn’t much use without some icons in it, so the next thing that we will need to do is add some. Unlike all of our previous panes, however, the critical dimension – the height of the toolbox window, which will determine the size of the icons within it – is dependent on a factor outside of our control. It is defined by the height of the horizontal scroll bar, which in turn will depend on the desktop theme and mode that user has selected.
+A toolbox isn’t much use without some icons in it, so the next thing that we will need to do is to add some. Unlike all of our previous panes, however, the critical dimension – the height of the toolbox window, which will determine the size of the icons within it – is dependent on a factor outside of our control. It is defined by the height of the horizontal scroll bar, which in turn will depend on the desktop theme and mode that user has selected.
As a result, we will need to arrange the icons in the toolbox as we align it to the main window. This isn’t a problem: we’ve already seen how to move icons around using Wimp_ResizeIcon in several of the previous examples – it just adds another step to the process of opening the window.
@@ -265,7 +265,7 @@ ENDPROC
-Given that space is limited, we will lay the toolbox out with the minimum of wasted real estate as shown in : a border of one pixel around the outside of the icons, and one pixel between each icon. Usually icons are placed on a 4 by 4 OS Unit grid to ensure that designs will work in all modes including the old rectangular pixel ones found on early systems (see the Style Guide for details), but we’re reading the mode details when we arrange the toolbox and so only need to match the capability of the current screen mode.
+Given that space is limited, we will lay the toolbox out with the minimum of wasted real estate as shown in : a border of one pixel around the outside of the icons, and one pixel between each icon. Usually icons are placed on a grid of 4 by 4 OS Units to ensure that designs will work in all modes including the old rectangular pixel ones found on early systems (see the Style Guide for details), but since we’re reading the mode details when we arrange the toolbox, it is safe to only worry about matching the capability of the current screen mode.
@@ -354,11 +354,11 @@ FOR icon% = 0 TO toolbox%!88 - 1
NEXT icon%
ENDPROC
-When the code is run, the window should now look something like the one in
When the code is run, the window should now look something like the one in
One of the things that is worth noting here is the very limited – not to mention variable – space available for the icons in the toolbox. Care needs to be taken when designing the contents, to ensure that it can handle different screen modes and sizes of scroll bar whilst remaining clear and intuitive to the user. This is a problem that is getting worse as screen sizes reduce, and it may be that in a modern application, embedded toolboxes are best limited to the kinds of uses seen in Paint (
One of the things that is worth noting here is the very limited – not to mention variable – space available for the icons in the toolbox. Care needs to be taken when designing the contents, to ensure that it can handle different screen modes and sizes of scroll bar whilst remaining clear and intuitive to the user. This is a problem that is getting worse as screen sizes increase, and it may be that in a modern application, embedded toolboxes are best limited to the kinds of uses seen in Paint (
The full application with the code to position the icons can be found in
Fortunately the solution is simple: if a mode change occurs whilst our window is open, we should calculate all of the positioning again and then re-open it. Recalculating the position is fairly straight-forward, as we can re-use the positioning code in
Fortunately the solution is simple: if a mode change occurs whilst our window is open, we should calculate all of the positioning again and then re-open it. Recalculating the position is fairly straight-forward, as we can re-use the positioning code in
We don’t call
In order to be able to call
In order to be sent
In order to be sent
+
q%!0 = &400C1 : REM Message_ModeChange
q%!4 = 0 : REM Message_Quit & End of List
SYS "Wimp_Initialise", 380, &4B534154, TaskName$, q%
-To allow us to handle the new message, we will update the CASE which dispatches our Wimp_Poll events. Instead of simply setting the Quit% variable to TRUE when Message_Quit is received, we will instead call a new procedure called PROCuser_message which can then the different codes which are received.
+To allow us to handle the new message, we will update the CASE which dispatches our Wimp_Poll events as shown in . Instead of simply setting the Quit% variable to TRUE when Message_Quit is received, we will instead call a new procedure called PROCuser_message which can then the different codes which are received.
-CASE reason% OF
+CASE reason% OF
WHEN 2 : SYS "Wimp_OpenWindow",,b%
WHEN 3 : SYS "Wimp_CloseWindow",,b%
WHEN 6 : PROCmouse_click(b%)
@@ -427,9 +427,9 @@ SYS "Wimp_Initialise", 380, &4B534154, TaskName$, q%
WHEN 17, 18 : PROCuser_message(b%)
ENDCASE
-PROCuser_message itself is fairly simple. It contains a CASE structure to test the reason code of the incoming message, and call appropriate code in each case. A Message_Quit still sets the Quit% variable to TRUE , while Message_ModeChange will in turn call the new PROCrecalculate_toolbox procedure.
+PROCuser_message itself is fairly simple, and can be seen in . It contains a CASE structure to test the reason code of the incoming message, and call appropriate code in each case. A Message_Quit still sets the Quit% variable to TRUE , while Message_ModeChange will in turn call the new PROCrecalculate_toolbox procedure.
-DEF PROCuser_message(b%)
+DEF PROCuser_message(b%)
CASE b%!16 OF
WHEN 0 : REM Message_Quit
Quit% = TRUE
@@ -438,7 +438,7 @@ WHEN &400C1 : REM Message_ModeChange
ENDCASE
ENDPROC
-With all of these changes in place, the full application can be found in .
+With all of these changes in place, the full application can be found in . There should no functional differences from the previous version, besides its ability to more gracefully handle mode changes.