HiddenElements - mattbichay/test GitHub Wiki

PageOutline(1-5, Contents)

Table of Contents

Hidden elements

Rocket distinguishes between normal elements that are part of the DOM and visible to all subsystems, and hidden (or non-DOM) elements that (by default) can only be found if explicitly asked for. Hidden elements are typically used by custom elements; for example, the drop-down select element in the Controls plugin creates hidden elements for its arrow button, the value field and the selection box.

Differences in hidden elements

The subsystems of Rocket that ignore hidden elements are:

 * Automatic layout.
 * RML serialisation; ie, GetInnerRML() will not generate RML for hidden elements.

important subsystems that still recognise hidden elements are:

 * Input events.
 * Update and rendering.
 * RCSS properties.

Custom elements that make use of hidden elements can therefore control their size and positioning exactly, while still getting all the flexibility of the RCSS property system. Helper methods are made available for layout.

Adding a hidden element

Hidden elements are created just like other elements, either through the [wiki:documentation/C++Manual/Elements#Dynamicallycreatingelements] or CreateElement() on a [wiki:documentation/C++Manual/Documents#Creatingnewelements].

To parent an element to another as a hidden element, call AppendChild() as normal but set the second parameter to 'false'.

If you parent the element using InsertBefore() instead of AppendChild(), the new element will be hidden if the element it was inserted adjacent to is hidden.

Accessing hidden elements

Elements segregate their children by their hidden status. Visible children are always placed before, and therefore have a lower index, than hidden children. By default, the element's function GetNumChildren() will return the number of visible elements. To find the total number of elements including hidden elements, pass the boolean 'true' into the function.

The following code will iterate over all hidden children of an element:

Formatting hidden elements

Custom elements typically size and position their hidden elements internally when they receive a "resize" event.

Sizing

Hidden elements can be sized by calling the SetBox() function. SetBox() takes a Rocket::Core::Box structure, which contains sizes for a two-dimensional content area and per-edge padding, borders and margin (see the [wiki:documentation/RCSS/BoxModel] for more information on the box model).

You can either construct the box yourself, or use the static BuildBox() function on Rocket::Core::ElementUtilities:

BuildBox() will generate the values of a Rocket::Core::Box from the 'width', 'max-width', 'min-width', and 'height', 'max-height' and 'min-height' properties set on an element. The parameters are:

 * ''box'': The box to be generated.
 * ''containing_block'': The element's containing block. This is typically the size of the content area of the containing element, but does not have to be.
 * ''element'': The element to generate the box for.
 * ''inline_element'': True if the element is inline, false if not. Generally you want to leave this as false.

The following code will generate and set the box on a hidden element from within its parent:

But if you want to force the hidden element to be a certain size, instead you might do:

Positioning

To set the position of a hidden element, use the SetOffset() function. This sets the two-dimensional offset of the element top-left border edge from another element's top-left border edge. Typically, a custom element will position an internal hidden element relative to itself, but this is not required.

However, Rocket::Core::ElementUtilities has a number of functions to aid in positioning a hidden element.

PositionElement() resizes an element (using BuildBox()) and positions it within its parent. As positioning border-corner to border-corner can be quite confusing, this function treats the offset as between the content areas of the elements.

There is also an override for PositionElement() for positioning an element offset from a specific corner or edge of its parent, not just the top-left corner. The third parameter, 'anchor', can be one or more of the PositionAnchor enumeration ORed together:

Invoking the layout engine

Rocket's internal layout engine can be run on a hidden element to format the element's visible descendants. To do so, call the static FormatElement() function on Rocket::Core::ElementUtilities.

Formatting hidden text elements

It possible to append text elements as hidden elements. In this case, you will need to use the Rocket::Core::ElementText API to get the element to generate and position strings of characters.

Generating lines of text

Once a text element has had raw text set on it (through the SetText() function), you can call GenerateString() to generate a character sequence for rendering on a single line. Depending on the length of the raw text and the available width, you may need to call GenerateString() multiple times to generate all the lines required to render the element's content.

The parameters to this function are:

 * ''line'': The string the contents of the generated line will be written to.
 * ''line_length'': An integer to store the number of characters used by the source string to generate this line. Because of whitespace processing, this value may be greater than the length of the generated line.
 * ''line_width'': A floating-point value to store the width of the generated string, in pixels.
 * ''line_begin'': The index of the first character in the source string to begin generating the line from.
 * ''maximum_line_width'': The maximum length (in pixels) the line can be.
 * ''right_spacing_width'': If the generated line is the last line required by the text node, then this space (in pixels) must be available to the right of the line. This is not generally required by custom text layouts.
 * ''trim_whitespace_prefix'': If this is set to true, collapsed whitespace will be trimmed from the front of the line. This is usually set to false for the first line, true for the second and subsequent line.

The function will return true if the generated line is the last line required to render the content of the element, false if further lines are required.

The following code sample will generate all of the lines required for a text node, each line being allowed a maximum width of 200 pixels:

The GenerateString() will format whitespace and endlines as appropriate for the value of the 'white-space' RCSS property on the element. To change how it processes whitespace, change the 'white-space' property.

Just generating lines of text from the element won't position them or get them rendering however.

Rendering text

Text elements store a list of generated lines, each with a two-dimensional offset from the top-left of the text element. To begin positioning lines, call ClearLines() to clear all previously-generated lines.

Then call AddLines() for each generated line.

The following code sample extends the previous sample by placing each line of text as it is generated:

Examples

You can see plenty of examples of using hidden elements in the Controls plugin, particularly in the select form control (ElementFormControlSelect.cpp and WidgetDropDown.cpp), or for text layout, the text area control (ElementFormControlText.cpp and WidgetTextInput.cpp).

⚠️ **GitHub.com Fallback** ⚠️