Skip to content

windows

Jan Boon edited this page Jul 21, 2026 · 3 revisions

title: Windows and Containers description: Container windows, modals, menus, tabs, trees, lists, scroll text and rollouts published: true editor: markdown

Groups structure the interface; a handful of group widgets provide the actual windowing. Everything here accepts the common element and group attributes; group-level extras worth knowing are escapable (+on_escape), on_enter (Enter validation), on_active/on_deactive, group_onclick_l/group_onclick_r (clicks nothing else handled), win_priority (stacking band, 0–7), and use_cursor.

container — the standard window

The showcase launcher: a plain fixed-size container window with title bar and close button

container is the window widget: title bar, close/help buttons, dragging, resizing, collapsing, docking, per-window alpha. A minimal working one is shown in Your first window; the full attribute surface:

Title and headertitle (title_opened/title_closed for state-specific text; translated when it starts with ui), title_class (text, formated, text_id — the last binds the title to a database string), header_active, header_color (a database path, not a literal color), content_y_offset.

User abilitiesmovable, openable (collapsible; opened for the initial state), lockable/locked, resizer (border resizers on free windows; pop_min_w/pop_max_w/pop_min_h/pop_max_h clamp the range), right_button (the multi-purpose corner button: close on free windows, pop-out/pop-in on docked ones), help_button + help_page, savable/active_savable (persist geometry/state), modal (window grabs input while active), modal_parent.

Eventson_open, on_close, on_close_button, on_deactive_check (can veto closing), on_move, on_begin_move, on_resize, on_alpha_settings_changed, each with _params.

Skinoptions="layerN" names the layer options block supplying every frame/header texture. When omitted, the block is chosen by nesting depth (layer0 for free windows, deeper for docked children).

Anatomy: the three special children

A container looks up three child groups by id and warns if content is placed elsewhere:

<group type="container" id="win" ...>
	<group id="header_closed" ...>  <!-- widgets on the title bar while collapsed -->
	<group id="header_opened" ...>  <!-- widgets on the title bar while expanded -->
	<group id="content" ...>        <!-- the window body -->
</group>

Everything else — title views, the collapse arrow, buttons, resizers, the docked-children list and its scrollbar — is auto-created by the widget from its skin options.

Rollouts: popin containers

The contacts window: a rollout list where every row is a docked child container One branch open and one closed; a closed child is just its title bar Three nesting levels open: each depth pulls the next layer skin

Containers dock inside other containers to form rollout lists (the classic contacts window). The docking is declared by nested <tree> nodes at the interface root — not by nesting the <group> elements:

<tree node="rollout">
	<node node="roll_friends">
		<node node="fr_kaetemi" />
		...
	</node>
</tree>
  • A docked child ("popin") renders inside the parent's child list; its width follows the parent; depth picks the layer1/layer2/... skin automatically.
  • A closed child container is just its title bar — put the row's icons in header_closed and you have a list entry; openable="true" children expand in place.
  • popable children can be popped out into free windows via the corner button and popped back in; movable_in_parent_list allows drag-reordering.
  • When the open child list outgrows pop_max_h, the parent gains a scrollbar riding the open rail.

The open-state frame geometry (m_open rail, el/em/er_open ending strip) and the frame_covers_open_list layer option that selects between the original open-frame layout and the shipped skins' full-frame stretch are described in Skinning.

modal

A modal dialog over the interface A second modal pushed on top via push_modal

modal is a frame group that grabs the interface while shown. Modals start inactive and are spawned by action handlers, not by activating them directly: enter_modal (replace current modal), push_modal (stack), leave_modal (pop) — client-convention handlers, params="group=ui:sample:my_modal". Modals are auto-registered as windows; no <tree> entry.

attribute default meaning
mouse_pos true spawn at the mouse (x/y become deltas); set false for centered dialogs with explicit posref
exit_click_out true click outside closes; onclick_out/onpostclick_out handlers fire around it
exit_click_l / exit_click_r / exit_click_b false any left/right click exits
exit_key_pushed false any key exits
force_inside_screen false clamp onto the canvas
category tag for close-by-category
options w_modal skin frame options block (the shipped data names it skin_modal)

Note that only the top modal of a stack is displayed; leave_modal reveals the one beneath.

menu

The sample menu opened from a button, with a nested submenu expanded The same menu opened as a context menu at the cursor via active_menu

menu is a modal specialization; define it once, open it from anywhere — a button's menu_l/menu_r attribute, or the active_menu handler (params_r="menu=ui:sample:sample_menu") for right-click context menus at the pointer.

Menu-level attributes: color, color_over, color_grayed (+ matching shadow_color_*), highlight_over (selection bar), space (line gap), fontsize, shadow, case_mode (default UPPER — menus shout unless told otherwise), max_visible_line (scroll cap), extends (clone another menu's lines).

Items are <action> children; a nested <action> is a submenu, and <separator/> draws a divider:

<group type="menu" id="sample_menu" ...>
	<action id="one" name="First entry" handler="set" params="..." />
	<separator/>
	<action id="chk" name="Checkable" checkable="true" checked="true" handler="..." />
	<action id="gray" name="Grayed entry" grayed="true" />
	<action id="sub" name="Submenu">
		<action id="sub_a" name="Nested A" handler="..." />
		<action id="sub_b" name="Nested B" handler="..." />
	</action>
</group>

Item attributes: name (translated when ui*), handler/params, cond (expression re-checked to gray the line), checkable/checked (checkbox skin comes from the menu_checkbox options block), grayed, selectable, per-item max_visible_line for its submenu, and usergroup_l/usergroup_r (template groups instantiated beside the line). There is no icon attribute; use a usergroup.

tab groups

The tabs window on its first tab Switched to the second tab: tab_button rows are radio buttons driving content groups

A tab group plus tab_button children named by convention tab0, tab1, …; each button's group= names the content group it reveals (looked up through the tab group's ancestors). The first tab selects itself at setup; onchange fires on switches. Tab buttons are text buttons riding the radio-button machinery, so per-state colors and textures come from the style (w_tab_* in the legacy skin).

tree — hierarchical lists

The list and tree window with all branches open The same tree with the Forest branch folded

group_tree displays a fold-arrow hierarchy (not to be confused with the window-registration <tree> element):

<group type="tree" id="t" col_over="255 255 255 60" col_select="255 255 255 100" fontsize="12">
	<node id="atys" name="Atys" opened="true" show="true">
		<node id="forest" name="Forest" opened="true" show="true" handler="set" params="..." />
		...
	</node>
</group>

Tree attributes: fontsize, col_over/col_over_back/col_select, fold-arrow textures (arbo_open_first, arbo_close_just_one, arbo_son_without_son — the first one's bitmap size sets the cell metrics), navigate_one_branch (auto-close siblings), select_ancestor_on_close. Node attributes: name, opened, show (hidden nodes promote their children), handler/params (+ handler_right), cond, bitmap (icon), per-node fontsize/y_decal/color. Nodes are also buildable from Lua at runtime.

list and scroll_text

list stacks dynamically added children (chat lines, log entries): addelt growth direction (T/B/L/R), align, space (pixel gap), maxelements (oldest dropped beyond it, default 1024), plus an inline text template (fontsize/color/shadow attributes on the list) for addTextChild calls from code or Lua.

A scroll_text group in the editors window: a text list with its scrollbar, wheel-scrollable

scroll_text is the standard composite — a list plus scrollbar, and the base of the HTML group:

<group type="scroll_text" id="st" w="352" h="120" ...>
	<group id="text_list" type="list" posref="TL TL" x="4" y="-4" space="2" maxelements="2000" ... />
	<ctrl type="scroll" id="scroll_bar" posref="TR TR" ...
	      tx_bottomleft="w_scroll_l0_b.tga" tx_middle="w_scroll_l0_m.tga" tx_topright="w_scroll_l0_t.tga" />
</group>

The children must be named text_list and scroll_bar (optional repeat-buttons button_add/button_sub scroll by lines). Mouse-wheel scrolling comes built in.

frame and header

frame draws a 3×3 border skin around its children (display, color, options naming the 9 textures; defaults to the modal skin) — the undecorated panel primitive, rarely needed once containers exist. header/header_entry build resizable column headers over list columns (wmin, resizer_size, target syncing a column group's width); they exist in the library but are essentially exercised only by the client's list windows.

Clone this wiki locally