### Banner Windows

The “tadsio” function set provides a group of functions that allow the program to perform sophisticated manipulation of the display layout. This group of functions, called the Banner Window API, lets the program divide the screen into separate “window” areas that can show independent information.

The banner window API provides much of the same functionality that was available in TADS 2’s full HTML interpreters using the <BANNER> tag. However, the banner window API goes beyond the <BANNER> tag from TADS 2 in several important ways:

- The <BANNER> tag in TADS 2 was available only in full HTML interpreters. The TADS 3 banner window API works on many different interpreters, including text-only interpreters. (It isn’t guaranteed to work on all interpreters, but the range of compatible interpreters is greatly expanded compared with the HTML-only <BANNER> tag.)
- The <BANNER> tag was sent to the main output stream, so updating a banner had the side effect of updating the main output window; this made it impossible to update a banner window without canceling command-line editing in progress, such as during a real-time event. The banner window API makes each window’s output stream truly independent, so banners can be freely updated during timed events without interfering with operations in progress in other windows, including input editing in the main window.
- The <BANNER> tag was tied to the hierarchical structure of HTML, which meant that the entire contents of a banner had to be enclosed within the <BANNER>…</BANNER> sequence; this made it impossible to add new text to a banner later, after the </BANNER> close tag, and in particular made it impossible to add to a banner in response to a new command. The banner window API treats each window’s output stream as independent, so the program is free to add to an existing banner at any time.
- The banner window API adds several new features to banners that were not present in the <BANNER> tag, including optional scrollbars, and optional automatic scrolling into view as new text is added.
- Banner windows can be split from the main text window, as the <BANNER> tag did in TADS 2, but they can also be split from other banner windows. This provides much more powerful layout capabilities.
- The banner window API introduces the new “text grid” window type, which simulates a character-mode terminal window and thus gives the program character-by-character control over text positioning. Text grid windows allow the program to write text at any position within the window, and to overwrite text previously displayed.

Note that the banner API replaces the <BANNER> tag. The <BANNER> tag is not supported in TADS 3; interpreters will ignore it.

### Screen Layout Overview

Banners work by splitting one window into two. In other words, we take an existing window and draw an imaginary line either across the width of the window, or down the height of the window; the existing window keeps the space on one side of the line, and the new banner window gets the space on the other side of the line. The existing window shrinks in the process, since some of its space is taken over for the new banner window.

The original window that we split in two is called the “parent” window. The parent can be the main game window (the original window that the interpreter automatically creates at start-up, and which contains the main input/output transcript of the game), or it can be another banner window. We sometimes refer to the new banner window as a “child” of the parent window.

When the program creates a banner window, it specifies an “alignment” and a size for the new window. The alignment determines how we draw the line that splits the parent window, and which side of the line contains the banner window and which contains the shrunken parent window. There are four types of alignment: Top, Bottom, Left, and Right. For Top and Bottom alignment, we split the window with a line across the width of the window; for Top alignment, the new banner window gets the space above the line, and the for Bottom alignment, the new banner takes the space below the line. Left and Right alignment split the window with a vertical line; a Left banner takes the portion to the left of the line, and a Right banner takes the portion to the right of the line. The size determines where the dividing line goes: the dividing line is placed such that the banner’s height (for a Top or Bottom banner) or width (for a Left or Right banner) matches the size parameter.

To determine where each banner goes, the interpreter does the following. We start with the main window, giving it the entire available space (this might be the entire screen on a character-mode terminal, or the entire application window on a graphical system). We then visit each child of the main window. For each child, we look at the child’s alignment and size to determine where to draw the imaginary dividing line; then we give the banner window the appropriate portion, and shrink the main game window to take its portion of the space. Then, we visit all of the child’s children, and do the same thing, dividing and shrinking the child. We repeat the process on the child’s children’s children, and so on until we run out of descendants.

Let’s look at an example. Initially, we start out with just the main game window, which takes the entire available space:

Main

Now, let’s add a banner. Text games traditionally display a status line at the top of the screen, with one or two lines of text; so, let’s create a banner for the status line. For now, we’ll make it one “text unit” high, which is roughly a line of text. So, we’re creating a banner whose parent is the main window, with Top alignment and a size of 1.

Status
Main

Now let’s suppose that we want to add a more complex display, with an area below the status line that displays a picture of the current location. We want another top-aligned child of the main window, because we want it to run the width of the main window and be above the main window. We’ll make its size about ten lines for now.

Status
Picture
Main

This raises a question: why is the Picture window below the Status window? And what if we actually wanted it above the Status window? The answer is in the ordering of the windows: the Status window comes first in the main window’s child list, so it gets split off first, which means it gets the top of the entire display area. The Picture window is split off second, which means that it has to take what’s left of the main window after the Status window has already been carved out. If we wanted the Picture window to be above the Status window, we’d simply have to specify that it comes first. Note that this doesn’t mean we have to create it first; when we create a new banner, we can specify where the new banner goes among the other children of its parent, so if we had wanted the Picture window to be on top, we could simply have specified that it goes first in the main window’s child list.

Now we want to add another window: we want to add a window alongside the picture window, showing a compass graphic in the new window. We don’t want to create another “band” across the entire width of the main window; rather, we want to share some of the space the Picture window already has. To do this, we can create a child of the Picture window, and align it to the right.

Status
Picture | C
Main

The Compass (“C”) window splits the area that the Picture window had, taking the right portion because it’s a right-aligned banner.

### Borders

A banner can optionally display a “border” to separate it from its parent. The border essentially makes the imaginary dividing line between the banner and its parent visible on the screen. Borders are controlled via the “style” flag when creating a banner.

A banner’s border is always exactly one line: it’s always the dividing line between the banner and its parent. In the example above with the Picture and Status banners, if the Picture banner had a border, it would appear between the Picture and Main windows, because the Picture window was split from the Main window. To draw a line between the Status and Picture windows, you would have to give the Status banner a border.

A banner’s children have no effect on the banner’s border. If a banner is drawn with a border, the border will appear exactly the same way whether the banner has children or not; so, to figure out where a border would be drawn, consider what the window would look like without any children of its own. In the example above with the Picture and Compass windows, if the Picture window had a border, this border would be drawn across the full width of the window, under both the Picture and Compass (“C”) windows. So, there would be a border between the Compass window and the Main window whether or not the Compass window itself had a border. (Furthermore, if the Compass window did have a border, it would be drawn as a vertical line between the Compass and Picture windows, because the Picture window is the Compass window’s parent.)

Some systems do not support borders at all; in fact, most character-mode platforms do not, because there’s usually no good way to draw lines in character mode, and even if there were, it would take up too much space. You can tell whether or not the current system supports border drawing by checking the style flag returned from bannerGetInfo(); on systems that don’t support borders, you might want to use some other means to visually separate a banner from its parent, such as using different background (“screen”) colors in each window.

### More Details on Layout

TADS interpreters display everything on what we call the “screen,” by which we mean the physical display area devoted to the interpreter. The screen isn’t necessarily the same as the physical display device (the user’s monitor, or the terminal, for example), although on some systems it is. The most typical examples are:

- For a character-mode terminal, or an operating system (such as MS-DOS) that uses a simple character-mode display, the screen usually is the entire physical display device.
- For a character-mode process running in a graphical environment, such as an “xterm” session running under the X window system on Unix, the “screen” is the terminal window.
- On a graphical operating system where the TADS interpreter runs as a native GUI program (for example, WinTADS or HTML TADS on Windows, or MacTADS or HyperTADS on Macintosh), the “screen” is actually the interpreter application’s main window. Note that in these cases, when we talk about “banner windows,” we’re talking about subdividing the area of that main application window, not about opening new native windows.

When a TADS interpreter first loads a new game program, it devotes the entire “screen” to one window, which we call the “main game window.” This main window acts a lot like a banner window, but it has some differences, so we use the special designation “main game window” to refer to this window.

At any time while the game program is running, it can create new “banner windows.” A banner window is a rectangular area of the screen that can be separately controlled: each banner has its own contents, background color, text color, and so on.

All of the banner windows that are shown at any given time share space on the screen with one another and with the main game window. Two windows can never overlap, and all of the windows taken together must fill the entire screen; in other words, the windows act as non-overlapping “tiles” that completely fill the available screen space. These are important constraints that determine precisely how the screen looks with a given arrangement of windows, and make it relatively simple to specify the screen layout; the disadvantage of these constraints is that they don’t allow the game program to create any arbitrary display, but the compensating advantage is that the constraints are simple to apply across a wide range of platforms, so the program can count on consistent results without having to include special-case code for different machines and display types.

Each banner window has three main parameters that control its layout on the screen. First, each banner has a “parent”: this is either the main game window or another banner window, and provides the base area from which the new banner’s area is taken. Second, each banner has an alignment type, which can be Top, Bottom, Left, or Right. The alignment specifies which portion of the parent window’s space is taken for the banner. A top-aligned banner takes the top portion of the parent’s space, and runs the full width of the parent window; a bottom-aligned banner also runs the entire width of the parent, but takes the bottom portion of its space. Left and right banners run the entire height of the parent window, and take the left and right side, respectively, of the parent’s space. Third, each banner has a size, which gives the size of the “free” dimension, as determined by the alignment: a top or bottom banner’s size specifies its height, and the left or right banner’s size specifies its width.

Each parent window can have one or more children. When a window has more than one child, the children are arranged into an ordered list: one banner is the first child, another is the second, and so on. The order is important because each child is carved out of its parent’s remaining space; we start with the first child, taking its space away from the parent’s space, then move to the second child, taking its space away from what remains of the parent’s space, and so on. When the game program creates a banner, it can specify the position of the new banner among the parent’s children.

The screen layout is dynamic: each time a new banner window is created, or a banner window is removed, or a banner is resized, or the screen size changes (which can happen, for example, when the user resizes the “xterm” window displaying the interpreter), TADS must recalculate the screen layout. Every time any of these events occurs, TADS completely recalculates the screen layout; this means that the layout is always predictable, because it’s always calculated the same way, regardless of what caused a change.

To calculate the screen layout, the interpreter first gives the main game window the entire screen area. The interpreter then visits each child of the main game window, in the order that the program specified when creating the child windows. For each child window, we do the following:

1. We look at the current child window’s alignment and size settings, and figure out where to draw the imaginary line dividing the parent window. If the child’s size setting is greater than the available space in the parent window, we limit the child’s size to that of the parent window; in other words, the child gets all of the parent’s space (but no more), and the parent will get nothing.
2. We assign the space on one side of the dividing line (according to the alignment) to the current child.
3. We assign the space on the other side of the line to the parent, shrinking the parent to its new size.
4. For each child of the current child window, we recursively apply this same procedure to subdivide the current child’s space among its own children.

There are a couple of interesting features of this layout algorithm worth pointing out.

First, when a banner is deleted, all of its children become immediately invisible. This is because a banner gets its space exclusively from its parent; once a banner is deleted, its children no longer have any way to obtain any space on the display. It won’t even help to resize the children: without a parent, a child simply has no way to obtain any display space. The children of a deleted banner remain valid as abstract objects, so you can still call banner API functions that reference their banner handles, but they can never again have a display presence.

Second, a banner’s final size is not necessarily the same as its size parameter setting. Suppose we have a top-aligned banner (call it “A”), a child of the main game window with a size of 50%. Suppose also that this window has a child of its own (call this “B”): a bottom-aligned banner which also has a size of 50%. The layout algorithm will start by giving banner A the top half of the entire screen; but when we lay out its child B, we take away half of that height to give to B. In the end, A only gets 25% of the entire screen. (This probably won’t come up a lot in practice, since it would be unusual to create a child with the same orientation as its parent.)

Third, a child window can never cause its parent to expand. If a child’s size is greater than the available space in its parent, the child simply gets the entire available space in the parent – but no more – and the parent is shrunken down to zero size.

Fourth, although a child causes its parent to shrink as the child carves out space from the parent, this effect never flows “up the tree”: a child can never affect its grandparent or any siblings of its parent. This is an important but subtle point, because it makes the layout rules simple and predictable; there is no “negotiation” for space, and no possibility of irresolvable conflicts, as can sometimes occur with constraint-based layout systems.

### Banner Types

When the game creates a banner window, it can specify the type of window to use. The following types are defined:

- Text. This is an ordinary window that behaves much as the main game window: it has stream-oriented output, so each bit of text written to the window is displayed at the end of any existing text in the window. Text windows support HTML markups, to the same extent the main game window does. On full HTML interpreters, text windows can display graphics, typefaces, text sizes, and so on – everything that the main game window can display.
- Text Grid. This window emulates a character-mode terminal. This type of window displays only text, and uses a single fixed-width font (determined by the operating system, or, on some systems, chosen by the user through preferences mechanism). HTML is not interpreted in these windows; it is not possible to display graphics in a text grid, even on a full HTML interpreter on a GUI system, and these windows can’t even display different typefaces or text sizes; the one available effect is that the text and background colors can be controlled, on interpreters (and display devices) that support text colors. In exchange for sacrificing all of the HTML formatting controls, text grid windows allow you to control the exact positioning of text within the window: you can set the output position to anywhere within the window for each bit of text you display in the window, and you can even overwrite text previously displayed with new text. Text grids can thus be used for text animation and special text formatting effects.

Note that text grids are mostly provided for character-mode platforms, but they’re also supported on the full HTML interpreters for compatibility. In most cases, the kinds of effects for which text grids are most useful can be presented more elegantly on the full HTML interpreters by other means; for example, a “menu” window that uses cursor positioning to move around a selection pointer in response to keyboard inputs can often be better presented in HTML interpreters using a list of hyperlinks. Whenever you're about to use a text grid, you should at least consider whether there might be another alternative that’s a better fit for GUI platforms.

### Sizing Banners

The banner API provides three different ways of setting the size of a banner. Which sizing method is best for a particular banner depends on how the banner is used.

Note that when we talk about the “size” of a banner, we’re talking about the free dimension of the banner, because the other dimension is always bound by the layout rules and thus can’t be controlled independently. For a top-aligned or bottom-aligned banner, the size is the height; for a left- or right-aligned banner, the size is the width.

Percentage sizing: The first method is to size a banner in proportion to the available parent area, by specifying the size as a percentage when creating the banner (with bannerCreate()) or changing its size (with bannerSetSize()). The size of the banner will always be the given percentage of the available parent space; see the Screen Layout Overview for details of how this is determined. When you set a percentage size, the banner specifically remembers the percentage value, not the pixel size that the percentage translates into at any given time; whenever the layout changes (because the user resizes the application window, for example, or because another banner is created), the banner automatically adjusts to the new layout using the same percentage.

Absolute sizing: The second method of sizing a banner is to state the size in terms of the “natural units” of the banner window. The natural units depend on the type of banner:

- For a text window, the natural size is character cells. Because a text window can use a proportionally-spaced font, where characters are of differing sizes, and can even display multiple fonts at once, the unit size here is necessarily arbitrary, so this is defined as the size of a “0” character in the default font of the window. The default font is the initial font for a newly created text window; note that this might differ from the original initial font of an existing text window, because the user could have changed the default font in the preference settings after the window was created.
- For a text grid window, the natural size is character cells. A text grid always uses a single, fixed-pitch font, so this is simply the size of a character in the window’s current font.

Contents-based sizing: The third method is to size the banner so that its current contents exactly fit. In many cases, it’s desirable for a banner to be exactly big enough to show some specific contents; this is the case when a banner is used to display something like a status line or an interactive menu. Even absolute sizing is inherently imprecise for regular text windows, because the natural sizing units are character cells that might not represent the actual mix of characters and fonts displayed. To accommodate the need for exact content-based sizing, the banner API provides a function, bannerSizeToContents(), that sets the size of a banner window so that the actual current contents exactly fit.

Unfortunately, contents-based sizing is not available on all platforms, because some platforms are not capable of supporting it. It is always safe to call bannerSizeToContents(), but on platforms where contents-based sizing isn’t supported, the function will simply do nothing. Because of this, programs must use the following procedure when contents-based sizing is desired:

1. Calculate an estimate of the required size, in the window’s natural units. For text windows, this is usually just a matter of determining how many lines of text will be displayed; it’s not possible to take into account any line wrapping that might occur, so if line wrapping is probable, it might be desirable to pad the estimate accordingly.
2. Call bannerSetSize() to set the banner size to the estimated size. Pass true for the isAdvisory flag, to indicate that an exact contents-based size will be set later. Platforms that support contents-based sizing will ignore this call entirely, because of the isAdvisory flag, so there will be no unnecessary redrawing from an extra resize.
3. Display the contents.
4. Call bannerSizeToContents() to set the exact contents-based size, if possible. For platforms where this is not implemented, it will have no effect, so the estimated size will remain in effect; where contents-based sizing is available, the estimated size will be discarded and the exact size set instead.

By using this procedure, a program can ensure that it will look reasonably good on all platforms, and that it will look exactly as desired on those platforms that do support size-to-contents (as most platforms do).

### Banner Functions

The banner API is part of the “tads-io” function set, which provides programmatic control over the TADS user interface. The banner functions all have names of the form bannerXxx.

bannerClear(handle) – clears the banner’s display. Removes all text from the banner, and moves the output position back to the upper left corner of the banner’s window.

bannerCreate(parent, where, other, windowType, align, size, sizeUnits, style) – creates a new banner window with the given parameters.

parent is the handle of an existing banner that is to serve as the parent of the new banner, or nil if the new banner is to be a child of the main game window. The new banner’s space is obtained by splitting the parent window.

where and other together indicate where the banner goes in the parent’s list of children, which determines how the new banner is laid out relative to the other children of the same parent (see “Screen Layout Overview”). where can be one of the following values:

- BannerFirst – indicates that the new banner is the first child of parent. The other parameter is not used in this case.
- BannerLast – indicates that the new banner is the last child of parent.
- BannerBefore – indicates that the new banner should be inserted into the child list immediately before other, which must be the handle of an existing child of the given parent.
- BannerAfter – indicates that the new banner should be inserted into the child list immediately after other, which must be the handle of an existing child of the given parent.

Note that the child list order specified via where and other is not permanent; it merely determines where the new banner goes in the current child list of the given parent. For example, specifying BannerFirst does not mean that the banner will remain the first child forever; it merely puts it at the start of the current list. If banner A is created with BannerFirst specified, and later banner B is created with BannerFirst, banner A will become the second child after B.

If BannerBefore or BannerAfter is specified, and other is not a valid banner handle or is not a child of the given parent, then the system ignores where and other and inserts the banner as the last child of the parent, as though BannerLast had been specified.

The windowType parameter indicates the type of banner to create; this is one of the following (see “Banner Types” for more information):

- BannerTypeText – an ordinary text window. This type of window behaves essentially the same way as the main game window; in particular, it interprets HTML to the same extent that the main game window does.
- BannerTypeTextGrid – a “text grid” window, which simulates a character-mode terminal window by displaying a rectangular array of characters.

The align setting indicates how the banner’s space is carved out of its parent’s space. This can have one of the following values:

- BannerAlignTop – the banner goes at the top of the parent’s space
- BannerAlignBottom – the banner goes at the bottom of the parent’s space
- BannerAlignLeft – the banner goes at the left of the parent’s space
- BannerAlignRight – the banner goes at the right of the parent’s space

The size parameter gives the initial size of the banner, the meaning of which depends on sizeUnits:

- BannerSizePercent – the size is a percentage of the parent’s space as it is just before carving out this banner. The size is given as a value from 0 to 100. The banner will remember that its size is a percentage; whenever the overall display area size changes (for example, whenever the user resizes the main application window for the interpreter), the size of the banner on-screen will be refigured as the same percentage of the new available space.
- BannerSizeAbsolute – the size is given in the “natural units” of the banner, which depend upon the window type:

- For a text window (BannerTypeText), the size is given in character rows or columns. The size of each character can vary if the window uses a proportional font or can display multiple fonts, so for consistency we define this unit as the size of a “0” character in the window’s default (initial) font. To compute the actual pixel size of the window, the system will take into account space needed for interior margins and borders; this ensures that the window will be large enough to show the requested number of rows or columns of text. (Note, however, that a banner of size 0 will not add any internal space, since a zero-sized banner has no screen presence at all.)
- For a text grid window (BannerTypeTextGrid), the size is given in rows or columns in the grid’s fixed-pitch font. As with a text window, the space needed for margins and borders will be added to the requested row/column size.

style is a combination of flag values specifying the desired behavior for the banner. Some of the style flags directly indicate particular aspects of the on-screen appearance of the banner; other styles are advisory, giving the interpreter some hints about how you’re planning to use the banner, so that the interpreter can select appearance or behavior variations that are appropriate to the current platform. Not all interpreters support all styles, so you have to think of the style flags as hints to the interpreter about the desired appearance, rather than a specification of the actual appearance. After you create the banner, you can use bannerGetInfo() to retrieve the actual style flags, which will give you some indication of how the interpreter treated your request.

The style flags are:

- BannerStyleBorder – show the banner with a border, which is to say a line on the banner’s inner edge (the edge nearest the main text window: for a BannerAlignTop banner, this will be the banner’s bottom edge). Most character-mode interpreters do not support this style, because drawing a border would consume an entire character row or column and would thus take up too much space visually.
- BannerStyleVScroll – show the banner with a vertical scrollbar, if the system has scrollbars. Character-mode platforms will usually ignore this flag.
- BannerStyleHScroll – show the banner with a horizontal scrollbar, if possible.
- BannerStyleAutoVScroll – whenever new text is displayed in the banner, and the new text would appear outside of the on-screen boundaries of the banner, scroll the banner’s contents vertically to bring the latest text into view. If this style isn’t set, the banner won’t automatically scroll vertically (if it has a vertical scrollbar, though, the user will be able to scroll it manually).
- BannerStyleAutoHScroll – when new text is displayed in the banner, scroll the banner’s contents horizontally if necessary to bring the new text into view.
- BannerStyleTabAlign – the <TAB> tag is needed for text alignment purposes in the new window. This flag won’t change the appearance of the banner in a full HTML interpreter or in most character-mode interpreters, but for text-only interpreters running on GUI systems where proportional fonts are available, this might force the interpreter to use a fixed-pitch font for the banner so that it can use spaces to implement the tab alignment.
- BannerStyleMoreMode – use "more" mode in the banner. This implies BannerStyleAutoVScroll. In "more" mode, the interpreter pauses whenever new text written to the banner is about to force older text to scroll out of view, to ensure that the user has had a chance to read all of the text before it scrolls away. The exact user interface varies by platform; on most systems, the interpreter displays a prompt message, such as "[More]", in the window that's about to overflow, then waits for the user to press a key. This style allows a banner window to be used to display long passages without worrying about whether or not the text will fit in the user's available display area.

This function returns a handle to the new banner, or nil if an error occurs creating the banner. The banner handle can be used to operate on the banner in other bannerXxx() functions.

bannerDelete(handle) – delete the given banner. This removes the banner from the display, and recalculates the layout for all of the other banners remaining on the screen. After this function is called, the banner handle becomes invalid and must not be used for anything else.

Note that any children of the banner being deleted will immediately become invisible. They will remain valid, so you can continue to pass their handles to banner functions, but they will not have any display presence. A banner always obtains its display space by splitting its parent, so once the parent is gone, a child has no way of obtaining any screen space of its own and thus becomes invisible.

bannerFlush(handle) – flushes the text output buffer for the given banner, immediately updating the display with any pending text.

bannerGetInfo(banner) – retrieves information on the banner. This function returns a list of values, as follows:

- [1] – the window’s alignment type (a BannerAlignXxx value)
- [2] – the window’s actual style (a bit-wise combination of BannerStyleXxx flags). This can be used to determine how the styles originally requested were interpreted by the local platform. In some cases, it might be desirable to take some special action if a given style flag wasn’t honored; for example, if a border was requested but the actual style flags indicate that no border is displayed, the program might want to use a different background color in the banner to make the banner’s screen area stand out from the adjacent window’s.
- [3] – the height of the banner’s screen area, in text rows. For GUI platforms, this is an estimate only, since the size of text can vary on these platforms; the estimate will give the number of lines of text in the window’s default font that will fit in the window’s height, which might be considerably different than the number of lines actually displayed.
- [4] – the width of the banner’s screen area, in text columns. As with the height, this is only an estimate on GUI platforms, since the banner might use proportionally-spaced characters and might use several different fonts; the estimate gives the number of digit 0’s, in the window’s default font, that will fit in the window’s width.
- [5] – the pixel height of the banner. This is meaningful only on GUI platforms; on character-mode platforms, this will always be zero.
- [6] – the pixel width of the banner. This is used on GUI platforms only; on character-mode platforms, this will always be zero.

bannerGoTo(handle, row, col) – move the output position in the given text grid banner to the given row and column. Rows and columns are numbered from 1 at the upper left corner. This function can be used only in text grid windows; in other types of windows, it has no effect.

bannerSay(handle, …) – writes one or more text items to the banner. This function treats the parameters following handle the same way that tadsSay() does.

bannerSetScreenColor(handle, color) – set the background color in the banner. This immediately changes the entire window’s background to the given color (in other words, this doesn’t merely affect subsequent text, but also affects everything already displayed in the banner). The color values are the same as for bannerSetTextColor(), except that ColorTransparent is not meaningful here. This function can't be used in ordinary text windows (BannerTypeText); use the HTML <BODY BGCOLOR> tag instead.

bannerSetSize(handle, size, sizeUnits, isAdvisory) – set the size of the banner. The size and sizeUnits parameters have the same meanings they do in bannerCreate(). If isAdvisory is true, it indicates that the size setting is only an estimate, and that a call to bannerSizeToContents() will be made later; in this case, the interpreter might simply ignore this estimated size setting entirely, to avoid unnecessary redrawing. Platforms that do not support contents-based sizing will always set the estimated size, even when isAdvisory is true. If isAdvisory is nil, the platform will set the banner size as requested; set isAdvisory to nil when you will not follow up with a call to bannerSizeToContents().

bannerSetTextColor(handle, fg, bg) – set the text color in the given banner to the given foreground and background colors. The new color settings are used for text subsequently displayed; any text already displayed is not affected. This can't be used in ordinary text windows (BannerTypeText); use the HTML <FONT COLOR> tag instead.

The foreground and background colors can have the following values:

- ColorText – the default text foreground color (usually a user preference setting)
- ColorTextBg – the default text background color
- ColorStatusText – the default “status line” text color
- ColorStatusBg – the default status line background color
- ColorInput – the default input text color
- ColorRGB(r, g, b) – the specific color given as with red, green, and blue component values; each component can vary from 0 to 255. ColorRGB(0,0,0) is black, and ColorRGB(255,255,255) is white.
- ColorBlack, ColorWhite, ColorRed, ColorBlue, ColorGreen, ColorYellow, ColorCyan, ColorAqua, ColorMagenta, ColorSilver, ColorGray, ColorMaroon, ColorPurple, ColorFuchsia, ColorLime, ColorOlive, ColorNavy, and ColorTeal provide the standard set of HTML-defined colors. These are all convenience macros that simply use ColorRGB() with the corresponding HTML RGB values.

In addition, the special value ColorTransparent can be used for the background color. This indicates that the text should be drawn with a transparent background, and thus should simply be drawn against the banner’s current background color.

bannerSizeToContents(handle) – resizes the given banner based on the current contents of the banner. For a top-aligned or bottom-aligned banner, this sets the banner’s height so that the banner is just tall enough to show all of the contents as currently laid out. For a left-aligned or right-aligned banner, this sets the banner’s width so that the banner is just wide enough to hold the banner’s single widest indivisible element (such as a single word or a picture). This routine can be used to set the banner’s size based on the actual size of the contents; it’s impossible to know the exact size of a banner’s contents until you actually display the contents, because the sizes of fonts and other display elements vary from one machine to another, and can even change on the same machine in response to user preference settings and other factors.

Note that this routine might not be implemented on all platforms; on platforms where it’s not implemented, this routine will simply do nothing at all. Importantly, it’s legal to call the routine on all platforms (there will be no error or other adverse effect where the routine isn’t implemented), but programs cannot rely on this routine being available. To ensure a reasonable size is always set regardless of platform, callers should always use bannerSetSize() to set an approximate size, assign true for the isAdvisory flag, and then also call bannerSizeToContents() to set the exact content-based size, if appropriate.