gui_containers.rst 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. .. _doc_gui_containers:
  2. Using Containers
  3. ================
  4. :ref:`Anchors <doc_size_and_anchors>` are an efficient way to handle
  5. different aspect ratios for basic multiple resolution handling in GUIs.
  6. For more complex user interfaces, they can become difficult to use.
  7. This is often the case of games, such as RPGs, online chats, tycoons or simulations. Another
  8. common case where more advanced layout features may be required is in-game tools (or simply just tools).
  9. All these situations require a more capable OS-like user interface, with advanced layout and formatting.
  10. For that, :ref:`Containers <class_container>` are more useful.
  11. Container layout
  12. ----------------
  13. Containers provide a huge amount of layout power (as an example, the Godot editor user interface is entirely done using them):
  14. .. image:: img/godot_containers.png
  15. When a :ref:`Container <class_Container>`-derived node is used, all children :ref:`Control <class_Control>` nodes give up their
  16. own positioning ability. This means the *Container* will control their positioning and any attempt to manually alter these
  17. nodes will be either ignored or invalidated the next time their parent is resized.
  18. Likewise, when a *Container* derived node is resized, all its children will be re-positioned according to it,
  19. with a behavior based on the type of container used:
  20. .. image:: img/container_example.gif
  21. Example of *HBoxContainer* resizing children buttons.
  22. The real strength of containers is that they can be nested (as nodes), allowing the creation of very complex layouts that resize effortlessly.
  23. Sizing options
  24. --------------
  25. When adding a node to a container, the way the container treats each child depends mainly on their *container sizing options*. These options
  26. can be found by inspecting the layout of any *Control* that is a child of a *Container*.
  27. .. image:: img/container_sizing_options.webp
  28. Sizing options are independent for vertical and horizontal sizing and not all containers make use of them (but most do):
  29. * **Fill**: Ensures the control *fills* the designated area within the container. No matter if
  30. a control *expands* or not (see below), it will only *fill* the designated area when this is toggled on (it is by default).
  31. * **Expand**: Attempts to use as much space as possible in the parent container (in each axis).
  32. Controls that don't expand will be pushed away by those that do. Between expanding controls, the
  33. amount of space they take from each other is determined by the *Stretch Ratio* (see below).
  34. This option is only available when the parent Container is of the right type, for example the *HBoxContainer* has this option
  35. for horizontal sizing.
  36. * **Shrink Begin** When expanding, try to remain at the left or top of the expanded
  37. area.
  38. * **Shrink Center** When expanding, try to remain at the center of the expanded
  39. area.
  40. * **Shrink End** When expanding, try to remain at the right or bottom of the expanded
  41. area.
  42. * **Stretch Ratio**: The ratio of how much expanded controls take up the available space in relation to each
  43. other. A control with "2", will take up twice as much available space as one with "1".
  44. Experimenting with these flags and different containers is recommended to get a better grasp on how they work.
  45. Container types
  46. ---------------
  47. Godot provides several container types out of the box as they serve different purposes:
  48. Box Containers
  49. ~~~~~~~~~~~~~~
  50. Arranges child controls vertically or horizontally (via :ref:`HBoxContainer <class_HBoxContainer>` and
  51. :ref:`VBoxContainer <class_VBoxContainer>`). In the opposite of the designated direction
  52. (as in, vertical for a horizontal container), it just expands the children.
  53. .. image:: img/containers_box.png
  54. These containers make use of the *Stretch Ratio* property for children with the *Expand* flag set.
  55. Grid Container
  56. ~~~~~~~~~~~~~~
  57. Arranges child controls in a grid layout (via :ref:`GridContainer <class_GridContainer>`, amount
  58. of columns must be specified). Uses both the vertical and horizontal expand flags.
  59. .. image:: img/containers_grid.png
  60. Margin Container
  61. ~~~~~~~~~~~~~~~~
  62. Child controls are expanded towards the bounds of this control (via
  63. :ref:`MarginContainer <class_MarginContainer>`). Padding will be added on the margins
  64. depending on the theme configuration.
  65. .. image:: img/containers_margin.png
  66. Again, keep in mind that the margins are a *Theme* value, so they need to be edited from the
  67. constants overrides section of each control:
  68. .. image:: img/containers_margin_constants.png
  69. Tab Container
  70. ~~~~~~~~~~~~~
  71. Allows you to place several child controls stacked on top of each other (via
  72. :ref:`TabContainer <class_TabContainer>`), with only the *current* one visible.
  73. .. image:: img/containers_tab.png
  74. Changing the *current* one is done via tabs located at the top of the container, via clicking:
  75. .. image:: img/containers_tab_click.gif
  76. The titles are generated from the node names by default (although they can be overridden via *TabContainer* API).
  77. Settings such as tab placement and *StyleBox* can be modified in the *TabContainer* theme overrides.
  78. Split Container
  79. ~~~~~~~~~~~~~~~
  80. Accepts only one or two children controls, then places them side to side with a divisor
  81. (via :ref:`HSplitContainer <class_HSplitContainer>` and :ref:`VSplitContainer <class_VSplitContainer>`).
  82. Respects both horizontal and vertical flags, as well as *Ratio*.
  83. .. image:: img/containers_split.png
  84. The divisor can be dragged around to change the size relation between both children:
  85. .. image:: img/containers_split_drag.gif
  86. PanelContainer
  87. ~~~~~~~~~~~~~~
  88. A container that draws a *StyleBox*, then expands children to cover its whole area
  89. (via :ref:`PanelContainer <class_PanelContainer>`, respecting the *StyleBox* margins).
  90. It respects both the horizontal and vertical sizing options.
  91. .. image:: img/containers_panel.png
  92. This container is useful as a top-level control, or just to add custom backgrounds to sections of a layout.
  93. FoldableContainer
  94. ~~~~~~~~~~~~~~~~~
  95. A container that can be expanded/collapsed
  96. (via :ref:`FoldableContainer <class_FoldableContainer>`).
  97. Child controls are hidden when it is collapsed.
  98. ScrollContainer
  99. ~~~~~~~~~~~~~~~
  100. Accepts a single child node. If the child node is bigger than the container, scrollbars will be added
  101. to allow panning the node around (via :ref:`ScrollContainer <class_ScrollContainer>`). Both
  102. vertical and horizontal size options are respected, and the behavior can be turned on or off
  103. per axis in the properties.
  104. .. image:: img/containers_scroll.png
  105. Mouse wheel and touch drag (when touch is available) are also valid ways to pan the child control around.
  106. .. image:: img/containers_center_pan.gif
  107. As in the example above, one of the most common ways to use this container is together with a *VBoxContainer* as child.
  108. AspectRatioContainer
  109. ~~~~~~~~~~~~~~~~~~~~
  110. A container type that arranges its child controls in a way that preserves their proportions
  111. automatically when the container is resized.
  112. (via :ref:`AspectRatioContainer <class_AspectRatioContainer>`).
  113. It has multiple stretch modes, providing options for adjusting the child controls' sizes concerning the container:
  114. "fill," "width control height," "height control width," and "cover."
  115. .. image:: img/containers_aspectratio.webp
  116. It is useful when you have a container that needs to be dynamic and responsive to different screen sizes,
  117. and you want the child elements to scale proportionally without losing their intended shapes.
  118. .. image:: img/containers_aspectratio_drag.webp
  119. FlowContainer
  120. ~~~~~~~~~~~~~
  121. FlowContainer is a container that arranges its child controls either horizontally or vertically
  122. (via :ref:`HFlowContainer <class_HFlowContainer>` and via :ref:`VFlowContainer <class_VFlowContainer>`).
  123. When the available space runs out, it wraps the children to the next line or column, similar to how text wraps in a book.
  124. .. image:: img/containers_hflow.webp
  125. It is useful for creating flexible layouts where the child controls adjust automatically to the available space without overlapping.
  126. .. image:: img/containers_hflow_drag.webp
  127. CenterContainer
  128. ~~~~~~~~~~~~~~~
  129. CenterContainer is a container that automatically keeps all of its child controls centered within it at their minimum size.
  130. It ensures that the child controls are always aligned to the center, making it easier to create centered layouts without manual positioning
  131. (via :ref:`CenterContainer <class_CenterContainer>`).
  132. .. image:: img/containers_center.webp
  133. .. image:: img/containers_center_drag.webp
  134. SubViewportContainer
  135. ~~~~~~~~~~~~~~~~~~~~
  136. This is a special control that will only accept a single *Viewport* node as child, and it will display
  137. it as if it was an image (via :ref:`SubViewportContainer <class_SubViewportContainer>`).
  138. Creating custom Containers
  139. --------------------------
  140. It is possible to create a custom container using a script.
  141. Here is an example of a container that fits children to its size:
  142. .. tabs::
  143. .. code-tab:: gdscript GDScript
  144. extends Container
  145. func _notification(what):
  146. if what == NOTIFICATION_SORT_CHILDREN:
  147. # Must re-sort the children
  148. for c in get_children():
  149. # Fit to own size
  150. fit_child_in_rect(c, Rect2(Vector2(), size))
  151. func set_some_setting():
  152. # Some setting changed, ask for children re-sort.
  153. queue_sort()
  154. .. code-tab:: csharp
  155. using Godot;
  156. public partial class CustomContainer : Container
  157. {
  158. public override void _Notification(int what)
  159. {
  160. if (what == NotificationSortChildren)
  161. {
  162. // Must re-sort the children
  163. foreach (Control c in GetChildren())
  164. {
  165. // Fit to own size
  166. FitChildInRect(c, new Rect2(new Vector2(), Size));
  167. }
  168. }
  169. }
  170. public void SetSomeSetting()
  171. {
  172. // Some setting changed, ask for children re-sort.
  173. QueueSort();
  174. }
  175. }