Rename GUI to User Interface (UI)

This commit is contained in:
Nathan Lovato
2020-10-08 17:05:17 -06:00
parent 9a12147a31
commit 1778b89945
65 changed files with 42 additions and 71 deletions

View File

@@ -0,0 +1,353 @@
.. _doc_bbcode_in_richtextlabel:
BBCode in RichTextLabel
=======================
Introduction
------------
Label nodes are great for displaying basic text, but they have limits. If you want
to change the color of the text, or its alignment, that change affects all of the
text in the Label node. You can't have only one part of the text be one color, or
only one part of the text be centered. To get around this limitation you would use
a :ref:`class_RichTextLabel`.
:ref:`class_RichTextLabel` allows the display of complex text markup in a Control.
It has a built-in API for generating the markup, but can also parse a BBCode.
Note that the BBCode tags can also be used, to some extent, in the
:ref:`XML source of the class reference <doc_updating_the_class_reference>`.
Using BBCode
------------
For uniformly formatted text you can write in the "Text" property, but if you want
to use BBCode markup you should use the "Text" property in the "Bb Code" section
instead (``bbcode_text``). Writing to this property will trigger the parsing of your
markup to format the text as requested. Before this happens, you need to toggle the
"Enabled" checkbox in the "Bb Code" section (``bbcode_enabled``).
.. image:: img/bbcodeText.png
For example, ``BBCode [color=blue]blue[/color]`` would render the word "blue" with
a blue color.
.. image:: img/bbcodeDemo.png
You'll notice that after writing in the BBCode "Text" property the regular "Text"
property now has the text without the BBCode. While the text property will be updated
by the BBCode property, you can't edit the text property or you'll lose the BBCode
markup. All changes to the text must be done in the BBCode parameter.
.. note::
For BBCode tags such as ``[b]`` (bold), ``[i]`` (italics) or ``[code]`` to
work, you must set up custom fonts for the RichTextLabel node first.
There are no BBCode tags to control vertical centering of text yet.
Reference
---------
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| Command | Tag | Description |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **bold** | ``[b]{text}[/b]`` | Makes {text} bold. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **italics** | ``[i]{text}[/i]`` | Makes {text} italics. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **underline** | ``[u]{text}[/u]`` | Makes {text} underline. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **strikethrough** | ``[s]{text}[/s]`` | Makes {text} strikethrough. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **code** | ``[code]{text}[/code]`` | Makes {text} use the code font (which is typically monospace). |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **center** | ``[center]{text}[/center]`` | Makes {text} horizontally centered. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **right** | ``[right]{text}[/right]`` | Makes {text} horizontally right-aligned. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **fill** | ``[fill]{text}[/fill]`` | Makes {text} fill the RichTextLabel's width. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **indent** | ``[indent]{text}[/indent]`` | Increase the indentation level of {text}. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **url** | ``[url]{url}[/url]`` | Show {url} as such, underline it and make it clickable. |
| | | **Must be handled with the "meta_clicked" signal to have an effect.** |
| | | See :ref:`doc_bbcode_in_richtextlabel_handling_url_tag_clicks`. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **url (ref)** | ``[url=<url>]{text}[/url]`` | Makes {text} reference <url> (underlined and clickable). |
| | | **Must be handled with the "meta_clicked" signal to have an effect.** |
| | | See :ref:`doc_bbcode_in_richtextlabel_handling_url_tag_clicks`. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **image** | ``[img]{path}[/img]`` | Insert image at resource {path}. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **resized image** | ``[img=<width>]{path}[/img]`` | Insert image at resource {path} using <width> (keeps ratio). |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **resized image** | ``[img=<width>x<height>]{path}[/img]`` | Insert image at resource {path} using <width>×<height>. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **font** | ``[font=<path>]{text}[/font]`` | Use custom font at <path> for {text}. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **color** | ``[color=<code/name>]{text}[/color]`` | Change {text} color; use name or # format, such as ``#ff00ff``. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **table** | ``[table=<number>]{cells}[/table]`` | Creates a table with <number> of columns. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
| **cell** | ``[cell]{text}[/cell]`` | Adds cells with the {text} to the table. |
+-----------------------+-----------------------------------------------------------+--------------------------------------------------------------------------+
Built-in color names
~~~~~~~~~~~~~~~~~~~~
List of valid color names for the [color=<name>] tag:
- aqua
- black
- blue
- fuchsia
- gray
- green
- lime
- maroon
- navy
- purple
- red
- silver
- teal
- white
- yellow
Hexadecimal color codes
~~~~~~~~~~~~~~~~~~~~~~~
For opaque RGB colors, any valid 6-digit hexadecimal code is supported, e.g. ``[color=#ffffff]white[/color]``.
Short RGB color codes such as ``#6f2`` (equivalent to ``#66ff22``) are also supported.
For transparent RGB colors, any 8-digit hexadecimal code can be used, e.g. ``[color=#88ffffff]translucent white[/color]``.
In this case, note that the alpha channel is the **first** component of the color code, not the last one.
Short RGBA color codes such as ``#86f2`` (equivalent to ``#8866ff22``) are also supported.
.. _doc_bbcode_in_richtextlabel_handling_url_tag_clicks:
Handling ``[url]`` tag clicks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
By default, ``[url]`` tags do nothing when clicked. This is to allow flexible use
of ``[url]`` tags rather than limiting them to opening URLs in a web browser.
To handle clicked ``[url]`` tags, connect the RichTextLabel node's
:ref:`meta_clicked <class_RichTextLabel_signal_meta_clicked>` signal to a script function.
For example, the following method can be connected to ``meta_clicked`` to open
clicked URLs using the user's default web browser::
# This assumes RichTextLabel's `meta_clicked` signal was connected to
# the function below using the signal connection dialog.
func _richtextlabel_on_meta_clicked(meta):
# `meta` is not guaranteed to be a String, so convert it to a String
# to avoid script errors at run-time.
OS.shell_open(str(meta))
For more advanced use cases, it's also possible to store JSON in an ``[url]``
tag's option and parse it in the function that handles the ``meta_clicked`` signal.
For example: ``[url={"example": "value"}]JSON[/url]``
Image vertical offset
~~~~~~~~~~~~~~~~~~~~~
You use a custom font for your image in order to align it vertically.
1. Create a ``BitmapFont`` resource
2. Set this bitmap font with a positive value for the ``ascent`` property, that's your height offset
3. Set the BBCode tag this way: ``[font=<font-path>][img]{image-path}[/img][/font]``
Animation effects
-----------------
BBCode can also be used to create different text animation effects. Five customizable
effects are provided out of the box, and you can easily create your own.
Wave
~~~~
.. image:: img/wave.png
Wave makes the text go up and down. Its tag format is ``[wave amp=50 freq=2][/wave]``.
``amp`` controls how high and low the effect goes, and ``freq`` controls how fast the
text goes up and down.
Tornado
~~~~~~~
.. image:: img/tornado.png
Tornao makes the text move around in a circle. Its tag format is
``[tornado radius=5 freq=2][/tornado]``.
``radius`` is the radius of the circle that controls the offset, ``freq`` is how
fast the text moves in a circle.
Shake
~~~~~
.. image:: img/shake.png
Shake makes the text shake. Its tag format is ``[shake rate=5 level=10][/shake]``.
``rate`` controls how fast the text shakes, ``level`` controls how far the text is
offset from the origin.
Fade
~~~~
.. image:: img/fade.png
Fade creates a fade effect over the text that is not animated. Its tag format is
``[fade start=4 length=14][/fade]``.
``start`` controls the starting position of the falloff relative to where the fade
command is inserted, ``length`` controls over how many characters should the fade
out take place.
Rainbow
~~~~~~~
.. image:: img/rainbow.png
Rainbow gives the text a rainbow color that changes over time. Its tag format is
``[rainbow freq=0.2 sat=10 val=20][/rainbow]``.
``freq`` is the number of full rainbow cycles per second, ``sat`` is the saturation
of the rainbow, ``val`` is the value of the rainbow.
Custom BBCode tags and text effects
-----------------------------------
You can extend the :ref:`class_RichTextEffect` resource type to create your own custom
BBCode tags. You begin by extending the :ref:`class_RichTextEffect` resource type. Add
the ``tool`` prefix to your GDScript file if you wish to have these custom effects run
within the editor itself. The RichTextLabel does not need to have a script attached,
nor does it need to be running in ``tool`` mode. The new effect will be activable in
the Inspector through the **Custom Effects** property.
There is only one function that you need to extend: ``_process_custom_fx(char_fx)``.
Optionally, you can also provide a custom BBCode identifier simply by adding a member
name ``bbcode``. The code will check the ``bbcode`` property automatically or will
use the name of the file to determine what the BBCode tag should be.
``_process_custom_fx``
~~~~~~~~~~~~~~~~~~~~~~
This is where the logic of each effect takes place and is called once per character
during the draw phase of text rendering. This passes in a :ref:`class_CharFXTransform`
object, which holds a few variables to control how the associated character is rendered:
- ``identity`` specifies which custom effect is being processed. You should use that for
code flow control.
- ``relative_index`` tells you how far into a given custom effect block you are in as an
index.
- ``absolute_index`` tells you how far into the entire text you are as an index.
- ``elapsed_time`` is the total amount of time the text effect has been running.
- ``visible`` will tell you whether the character is visible or not and will also allow you
to hide a given portion of text.
- ``offset`` is an offset position relative to where the given character should render under
normal circumstances.
- ``color`` is the color of a given character.
- Finally, ``env`` is a :ref:`class_Dictionary` of parameters assigned to a given custom
effect. You can use :ref:`get() <class_Dictionary_method_get>` with an optional default value
to retrieve each parameter, if specified by the user. For example ``[custom_fx spread=0.5
color=#FFFF00]test[/custom_fx]`` would have a float ``spread`` and Color ``color``
parameters in its ` `env`` Dictionary. See below for more usage examples.
The last thing to note about this function is that it is necessary to return a boolean
``true`` value to verify that the effect processed correctly. This way, if there's a problem
with rendering a given character, it will back out of rendering custom effects entirely until
the user fixes whatever error cropped up in their custom effect logic.
Here are some examples of custom effects:
Ghost
~~~~~
::
tool
extends RichTextEffect
class_name RichTextGhost
# Syntax: [ghost freq=5.0 span=10.0][/ghost]
# Define the tag name.
var bbcode = "ghost"
func _process_custom_fx(char_fx):
# Get parameters, or use the provided default value if missing.
var speed = char_fx.env.get("freq", 5.0)
var span = char_fx.env.get("span", 10.0)
var alpha = sin(char_fx.elapsed_time * speed + (char_fx.absolute_index / span)) * 0.5 + 0.5
char_fx.color.a = alpha
return true
Pulse
~~~~~
::
tool
extends RichTextEffect
class_name RichTextPulse
# Syntax: [pulse color=#00FFAA height=0.0 freq=2.0][/pulse]
# Define the tag name.
var bbcode = "pulse"
func _process_custom_fx(char_fx):
# Get parameters, or use the provided default value if missing.
var color = char_fx.env.get("color", char_fx.color)
var height = char_fx.env.get("height", 0.0)
var freq = char_fx.env.get("freq", 2.0)
var sined_time = (sin(char_fx.elapsed_time * freq) + 1.0) / 2.0
var y_off = sined_time * height
color.a = 1.0
char_fx.color = char_fx.color.linear_interpolate(color, sined_time)
char_fx.offset = Vector2(0, -1) * y_off
return true
Matrix
~~~~~~
::
tool
extends RichTextEffect
class_name RichTextMatrix
# Syntax: [matrix clean=2.0 dirty=1.0 span=50][/matrix]
# Define the tag name.
var bbcode = "matrix"
func _process_custom_fx(char_fx):
# Get parameters, or use the provided default value if missing.
var clear_time = char_fx.env.get("clean", 2.0)
var dirty_time = char_fx.env.get("dirty", 1.0)
var text_span = char_fx.env.get("span", 50)
var value = char_fx.character
var matrix_time = fmod(char_fx.elapsed_time + (char_fx.absolute_index / float(text_span)), \
clear_time + dirty_time)
matrix_time = 0.0 if matrix_time < clear_time else \
(matrix_time - clear_time) / dirty_time
if value >= 65 && value < 126 && matrix_time > 0.0:
value -= 65
value = value + int(1 * matrix_time * (126 - 65))
value %= (126 - 65)
value += 65
char_fx.character = value
return true
This will add a few new BBCode commands, which can be used like so:
::
[center][ghost]This is a custom [matrix]effect[/matrix][/ghost] made in
[pulse freq=5.0 height=2.0][pulse color=#00FFAA freq=2.0]GDScript[/pulse][/pulse].[/center]

View File

@@ -0,0 +1,9 @@
Control node gallery
====================
Here is a list of common Control nodes with their name next to them:
.. image:: /img/control_gallery.png
The Control Gallery demo pictured above can be found
`on GitHub <https://github.com/godotengine/godot-demo-projects/tree/master/gui/control_gallery>`__.

View File

@@ -0,0 +1,228 @@
.. _doc_custom_gui_controls:
Custom GUI controls
===================
So many controls...
-------------------
Yet there are never enough. Creating your own custom controls that act
just the way you want them to is an obsession of almost every GUI
programmer. Godot provides plenty of them, but they may not work exactly
the way you want. Before contacting the developers with a pull-request
to support diagonal scrollbars, at least it will be good to know how to
create these controls easily from script.
Drawing
-------
For drawing, it is recommended to check the :ref:`doc_custom_drawing_in_2d` tutorial.
The same applies. Some functions are worth mentioning due to their
usefulness when drawing, so they will be detailed next:
Checking control size
~~~~~~~~~~~~~~~~~~~~~
Unlike 2D nodes, "size" is important with controls, as it helps to
organize them in proper layouts. For this, the
:ref:`Control.rect_size <class_Control_property_rect_size>`
property is provided. Checking it during ``_draw()`` is vital to ensure
everything is kept in-bounds.
Checking focus
~~~~~~~~~~~~~~
Some controls (such as buttons or text editors) might provide input
focus for keyboard or joypad input. Examples of this are entering text
or pressing a button. This is controlled with the
:ref:`Control.focus_mode <class_Control_property_focus_mode>`
property. When drawing, and if the control supports input focus, it is
always desired to show some sort of indicator (highlight, box, etc.) to
indicate that this is the currently focused control. To check for this
status, the :ref:`Control.has_focus() <class_Control_method_has_focus>` method
exists. Example
.. tabs::
.. code-tab:: gdscript GDScript
func _draw():
if has_focus():
draw_selected()
else:
draw_normal()
.. code-tab:: csharp
public override void _Draw()
{
if (HasFocus())
{
DrawSelected()
}
else
{
DrawNormal();
}
}
Sizing
------
As mentioned before, size is important to controls. This allows
them to lay out properly, when set into grids, containers, or anchored.
Controls, most of the time, provide a *minimum size* to help properly
lay them out. For example, if controls are placed vertically on top of
each other using a :ref:`VBoxContainer <class_VBoxContainer>`,
the minimum size will make sure your custom control is not squished by
the other controls in the container.
To provide this callback, just override
:ref:`Control.get_minimum_size() <class_Control_method_get_minimum_size>`,
for example:
.. tabs::
.. code-tab:: gdscript GDScript
func get_minimum_size():
return Vector2(30, 30)
.. code-tab:: csharp
public override Vector2 _GetMinimumSize()
{
return new Vector2(20, 20);
}
Alternatively, set it using a function:
.. tabs::
.. code-tab:: gdscript GDScript
func _ready():
set_custom_minimum_size(Vector2(30, 30))
.. code-tab:: csharp
public override void _Ready()
{
SetCustomMinimumSize(new Vector2(20, 20));
}
Input
-----
Controls provide a few helpers to make managing input events much easier
than regular nodes.
Input events
~~~~~~~~~~~~
There are a few tutorials about input before this one, but it's worth
mentioning that controls have a special input method that only works
when:
- The mouse pointer is over the control.
- The button was pressed over this control (control always
captures input until button is released)
- Control provides keyboard/joypad focus via
:ref:`Control.focus_mode <class_Control_property_focus_mode>`.
This function is
:ref:`Control._gui_input() <class_Control_method__gui_input>`.
Simply override it in your control. No processing needs to be set.
.. tabs::
.. code-tab:: gdscript GDScript
extends Control
func _gui_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
print("Left mouse button was pressed!")
.. code-tab:: csharp
public override void _GuiInput(InputEvent @event)
{
if (@event is InputEventMouseButton mbe && mbe.ButtonIndex == (int)ButtonList.Left && mbe.Pressed)
{
GD.Print("Left mouse button was pressed!");
}
}
For more information about events themselves, check the :ref:`doc_inputevent`
tutorial.
Notifications
~~~~~~~~~~~~~
Controls also have many useful notifications for which no dedicated callback
exists, but which can be checked with the _notification callback:
.. tabs::
.. code-tab:: gdscript GDScript
func _notification(what):
match what:
NOTIFICATION_MOUSE_ENTER:
pass # Mouse entered the area of this control.
NOTIFICATION_MOUSE_EXIT:
pass # Mouse exited the area of this control.
NOTIFICATION_FOCUS_ENTER:
pass # Control gained focus.
NOTIFICATION_FOCUS_EXIT:
pass # Control lost focus.
NOTIFICATION_THEME_CHANGED:
pass # Theme used to draw the control changed;
# update and redraw is recommended if using a theme.
NOTIFICATION_VISIBILITY_CHANGED:
pass # Control became visible/invisible;
# check new status with is_visible().
NOTIFICATION_RESIZED:
pass # Control changed size; check new size
# with get_size().
NOTIFICATION_MODAL_CLOSE:
pass # For modal pop-ups, notification
# that the pop-up was closed.
.. code-tab:: csharp
public override void _Notification(int what)
{
switch (what)
{
case NotificationMouseEnter:
// Mouse entered the area of this control.
break;
case NotificationMouseExit:
// Mouse exited the area of this control.
break;
case NotificationFocusEnter:
// Control gained focus.
break;
case NotificationFocusExit:
// Control lost focus.
break;
case NotificationThemeChanged:
// Theme used to draw the control changed;
// update and redraw is recommended if using a theme.
break;
case NotificationVisibilityChanged:
// Control became visible/invisible;
// check new status with is_visible().
break;
case NotificationResized:
// Control changed size; check new size with get_size().
break;
case NotificationModalClose:
// For modal pop-ups, notification that the pop-up was closed.
break;
}
}

Binary file not shown.

View File

@@ -0,0 +1,181 @@
.. _doc_gui_containers:
Using Containers
================
:ref:`Anchors <doc_size_and_anchors>` are an efficient way to handle
different aspect ratios for basic multiple resolution handling in GUIs,
For more complex user interfaces, they can become difficult to use.
This is often the case of games, such as RPGs, online chats, tycoons or simulations. Another
common case where more advanced layout features may be required is in-game tools (or simply just tools).
All these situations require a more capable OS-like user interface, with advanced layout and formatting.
For that, :ref:`Containers <class_container>` are more useful.
Container layout
----------------
Containers provide a huge amount of layout power (as an example, the Godot editor user interface is entirely done using them):
.. image:: img/godot_containers.png
When a :ref:`Container <class_Container>`-derived node is used, all children :ref:`Control <class_Control>` nodes give up their
own positioning ability. This means the *Container* will control their positioning and any attempt to manually alter these
nodes will be either ignored or invalidated the next time their parent is resized.
Likewise, when a *Container* derived node is resized, all its children will be re-positioned according to it,
with a behavior based on the type of container used:
.. image:: img/container_example.gif
Example of *HBoxContainer* resizing children buttons.
The real strength of containers is that they can be nested (as nodes), allowing the creation of very complex layouts that resize effortlessly.
Size flags
----------
When adding a node to a container, the way the container treats each child depends mainly on their *size flags*. These flags
can be found by inspecting any control that is a child of a *Container*.
.. image:: img/container_size_flags.png
Size flags are independent for vertical and horizontal sizing and not all containers make use of them (but most do):
* **Fill**: Ensures the control *fills* the designated area within the container. No matter if
a control *expands* or not (see below), it will only *fill* the designated area when this is toggled on (it is by default).
* **Expand**: Attempts to use as much space as possible in the parent container (in each axis).
Controls that don't expand will be pushed away by those that do. Between expanding controls, the
amount of space they take from each other is determined by the *Ratio* (see below).
* **Shrink Center** When expanding (and if not filling), try to remain at the center of the expanded
area (by default it remains at the left or top).
* **Ratio** Simple ratio of how much expanded controls take up the available space in relation to each
other. A control with "2", will take up twice as much available space as one with "1".
Experimenting with these flags and different containers is recommended to get a better grasp on how they work.
Container types
---------------
Godot provides several container types out of the box as they serve different purposes:
Box Containers
^^^^^^^^^^^^^^
Arranges child controls vertically or horizontally (via :ref:`HBoxContainer <class_HBoxContainer>` and
:ref:`VBoxContainer <class_VBoxContainer>`). In the opposite of the designated direction
(as in, vertical for an horizontal container), it just expands the children.
.. image:: img/containers_box.png
These containers make use of the *Ratio* property for children with the *Expand* flag set.
Grid Container
^^^^^^^^^^^^^^
Arranges child controls in a grid layout (via :ref:`GridContainer <class_GridContainer>`, amount
of columns must be specified). Uses both the vertical and horizontal expand flags.
.. image:: img/containers_grid.png
Margin Container
^^^^^^^^^^^^^^^^
Child controls are expanded towards the bounds of this control (via
:ref:`MarginContainer <class_MarginContainer>`). Padding will be added on the margins
depending on the theme configuration.
.. image:: img/containers_margin.png
Again, keep in mind that the margins are a *Theme* value, so they need to be edited from the
constants overrides section of each control:
.. image:: img/containers_margin_constants.png
Tab Container
^^^^^^^^^^^^^
Allows you to place several child controls stacked on top of each other (via
:ref:`TabContainer <class_TabContainer>`), with only the *current* one visible.
.. image:: img/containers_tab.png
Changing the *current* one is done via tabs located at the top of the container, via clicking:
.. image:: img/containers_tab_click.gif
The titles are generated from the node names by default (although they can be overridden via *TabContainer* API).
Settings such as tab placement and *StyleBox* can be modified in the *TabContainer* theme overrides.
Split Container
^^^^^^^^^^^^^^^
Accepts only one or two children controls, then places them side to side with a divisor
(via :ref:`HSplitContainer <class_HSplitContainer>` and :ref:`VSplitContainer <class_VSplitContainer>`).
Respects both horizontal and vertical flags, as well as *Ratio*.
.. image:: img/containers_split.png
The divisor can be dragged around to change the size relation between both children:
.. image:: img/containers_split_drag.gif
PanelContainer
^^^^^^^^^^^^^^
Simple container that draws a *StyleBox*, then expands children to cover its whole area
(via :ref:`PanelContainer <class_PanelContainer>`, respecting the *StyleBox* margins).
It respects both the horizontal and vertical size flags.
.. image:: img/containers_panel.png
This container is useful as top-level, or just to add custom backgrounds to sections of a layout.
ScrollContainer
^^^^^^^^^^^^^^^
Accepts a single child node. If this node is bigger than the container, scrollbars will be added
to allow panning the node around (via :ref:`ScrollContainer <class_ScrollContainer>`). Both
vertical and horizontal size flags are respected, and the behavior can be turned on or off
per axis in the properties.
.. image:: img/containers_scroll.png
Mouse wheel and touch drag (when touch is available) are also valid ways to pan the child control around.
.. image:: img/containers_center_pan.gif
As in the example above, one of the most common ways to use this container is together with a *VBoxContainer* as child.
ViewportContainer
^^^^^^^^^^^^^^^^^
This is a special control that will only accept a single *Viewport* node as child, and it will display
it as if it was an image (via :ref:`ViewportContainer <class_ViewportContainer>`).
Creating custom Containers
--------------------------
It is possible to easily create a custom container using script. Here is an example of a simple container that fits children
to its rect size:
.. tabs::
.. code-tab:: gdscript GDScript
extends Container
func _notification(what):
if what == NOTIFICATION_SORT_CHILDREN:
# Must re-sort the children
for c in get_children():
# Fit to own size
fit_child_in_rect( c, Rect2( Vector2(), rect_size ) )
func set_some_setting():
# Some setting changed, ask for children re-sort
queue_sort()

View File

@@ -0,0 +1,79 @@
.. _doc_gui_navigation:
Keyboard/Controller Navigation and Focus
========================================
It is a common requirement for a user interface to have full keyboard
and controller support for navigation and interaction. There are two main
reasons why this is beneficial for projects: improved accessibility (not everyone
can use mouse or touch controls for interactions), and getting your project
ready for :ref:`consoles <doc_consoles>` (or just for people who prefer
to game with a controller on PC).
Navigating between UI elements with keyboard or controller is done by
changing which node is actively selected. This is also called changing UI focus.
Every :ref:`Control <class_Control>` node in Godot is capable of having focus.
By default, some control nodes have the ability to automatically grab focus
reacting to built-in UI actions such as ``ui_up``, ``ui_down``, ``ui_focus_next``, etc.
These actions can be seen in the project settings in the input map and can be modified.
.. warning::
Because these actions are used for focus they should not be used for any
gameplay code.
Node settings
-------------
In addition to the built-in logic, you can define what is known as focus neighbors
for each individual control node. This allows to finely tune the path the UI focus
takes across the user interface of your project. The settings for individual
nodes can be found in the Inspector dock, under the "Focus" category of the
"Control" section.
.. image:: img/focus_settings.png
Neighbor options are used to define nodes for 4-directional navigation, such
as using arrow keys or a D-pad on a controller. For example, the bottom neighbor
will be used when navigating down with the down arrow or by pushing down on
the D-pad. The "Next" and "Previous" options are used with the focus shift button,
such as :kbd:`Tab` on desktop operating systems.
.. note::
A node can lose focus if it becomes hidden.
The mode setting defines how a node can be focused. **All** means a node can
be focused by clicking on it with the mouse, or selecting it with a keyboard
or controller. **Click** means it can only be focused on by clicking on it.
Finally, **None** means it can't be focused at all. Different control nodes have
different default settings for this based on how they are typically used, for
example, :ref:`Label <class_Label>` nodes are set to "None" by default,
while :ref:`buttons <class_Button>` are set to "All".
Make sure to properly configure your scenes for focus and navigation. If a node has
no focus neighbor configured, the engine will try to guess the next control automatically.
This may result in unintended behavior, especially in a complex user interface that doesn't
have well-defined vertical or horizontal navigation flow.
Necessary code
--------------
For keyboard and controller navigation to work correctly, any node must be focused on
using code when the scene starts. Without doing this, pressing buttons or keys won't
do anything. Here is a basic example of setting initial focus with code:
.. tabs::
.. code-tab:: gdscript GDScript
func _ready():
$StartButton.grab_focus()
.. code-tab:: csharp
public override void _Ready()
{
GetNode<Button>("StartButton").GrabFocus();
}
Now when the scene starts the "Start Button" node will be focused, and the keyboard
or a controller can be used to navigate between it and other UI elements.

View File

@@ -0,0 +1,221 @@
.. _doc_gui_skinning:
Introduction to GUI skinning
============================
It is essential for a game to provide clear, informative, and yet visually
pleasing user interface to its players. While :ref:`Control <class_Control>`
nodes come with a decently functional look out of the box, there is always
room for uniqueness and case-specific tuning. For this purpose Godot engine
includes a system for GUI skinning (or theming), which allows you to customize
the look of every control in your user interface, including your custom controls.
Here is an example of this system in action — a game with the GUI that is
radically different from the default UI theme of the engine:
.. figure:: img/tank-kings-by-winterpixel-games.png
:align: center
A "Gear Up!" screen in Tank Kings, courtesy of Winterpixel Games
Beyond achieving a unique look for your game, this system also enables developers
to provide customization options to the end users, including accessibility settings.
UI themes are applied in a cascading manner (i.e. they propagate from parent
controls to their children), which means that font settings or adjustments for
colorblind users can be applied in a single place and affect the entire UI tree.
Of course this system can also be used for gameplay purposes: your hero-based game
can change its style for the selected player character, or you can give different
flavors to the sides in your team-based project.
Basics of themes
----------------
The skinning system is driven by the :ref:`Theme <class_Theme>` resource. Every
Godot project has an inherent default theme that contains the settings used by
the built-in control nodes. This is what gives the controls their distinct look
out of the box. A theme only describes the configuration, however, and it is still
the job of each individual control to use that configuration in the way it requires
to display itself. This is important to remember when implementing
:ref:`your own custom controls <doc_custom_gui_controls>`.
.. note::
Even the Godot editor itself relies on the default theme. But it doesn't look the
same as a Godot project, because it applies its own heavily customized theme on top
of the default one. In principle, this works exactly like it would in your game
as explained :ref:`below <doc_gui_theme_in_project>`.
Theme items
~~~~~~~~~~~
The configuration that is stored in a theme consists of theme items. Each item has
a unique name and must be one of the following data types:
- **Color**
A :ref:`color <class_Color>` value, which is often used for fonts
and backgrounds. Colors can also be used for modulation of controls
and icons.
- **Constant**
An integer value, which can be used either for numeric properties of
controls (such as the item separation in a :ref:`BoxContainer <class_BoxContainer>`),
or for boolean flags (such as the drawing of relationship lines in a :ref:`Tree <class_Tree>`).
- **Font**
A :ref:`font <class_Font>` resource, which is used by controls that
display text. Fonts contain most text rendering settings, except for
its size and color. On top of that, alignment and text direction are
controlled by individual controls.
- **Icon**
A :ref:`texture <class_Texture>` resource, which is normally used
to display an icon (on a :ref:`Button <class_Button>`, for example).
- **StyleBox**
A :ref:`StyleBox <class_StyleBox>` resource, a collection of configuration
options which define the way a UI panel should be displayed. This is
not limited to the :ref:`Panel <class_Panel>` control, as styleboxes
are used by many controls for their backgrounds and overlays.
Theme types
~~~~~~~~~~~
To help with the organization of its items each theme is separated into types,
and each item must belong to a single type. In other words, each theme item
is defined by its name, its data type and its theme type. This combination
must be unique within the theme. For example, there cannot be two color items named
``font_color`` in a type called ``Label``, but there can be another ``font_color``
item in a type ``LineEdit``.
The default Godot theme comes with multiple theme types already defined,
one for every built-in control node that uses UI skinning. The example above
contains actual theme items present in the default theme. You can refer to the
**Theme Properties** section in the class reference for each control to see
which items are available to it and its child classes.
.. note::
Child classes can use theme items defined for their parent class (``Button``
and its derivatives being a good example of that). In fact, every control can
use every theme item of any theme type, if it needs to (but for the clarity and
predictability we try to avoid that in the engine).
It is important to remember that for child classes that process is automated.
Whenever a built-in control requests a theme item from the theme it can omit
the theme type, and its class name will be used instead. On top of that,
the class names of its parent classes will also be used in turn. This allows
changes to the parent class, such as ``Button``, to affect all derived
classes without the need to customize every one of them.
You can also define your own theme types, and additionally customize both built-in
controls and your own controls. Because built-in controls have no knowledge of
your custom theme types, you must utilize scripts to access those items. All control
nodes have several methods that allow to fetch theme items from the theme that
is applied to them. Those methods accept the theme type as one of the arguments.
.. tabs::
.. code-tab:: gdscript
var accent_color = get_color("accent_color", "MyType")
label.add_color_override("font_color", accent_color)
.. code-tab:: csharp
Color accentColor = GetColor("accent_color", "MyType");
label.AddColorOverride("font_color", accentColor);
Customizing a control
---------------------
Each control node can be customized directly without the use of themes. This
is called local overrides. Every theme property from the control's class
reference can be overridden directly on the control itself, using either
the Inspector dock, or scripts. This allows to make granular changes to a
particular part of the UI, while not affecting anything else in the project,
including this control's children.
.. figure:: img/themecheck.png
:align: center
Local overrides are less useful for the visual flair of your user interface,
especially if you aim for consistency. However, for layout nodes these are
essential. Nodes such as :ref:`BoxContainer <class_BoxContainer>` and
:ref:`GridContainer <class_GridContainer>` use theme constants for defining
separation between their children, and :ref:`MarginContainer <class_MarginContainer>`
stores its customizable margins in its theme items.
Whenever a control has a local theme item override, this is the value that
it uses. Values provided by the theme are ignored.
.. _doc_gui_theme_in_project:
Customizing a project
---------------------
Out of the box each project adopts the default project theme provided by Godot. The
default theme itself is constant and cannot be changed, but its items can be overridden
with a custom theme. Custom themes can be applied in two ways: as a project setting,
and as a node property throughout the tree of control nodes.
There are two project settings that can be adjusted to affect your entire project:
:ref:`gui/theme/custom<class_ProjectSettings_property_gui/theme/custom>` allows you to
set a custom project-wide theme, and :ref:`gui/theme/custom_font<class_ProjectSettings_property_gui/theme/custom_font>`
does the same to the default fallback font. When a theme item is requested by a control
node the custom project theme, if present, is checked first. Only if it doesn't have
the item the default theme is checked.
This allows you to configure the default look of every Godot control with a single
theme resource, but you can go more granular than that. Every control node also has
a :ref:`theme <class_Control_property_theme>` property, which allows you to set a
custom theme for the branch of nodes starting with that control. This means that the
control and all of its children, and their children in turn, would first check that
custom theme resource before falling back on the project and the default themes.
.. note::
Instead of changing the project setting you can set the custom theme resource to the
root-most control node of your entire UI branch to almost the same effect. While in the
running project it will behave as expected, individual scenes will still display
using the default theme when previewing or running them directly. To fix that you
can set the same theme resource to the root control of each individual scene.
For example, you can have a certain style for buttons in your project theme, but want
a different look for buttons inside of a popup dialog. You can set a custom theme
resource to the root control of your popup and define a different style for buttons
within that resource. As long as the chain of control nodes between the root of
the popup and the buttons is uninterrupted, those buttons will use the styles defined
in the theme resource that is closest to them. All other controls will still be styled
using the project-wide theme and the default theme styles.
To sum it up, for an arbitrary control its theme item lookup would look something
like this:
#. Check for local overrides of the same data type and name.
#. Using control's class name and parent class names:
a. Check every control starting from itself and see if it has a theme property set;
b. If it does, check that theme for the matching item of the same name, data and theme type;
c. If there is no custom theme or it doesn't have the item, move to the parent control;
d. Repeat steps a-c. until the root of the tree is reached, or a non-control node is reached.
#. Using control's class name check the project-wide theme, if it's present.
#. Using control's class name check the default theme.
Even if the item doesn't exist in any theme, a corresponding default value for that
data type will be returned.
Beyond controls
---------------
Naturally, themes are an ideal type of resource for storing configuration for
something visual. While the support for theming is built into control nodes,
other nodes can use them as well, just like any other resource.
An example of using themes for something beyond controls can be a modulation
of sprites for the same units on different teams in a strategy game. A theme
resource can define a collection of colors, and sprites (with a help from scripts)
can use those colors to draw the texture. The main benefit being that you
could make different themes using the same theme items for red, blue, and
green teams, and swap them with a single resource change.

View File

@@ -0,0 +1,158 @@
.. _doc_gui_using_theme_editor:
Using the theme editor
======================
This articles explains how to create and manage UI themes using the Godot
editor and its theme editor tool. We recommend getting familiar with the
basics behind GUI skinning/theming by reading :ref:`doc_gui_skinning` before starting.
The theme editor is a bottom panel tool that activates automatically, when
a :ref:`Theme <class_Theme>` resource is selected for editing. It contains
the necessary UI for adding, removing, and adjusting theme types and theme
items. It features a preview section for testing your changes live, as well
as a window dialog for doing bulk operations of the theme items.
Creating a theme
----------------
Like any other resources, themes can be created directly in the file system dock
by right-clicking and selecting **New Resource...**, then selecting **Theme**
and clicking **Create**. This is especially useful for creating project-wide
themes.
Themes also can be created from any control node. Select a control node in the scene
hierarchy, then in the inspector go to the ``theme`` property. From there you can
select **New Theme**.
.. figure:: img/new_theme.png
:align: center
This will create an empty theme and open up the theme editor. Keep in mind that
resources created this way are bundled with the scene by default. Use the context
menu to save the new theme to a file instead.
While the theme editor provides the tools to manage theme types and items, themes also
include the default, fallback font that you can edit only using the Inspector dock.
Same applies to the contents of complex resource types, such as :ref:`StyleBoxes <class_StyleBox>`
and icons — they open for editing in the Inspector.
.. figure:: img/default_font.png
:align: center
Theme editor overview
---------------------
.. figure:: img/theme_editor.png
:align: center
The theme editor has two main parts. The main theme editor, located at the bottom of
the Godot editor, aims to provide users with tools to quickly create, edit, and delete
theme items and types. It gives visual tools for picking and changing controls, abstracting
the underlying theme concepts. The **Manage Theme Items** dialog, on the other hand,
tries to address the needs of those who want to change themes manually. It's also
useful for creating a new editor theme.
Theme previews
~~~~~~~~~~~~~~
The left-hand side of the main editor has a set of preview tabs. The **Default Preview**
tab is visible out of the box and contains most of the frequently used controls in various
states. Previews are interactive, so intermediate states (e.g. hover) can be previewed as well.
.. figure:: img/default_preview.png
:align: center
Additional tabs can be created from arbitrary scenes in your project. The scene
must have a control node as its root to function as a preview. To add a new tab
click the **Add Preview** button and select the saved scene from your file system.
.. figure:: img/scene_preview.png
:align: center
If you make changes to the scene, they will not be reflected in the preview
automatically. To update the preview click the reload button on the toolbar.
Previews can also be used to quickly select the theme type to edit. Select the
picker tool from the toolbar and hover over the preview area to highlight control
nodes. Highlighted control nodes display their class name. Clicking on the highlighted
control opens it for editing on the right-hand side.
.. figure:: img/theme_preview_picker.png
:align: center
Theme types and items
~~~~~~~~~~~~~~~~~~~~~
The right-hand side of them theme editor provides a list of theme types available
in the edited theme resource, and the contents of the selected type. The list of
type's items is divided into several tabs, corresponding to each data type available
in the theme (colors, constants, styles, etc.). If the **Show Default** option is
enabled, then for each built-in type its default theme values are displayed, greyed
out. If the option is disabled, only the items available in the edited theme itself
are displayed.
.. figure:: img/theme_type_editor.png
:align: center
Individual items from the default theme can be added to the current theme by
clicking on the **Override** button next to the item. You can also override all
the default items of the selected theme type by clicking on the **Override All**
button. Overridden properties can then be removed with the **Remove Item** button.
Properties can also be renamed using the **Rename Item** button, and completely
custom properties can be added to the list using the text field below it.
Overridden theme items can be edited directly in the right-hand panel, unless they
are resources. Resources have rudimentary controls available for them, but must be
edited in the Inspector dock instead.
.. figure:: img/theme_item_inspector.png
:align: center
Styleboxes have an unique feature available, where you can pin an individual
stylebox from the list. Pinned stylebox acts like the leader of the pack, and
all styleboxes of the same type are updated alongside it when you change its
properties. This allows you to edit properties of several styleboxes at the
same time.
.. figure:: img/theme_pin_the_stylebox.png
:align: center
While theme types can be picked from a preview, they can also be added manually.
Clicking the plus button next to the type list opens the **Add item Type** menu.
In that menu you can either select a type from the list, or you can enter an
arbitrary name to create a custom type. Text field also filters the list of control
nodes.
.. figure:: img/add_item_type.png
:align: center
Manage and import items
-----------------------
Clicking the **Manage Items** button brings up the **Manage Theme Items** dialog. In
the **Edit Items** tab you can view and add theme types, as well as view and edit
the theme items of the selected type.
.. figure:: img/manage_items.png
:align: center
You can create, rename and remove individual theme items here by clicking the
corresponding **Add X Item** and specifying their name. You can also mass delete
theme items either by their data type (using the brush icon in the list) or by
their quality. **Remove Class Items** will remove all built-in theme items you
have customized for a control node type. **Remove Custom Items** will remove all
the custom theme items for the selected type. Finally, **Remove All Items** will
remove everything from the type.
From the **Import Items** tab you can import theme items from other themes. You can
import items from the default Godot theme, the Godot editor theme, or another custom
theme. You can import individual or multiple items, and you can decide whether to
copy or omit their data as well. There are several way you can select and deselect the
items, including by hand, by hierarchy, by data type, and everything. Opting to
include the data will copy all theme items as they are to your theme. Omitting the data
will create the items of the corresponding data type and name, but will leave them empty,
creating a template of a theme in a way.
.. figure:: img/import_items.png
:align: center

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
tutorials/ui/img/fade.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
tutorials/ui/img/margin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
tutorials/ui/img/sb1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
tutorials/ui/img/sb2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
tutorials/ui/img/shake.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
tutorials/ui/img/wave.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

36
tutorials/ui/index.rst Normal file
View File

@@ -0,0 +1,36 @@
User Interface (UI)
===================
.. toctree::
:maxdepth: 1
:name: toc-gui-basics
size_and_anchors
gui_containers
custom_gui_controls
gui_navigation
control_node_gallery
GUI skinning and themes
-----------------------
Godot features an in-depth skinning/theming system for control nodes. The pages in this section
explain the benefits of that system and how to set it up in your projects.
.. toctree::
:maxdepth: 1
:name: toc-gui-skinning
gui_skinning
gui_using_theme_editor
Control node tutorials
----------------------
The following articles cover specific details of using particular control nodes.
.. toctree::
:maxdepth: 1
:name: toc-control-nodes-tutorials
bbcode_in_richtextlabel

View File

@@ -0,0 +1,74 @@
.. _doc_size_and_anchors:
Size and anchors
================
If a game was always going to be run on the same device and at the same
resolution, positioning controls would be a simple matter of setting the
position and size of each one of them. Unfortunately, that is rarely the
case.
Only TVs nowadays have a standard resolution and aspect ratio.
Everything else, from computer monitors to tablets, portable consoles
and mobile phones have different resolutions and aspect ratios.
There are several ways to handle this, but for now, let's just imagine
that the screen resolution has changed and the controls need to be
re-positioned. Some will need to follow the bottom of the screen, others
the top of the screen, or maybe the right or left margins.
.. image:: img/anchors.png
This is done by editing the *margin* properties of controls. Each
control has four margins: left, right, bottom and top. By default, all of
them represent a distance in pixels relative to the top-left corner of
the parent control or (in case there is no parent control) the viewport.
.. image:: img/margin.png
When horizontal (left, right) and/or vertical (top, bottom) anchors are
changed to 1, the margin values become relative to the bottom-right
corner of the parent control or viewport.
.. image:: img/marginend.png
Here, the control is set to expand its bottom-right corner with that of
the parent, so when re-sizing the parent, the control will always cover
it, leaving a 20 pixel margin:
.. image:: img/marginaround.png
Centering a control
-------------------
To center a control in its parent, set its anchors to 0.5 and each margin
to half of its relevant dimension. For example, the code below shows how
a TextureRect can be centered in its parent:
::
var rect = TextureRect.new()
rect.texture = load("res://icon.png")
rect.anchor_left = 0.5
rect.anchor_right = 0.5
rect.anchor_top = 0.5
rect.anchor_bottom = 0.5
var texture_size = rect.texture.get_size()
rect.margin_left = -texture_size.x / 2
rect.margin_right = -texture_size.x / 2
rect.margin_top = -texture_size.y / 2
rect.margin_bottom = -texture_size.y / 2
add_child(rect)
Setting each anchor to 0.5 moves the reference point for the margins to
the center of its parent. From there, we set negative margins so that
the control gets its natural size.
Layout Presets
--------------
Instead of manually adjusting the margin and anchor values, you can use the
toolbar's Layout menu, above the viewport. Besides centering, it gives you many
options to align and resize control nodes.
.. image:: img/layout_dropdown_menu.png