Top |
The Types of WindowsThe Types of Windows — Blank, pair, text grid, text buffer, and graphics windows |
#define | wintype_Blank |
#define | wintype_Pair |
#define | wintype_TextBuffer |
#define | wintype_TextGrid |
#define | wintype_Graphics |
#define | wintype_AllTypes |
void glk_window_move_cursor (winid_t win
,glui32 xpos
,glui32 ypos
);
Sets the cursor position. If you move the cursor right past the end of a line, it wraps; the next character which is printed will appear at the beginning of the next line.
If you move the cursor below the last line, or when the cursor reaches the
end of the last line, it goes “off the screen” and further output has no
effect.
You must call glk_window_move_cursor()
or glk_window_clear()
to move the
cursor back into the visible region.
Note that the arguments of glk_window_move_cursor()
are unsigned
ints. This is okay, since there are no negative positions. If you try
to pass a negative value, Glk will interpret it as a huge positive value,
and it will wrap or go off the last line.
Also note that the output cursor is not necessarily visible. In particular, when you are requesting line or character input in a grid window, you cannot rely on the cursor position to prompt the player where input is indicated. You should print some character prompt at that spot — a “>” character, for example.
#define wintype_Blank (2)
A blank window is always blank. It supports no input and no output. (You
can call glk_window_get_stream()
on it, as you can with any window, but
printing to the resulting stream has no effect.) A blank window has no
size; glk_window_get_size()
will return (0,0), and it is illegal to set a
window split with a fixed size in the measurement system of a blank window.
A blank window is not the same as there being no windows. When Glk starts up, there are no windows at all, not even a window of the blank type.
#define wintype_Pair (1)
A pair window is completely filled by the two windows it contains. It supports no input and no output, and it has no size.
You cannot directly create a pair window; one is automatically created
every time you split a window with glk_window_open()
. Pair windows are
always created with a rock value of 0.
You can close a pair window with glk_window_close()
; this also closes every
window contained within the pair window.
It is legal to split a pair window when you call glk_window_open()
.
#define wintype_TextBuffer (3)
A text buffer window contains a linear stream of text. It supports output; when you print to it, the new text is added to the end. There is no way for you to affect text which has already been printed. There are no guarantees about how much text the window keeps; old text may be stored forever, so that the user can scroll back to it, or it may be thrown away as soon as it scrolls out of the window.
Therefore, there may or may not be a player-controllable scroll bar or other scrolling widget.
The display of the text in a text buffer is up to the library. Lines will probably not be broken in the middles of words — but if they are, the library is not doing anything illegal, only ugly. Text selection and copying to a clipboard, if available, are handled however is best on the player's machine. Paragraphs (as defined by newline characters in the output) may be indented.
You should not, in general, fake this by printing spaces before each paragraph of prose text. Let the library and player preferences handle that. Special cases (like indented lists) are of course up to you.
When a text buffer is cleared (with glk_window_clear()
), the library will do
something appropriate; the details may vary. It may clear the window, with
later text appearing at the top — or the bottom. It may simply print
enough blank lines to scroll the current text out of the window. It may
display a distinctive page-break symbol or divider.
The size of a text buffer window is necessarily imprecise. Calling
glk_window_get_size()
will return the number of rows and columns that would
be available if the window was filled with
“0” (zero) characters in the “normal” font.
However, the window may use a non-fixed-width font, so that number of
characters in a line could vary. The window might even support
variable-height text (say, if the player is using large text for emphasis);
that would make the number of lines in the window vary as well.
Similarly, when you set a fixed-size split in the measurement system of a text buffer, you are setting a window which can handle a fixed number of rows (or columns) of “0” characters. The number of rows (or characters) that will actually be displayed depends on font variances.
A text buffer window supports both character and line input, but not mouse input.
In character input, there will be some visible signal that the window is waiting for a keystroke. (Typically, a cursor at the end of the text.) When the player hits a key in that window, an event is generated, but the key is not printed in the window.
In line input, again, there will be some visible signal. It is most common for the player to compose input in the window itself, at the end of the text. (This is how IF story input usually looks.) But it's not strictly required. An alternative approach is the way MUD clients usually work: there is a dedicated one-line input window, outside of Glk's window space, and the user composes input there.
If this approach is used, there will still be some way to handle input from two windows at once. It is the library's responsibility to make this available to the player. You only need request line input and wait for the result.
By default, when the player finishes his line of input, the library will display the input text at the end of the buffer text (if it wasn't there already.) It will be followed by a newline, so that the next text you print will start a new line (paragraph) after the input.
If you call glk_cancel_line_event()
, the same thing happens; whatever text
the user was composing is visible at the end of the buffer text, followed by
a newline.
However, this default behavior can be changed with the
glk_set_echo_line_event()
call. If the default echoing is disabled, the
library will not display the input text (plus newline)
after input is either completed or cancelled. The buffer will end with
whatever prompt you displayed before requesting input. If you want the
traditional input behavior, it is then your responsibility to print the text,
using the Input text style, followed by a newline (in the original style).
#define wintype_TextGrid (4)
A text grid contains a rectangular array of characters, in a fixed-width font. Its size is the number of columns and rows of the array.
A text grid window supports output. It maintains knowledge of an output
cursor position. When the window is opened, it is filled with blanks (space
characters), and the output cursor starts in the top left corner —
character (0,0). If the window is cleared with glk_window_clear()
, the window
is filled with blanks again, and the cursor returns to the top left corner.
When you print, the characters of the output are laid into the array in order, left to right and top to bottom. When the cursor reaches the end of a line, or if a newline (0x0A) is printed, the cursor goes to the beginning of the next line. The library makes no attempt to wrap lines at word breaks. If the cursor reaches the end of the last line, further printing has no effect on the window until the cursor is moved.
Note that printing fancy characters may cause the cursor to advance more than one position per character. (For example, the “æ” ligature may print as two characters.) See Output, for how to test this situation.
You can set the cursor position with glk_window_move_cursor()
.
When a text grid window is resized smaller, the bottom or right area is thrown away, but the remaining area stays unchanged. When it is resized larger, the new bottom or right area is filled with blanks.
You may wish to watch for evtype_Arrange
events, and clear-and-redraw your
text grid windows when you see them change size.
Text grid window support character and line input, as well as mouse input (if a mouse is available.)
Mouse input returns the position of the character that was touched, from (0,0) to (width - 1, height - 1).
Character input is as described in the previous section.
Line input is slightly different; it is guaranteed to take place in the
window, at the output cursor position. The player can compose input only to
the right edge of the window; therefore, the maximum input length
is (windowwidth - 1 -
cursorposition).
If the maxlen argument of glk_request_line_event()
is smaller than this, the
library will not allow the input cursor to go more than maxlen characters
past its start point.
This allows you to enter text in a fixed-width field, without the player being able to overwrite other parts of the window.
When the player finishes his line of input, it will remain visible in the
window, and the output cursor will be positioned at the beginning of the
next row. Again, if you glk_cancel_line_event()
, the
same thing happens. The glk_set_echo_line_event()
call has no effect in grid
windows.
#define wintype_Graphics (5)
A graphics window contains a rectangular array of pixels. Its size is the number of columns and rows of the array.
Each graphics window has a background color, which is initially white. You can change this; see Graphics in Graphics Windows.
When a graphics window is resized smaller, the bottom or right area is thrown away, but the remaining area stays unchanged. When it is resized larger, the new bottom or right area is filled with the background color.
You may wish to watch for evtype_Arrange
events, and clear-and-redraw your
graphics windows when you see them change size.
In some libraries, you can receive a graphics-redraw event (evtype_Redraw
)
at any time. This signifies that the window in question has been cleared to
its background color, and must be redrawn. If you create any graphics
windows, you must handle these events.
Redraw events can be triggered when a Glk window is uncovered or made visible by the platform's window manager. On the other hand, some Glk libraries handle these problem automatically — for example, with a backing store — and do not send you redraw events. On the third hand, the backing store may be discarded if memory is low, or for other reasons — perhaps the screen's color depth has changed. So redraw events are always a possibility, even in clever libraries. This is why you must be prepared to handle them. However, you will not receive a redraw event when you create a graphics window. It is assumed that you will do the initial drawing of your own accord. You also do not get redraw events when a graphics window is enlarged. If you ordered the enlargement, you already know about it; if the player is responsible, you receive a window-arrangement event, which covers the situation.
For a description of the drawing functions that apply to graphics windows, see Graphics in Graphics Windows.
Graphics windows support no text input or output.
Not all libraries support graphics windows. You can test whether Glk graphics are available using the gestalt system. In a C program, you can also test whether the graphics functions are defined at compile-time. See Testing for Graphics Capabilities.
As with all windows, you should also test for NULL
when you create a
graphics window.
#define wintype_AllTypes (0)
A constant representing all window types, which may be used as the wintype
argument in glk_stylehint_set()
.