OpenTTD Source 20241224-master-gf74b0cf984
Hierarchical widgets

Hierarchical widgets, also known as nested widgets, are widgets stored in a tree. More...

Data Structures

class  NWidgetBase
 Baseclass for nested widgets. More...
 
class  NWidgetResizeBase
 Base class for a resizable nested widget. More...
 
class  NWidgetCore
 Base class for a 'real' widget. More...
 
class  NWidgetContainer
 Baseclass for container widgets. More...
 
class  NWidgetHorizontal
 Horizontal container. More...
 
class  NWidgetHorizontalLTR
 Horizontal container that doesn't change the direction of the widgets for RTL languages. More...
 
class  NWidgetVertical
 Vertical container. More...
 
class  NWidgetMatrix
 Matrix container with implicitly equal sized (virtual) sub-widgets. More...
 
class  NWidgetSpacer
 Spacer widget. More...
 
class  NWidgetBackground
 Nested widget with a child. More...
 
class  NWidgetViewport
 Nested widget to display a viewport in a window. More...
 
class  NWidgetScrollbar
 Nested widget to display and control a scrollbar in a window. More...
 
class  NWidgetLeaf
 Leaf widget. More...
 

Detailed Description

Hierarchical widgets, also known as nested widgets, are widgets stored in a tree.

At the leafs of the tree are (mostly) the 'real' widgets visible to the user. At higher levels, widgets get organized in container widgets, until all widgets of the window are merged.

Hierarchical widget kinds

A leaf widget is one of

The purpose of a leaf widget is to provide interaction with the user by displaying settings, and/or allowing changing the settings.

A container widget is one of

The purpose of a container widget is to structure its leafs and sub-containers to allow proper resizing.

Hierarchical widget computations

The first 'computation' is the creation of the nested widgets tree by calling the constructors of the widgets listed above and calling Add() for every child, or by means of specifying the tree as a collection of nested widgets parts and instantiating the tree from the array.

After the creation step,

Computations in the nested widgets take place as follows:

  1. A bottom-up sweep by recursively calling NWidgetBase::SetupSmallestSize() to initialize the smallest size (smallest_x, smallest_y) and to propagate filling and resize steps upwards to the root of the tree.
  2. A top-down sweep by recursively calling NWidgetBase::AssignSizePosition() with ST_SMALLEST to make the smallest sizes consistent over the entire tree, and to assign the top-left (pos_x, pos_y) position of each widget in the tree. This step uses fill_x and fill_y at each node in the tree to decide how to fill each widget towards consistent sizes. Also the current size (current_x and current_y) is set.
  3. After initializing the smallest size in the widget tree with ST_SMALLEST, the tree can be resized (the current size modified) by calling NWidgetBase::AssignSizePosition() at the root with ST_RESIZE and the new size of the window. For proper functioning, the new size should be the smallest size + a whole number of resize steps in both directions (ie you can only resize in steps of length resize_{x,y} from smallest_{x,y}).

After the second step, the current size of the widgets are set to the smallest size.

To resize, perform the last step with the new window size. This can be done as often as desired. When the smallest size of at least one widget changes, the whole procedure has to be redone from the start.

See also
Hierarchical widget parts