Использование контейнеров

Якоря — эффективный способ обработки различных соотношений сторон для базовой поддержки нескольких разрешений в графических интерфейсах.

Для более сложных интерфейсов этот подход может оказаться неудобным.

В играх такое часто бывает: например, в RPG, онлайн-чатах, стратегиях или симуляторах. Ещё один пример, где нужны продвинутые средства компоновки — игровые инструменты (или просто инструменты).

Во всех этих случаях нужен более функциональный интерфейс — похожий на ОС, с продвинутой компоновкой и форматированием. В таких случаях лучше подходят контейнеры.

Компоновка контейнеров

Контейнеры предоставляют мощные возможности компоновки (например, интерфейс редактора Godot полностью построен на них):

../../_images/godot_containers.png

Когда используется узел, производный от Контейнера, все дочерние узлы Control теряют возможность самостоятельного позиционирования. Это означает, что Контейнер будет управлять их расположением, а любые попытки ручного изменения этих узлов либо игнорируются, либо сбрасываются при следующем изменении размера родителя.

Аналогично, когда размер производного узла Container изменяется, все его дочерние элементы будут перемещены в соответствии с ним, причем поведение будет зависеть от типа используемого контейнера:

../../_images/container_example.gif

Пример изменения размера дочерних кнопок HBoxContainer.

Настоящее преимущество контейнеров заключается в том, что их можно вкладывать друг в друга (как узлы), что позволяет создавать очень сложные макеты, размер которых можно легко изменить.

Варианты размеров

При добавлении узла в контейнер, то, как контейнер обрабатывает каждый дочерний элемент, в основном зависит от параметров размера контейнера. Эти параметры можно найти, изучив структуру любого Control, являющегося дочерним элементом Container.

../../_images/container_sizing_options.webp

Параметры размеров независимы для вертикального и горизонтального размера, и не все контейнеры их используют (но большинство):

  • Fill: обеспечивает заполнение элементом управления указанной области внутри контейнера. Независимо от того, расширяется элемент управления или нет (см. ниже), он будет заполнять указанную область только при включенном параметре (по умолчанию).

  • Expand: пытается использовать как можно больше пространства в родительском контейнере (по каждой оси). Элементы управления, которые не расширяются, будут оттеснены теми, которые расширяются. Расстояние между расширяющимися элементами управления определяется Stretch Ratio (Коэффициентом растяжения) (см. ниже). Этот параметр доступен только для родительского контейнера соответствующего типа, например, HBoxContainer имеет этот параметр для изменения размера по горизонтали.

  • Shrink Begin При расширении старайтесь оставаться слева или сверху расширенной области.

  • Shrink Center При расширении старайтесь оставаться в центре расширенной области.

  • Shrink End При расширении старайтесь оставаться справа или внизу расширенной области.

  • Stretch Ratio: соотношение между развёрнутыми элементами управления и занимаемым ими доступным пространством. Элемент управления со значением "2" займёт вдвое больше доступного пространства, чем элемент управления со значением "1".

Рекомендуется поэкспериментировать с этими флагами и различными контейнерами, чтобы лучше понять, как они работают.

Типы Container

Godot предлагает несколько типов контейнеров по умолчанию, поскольку они служат разным целям:

Box Containers (Контейнеры-ящики)

Располагает дочерние элементы управления вертикально или горизонтально (через HBoxContainer и VBoxContainer). В противоположном указанному направлению (например, вертикально для горизонтального контейнера) дочерние элементы просто разворачиваются.

../../_images/containers_box.png

Эти контейнеры используют свойство Stretch Ratio для дочерних элементов с установленным флагом Expand.

Grid Container (Сетчатый контейнер)

Располагает дочерние элементы управления в виде сетки (через GridContainer, необходимо указать количество столбцов). Использует как вертикальный, так и горизонтальный флаги расширения.

../../_images/containers_grid.png

Margin Container (Контейнер маржи)

Дочерние элементы управления расширяются до границ данного элемента управления (через MarginContainer). Отступы к полям будут добавлены в зависимости от настроек темы.

../../_images/containers_margin.png

Опять же, помните, что поля — это значение Theme, поэтому их необходимо редактировать в разделе переопределений констант каждого элемента управления:

../../_images/containers_margin_constants.png

Tab Container (Контейнер вкладок)

Позволяет размещать несколько дочерних элементов управления друг над другом (через TabContainer), при этом видимым будет только текущий элемент.

../../_images/containers_tab.png

Изменение текущего значения осуществляется с помощью вкладок, расположенных в верхней части контейнера, путем нажатия:

../../_images/containers_tab_click.gif

Заголовки генерируются из имен узлов по умолчанию (хотя их можно переопределить через API TabContainer).

Такие настройки, как размещение вкладок и StyleBox, можно изменить в переопределениях темы TabContainer.

Split Container (Раздельный контейнер)

Принимает только один или два дочерних элемента управления, а затем размещает их рядом друг с другом с помощью разделителя (через HSplitContainer и VSplitContainer). Учитывает как горизонтальные, так и вертикальные флаги, а также Ratio.

../../_images/containers_split.png

Разделитель можно перетаскивать, чтобы изменить соотношение размеров между двумя дочерними элементами:

../../_images/containers_split_drag.gif

PanelContainer (Панельный контейнер)

Контейнер, который отображает StyleBox, а затем расширяет дочерние элементы, чтобы покрыть всю его область (через PanelContainer, с учетом полей StyleBox). Он учитывает как горизонтальные, так и вертикальные размеры.

../../_images/containers_panel.png

Этот контейнер полезен в качестве элемента управления верхнего уровня или просто для добавления пользовательских фонов к разделам макета.

FoldableContainer (Складной контейнер)

Контейнер, который можно развернуть/свернуть (через FoldableContainer). Дочерние элементы управления скрываются при его сворачивании.

ScrollContainer (Контейнер для прокрутки)

Принимает один дочерний узел. Если дочерний узел больше контейнера, будут добавлены полосы прокрутки для панорамирования узла (через ScrollContainer). Учитываются как вертикальные, так и горизонтальные параметры размера, и это поведение можно включить или отключить для каждой оси в свойствах.

../../_images/containers_scroll.png

Колесико мыши и сенсорное перетаскивание (если сенсорное управление доступно) также являются допустимыми способами панорамирования дочернего элемента управления.

../../_images/containers_center_pan.gif

Как и в примере выше, один из наиболее распространенных способов использования этого контейнера — совместно с VBoxContainer в качестве дочернего элемента.

AspectRatioContainer

Тип контейнера, который размещает дочерние элементы управления таким образом, чтобы их пропорции автоматически сохранялись при изменении размера контейнера. (через AspectRatioContainer). Он поддерживает несколько режимов растяжения, позволяющих регулировать размеры дочерних элементов управления относительно контейнера: "fill (заполнение)," "width control height (высота элемента управления шириной)," "height control width (ширина элемента управления высотой)," and "cover (покрытие)."

../../_images/containers_aspectratio.webp

Это полезно, когда у вас есть контейнер, который должен быть динамичным и реагировать на разные размеры экрана, и вы хотите, чтобы дочерние элементы масштабировались пропорционально, не теряя при этом своих предполагаемых форм.

../../_images/containers_aspectratio_drag.webp

FlowContainer

FlowContainer — это контейнер, который размещает свои дочерние элементы управления горизонтально или вертикально (через HFlowContainer и через VFlowContainer). Когда доступное место заканчивается, он переносит дочерние элементы на следующую строку или столбец, подобно тому, как текст переносится в книге.

../../_images/containers_hflow.webp

Это полезно для создания гибких макетов, в которых дочерние элементы управления автоматически подстраиваются под доступное пространство, не перекрывая друг друга.

../../_images/containers_hflow_drag.webp

CenterContainer

CenterContainer — это контейнер, который автоматически центрирует все дочерние элементы управления внутри себя при их минимальном размере. Он гарантирует, что дочерние элементы управления всегда будут выровнены по центру, что упрощает создание центрированных макетов без ручного позиционирования (через CenterContainer).

../../_images/containers_center.webp ../../_images/containers_center_drag.webp

SubViewportContainer

Это специальный элемент управления, который принимает только один узел Viewport в качестве дочернего элемента и отображает его так, как если бы это было изображение (через SubViewportContainer).

Создание пользовательских Containers

Можно создать собственный контейнер с помощью скрипта. Вот пример контейнера, который подгоняет дочерние элементы под свой размер:

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(), size))

func set_some_setting():
    # Some setting changed, ask for children re-sort.
    queue_sort()