Okay, I think we’re just about there - see the attached I7 source and compiled Glulx game. In the game you can enter “status n” where n is 1, 2 or 3 (anything else is interpreted as 3) and “toggle” to turn the status line off (if it’s on) or back on (if it’s off). I haven’t tested this with many different interpreters (and embarrassingly it’s shown up some problems in the Windows I7 front-end’s Game tab’s handling of colours) so please check that it works for you.
Right, so what did I change?
The first thing was the order in which windows were being opened. You had the “statusanchor” window as the parent of the status window, but at the same time wanted the statusanchor and status windows to have fixed heights, with the main text window occupying the rest. That’s not going to work, due to how Glk handles window splitting and sizing, which is a rather elegant and powerful system, but not exactly easy to explain. It’s covered in detail in sections 3.1 and 3.2 of Zarf’s Glk specification (see http://www.eblong.com/zarf/glk/glk-spec-074_3.html) and I’ve tried to write a few paragraphs that explains it more simply, but I haven’t succeeded.
Your code started from the main window: it split that to add the statusanchor window above it, and then split the statusanchor window to add the status window above that. The problem with doing it like that is that that first split, adding the statusanchor window, fixes how the space will be shared between the main text window and whatever is above it: the result is that both the statusanchor window and the status window end up having to occupy the 20 pixels specified in the first split which is, in short, not enough. One way to think about it would be to imagine drawing the splits on a blank piece of paper, starting from an empty rectangle: each time we open a new window we’re choosing a window to split, and then drawing a vertical or horizontal split to divide up its space, but we are not stealing space from any other window.
The solution is to change the order of these window splits: split the status window from the main text window, then the statusanchor window from the main text window, and finally the textmap window from the main text window. This does affect opening and closing the status window (which we’ll get to) but does mean that the windows arrange in the desired way. As I say, I wish I could explain why more simply than the Glk specification, but … Anyway, doing that gives us windows that appear in the correct positions and relationships.
The next thing to be looked at is the use of Basic Screen Effects to populate the status line (“Rule for constructing the status line: …”). There’s nothing wrong with using Basic Screen Effects for this, but the important thing to understand is that when this rule calls “fill the status bar with …” it will always reset the status window height to however many rows are in the supplied table. This is why when you used this in your example code, it overwrote any status window height that had been set by a call to VM_StatusLineHeight().
To get round this, I’ve assumed that what you intend to do is to switch between three tables for the status window, each with a different number of rows. My code has a number variable called “status-depth”, and this is used in the status line construction rule to decide which table to use. Since we’re using this to set the status window height, all the junk in the example calling VM_StatusLineHeight() has been deleted.
The final thing was your desire to turn the status window on and off. The only problem here is that my re-ordering of how the windows are created means that the status window cannot be re-opened by splitting from either the statusanchor window or the main text window: instead it must be split from the “pair window” that contains both of those two windows. Again, the reason for this is obvious if you understand section 3 of the Glk specification, and not otherwise. Fortunately we can easily handle this by tweaking Erik’s code from “Glulx Status Window Control”, which in my example is the I6 method InitCustomStatusWindow() and the rule that calls it. This relies on the fact that, due to where we want the status bar to be, it’s always opened or re-opened by splitting the root Glk window, which we get with the Glk call glk_window_get_root().
I think that covers everything. Phew!
It was either that or write a design document for work …
StatusLine.zip (187 KB)