Using Containers

Anchors son una forma eficiente de manejar diferentes relaciones de aspecto para el manejo básico de resolución múltiple en las GUI,

En el caso de las interfaces de usuario más complejas, pueden llegar a ser difíciles de usar.

Este es a menudo el caso de los juegos, como los RPG, los chats online, los tycoons o las simulaciones. Otro caso común en el que pueden requerirse características de diseño más avanzadas es el de las herramientas dentro del juego (o simplemente las herramientas).

Todas estas situaciones requieren una interfaz de usuario más capaz, como un sistema operativo, con un diseño y formato avanzados. Para eso, Containers son más útiles.

Esquema de Containers

Los contenedores proporcionan una enorme cantidad de potencia de diseño (por ejemplo, la interfaz de usuario del editor de Godot está totalmente hecha con ellos):

../../_images/godot_containers.png

Cuando se usa un nodo Container derivado, todos los nodos Control hijos renuncian a su propia capacidad de posicionamiento. Esto significa que el Contenedor controlará su posicionamiento y cualquier intento de alterar manualmente estos nodos será o bien ignorado o invalidado la próxima vez que su padre sea redimensionado.

De la misma manera, cuando un nodo derivado de Contenedor es redimensionado, todos sus hijos serán reubicados de acuerdo a él, con un comportamiento basado en el tipo de contenedor utilizado:

../../_images/container_example.gif

Ejemplo de HBoxContainer cambiando el tamaño de los botones para niños.

La verdadera fuerza de los contenedores es que pueden anidarse (como nodos), lo que permite crear diseños muy complejos que se redimensionan sin esfuerzo.

Size flags

Cuando se añade un nodo a un contenedor, la forma en que el contenedor trata a cada hijo depende principalmente de sus size flags. Estas flags pueden ser encontradas inspeccionando cualquier control que sea hijo de un contenedor.

../../_images/container_size_flags.png

Las size flags son independientes para el tamaño vertical y horizontal y no todos los contenedores las utilizan (pero la mayoría sí):

  • Fill: Asegura que el control llena el área designada dentro del contenedor. No importa si un control se expande o no (ver más abajo), sólo llenará el área designada cuando éste esté activado (es por defecto).

  • Expandir: Intenta utilizar tanto espacio como sea posible en el contenedor padre (en cada eje). Los controles que no se expanden serán alejados por los que sí lo hacen. Entre los controles que se expanden, la cantidad de espacio que toman entre sí está determinada por el Ratio (ver abajo).

  • Shrink Center Cuando se expande (y si no se llena), trata de permanecer en el centro del área expandida (por defecto permanece a la izquierda o arriba).

  • Ratio Relación simple de cuánto los controles expandidos ocupan el espacio disponible en relación a cada uno. Un control con "2", ocupará el doble de espacio disponible que uno con "1".

Se recomienda experimentar con estas banderas y diferentes contenedores para comprender mejor cómo funcionan.

Tipos de Container

Godot proporciona varios tipos de contenedores fuera de la caja ya que sirven para diferentes propósitos:

Box Containers

Arranges child controls vertically or horizontally (via HBoxContainer and VBoxContainer). In the opposite of the designated direction (as in, vertical for an horizontal container), it just expands the children.

../../_images/containers_box.png

Estos contenedores hacen uso de la propiedad Ratio para los niños con la bandera Expandir puesta.

Grid Container

Dispone los controles hijo en un diseño de cuadrícula (mediante GridContainer, se debe especificar la cantidad de columnas). Utiliza las banderas de expansión vertical y horizontal.

../../_images/containers_grid.png

Margin Container

Los controles de hijos se expanden hacia los límites de este control (vía MarginContainer). Se añadirá un relleno en los márgenes dependiendo de la configuración del tema.

../../_images/containers_margin.png

De nuevo, ten en cuenta que los márgenes son un valor Theme, por lo que deben ser editados desde la sección de sobreescrituras constantes de cada control:

../../_images/containers_margin_constants.png

Tab Container

Permite colocar varios controles hijo apilados unos encima de otros (vía TabContainer), con sólo el corriente visible.

../../_images/containers_tab.png

El cambio de la corriente se realiza a través de las pestañas situadas en la parte superior del contenedor, mediante un clic:

../../_images/containers_tab_click.gif

Los títulos se generan a partir de los nombres de los nodos por defecto (aunque pueden ser anulados a través de la API TabContainer).

Los ajustes como la colocación de las pestañas y StyleBox pueden ser modificados en el tema TabContainer.

Split Container

Acepta sólo uno o dos control hijos, y luego los coloca de lado a lado con un divisor (vía HSplitContainer y VSplitContainer). Respeta tanto las banderas horizontal como las vertical, así como Ratio.

../../_images/containers_split.png

El divisor puede ser arrastrado para cambiar la relación de tamaño entre ambos niños:

../../_images/containers_split_drag.gif

Panel Container

Un simple contenedor que dibuja una StyleBox, y luego expande a los hijos para cubrir toda su área (vía PanelContainer, respetando los márgenes de StyleBox). Respeta las flags de tamaño horizontal y vertical.

../../_images/containers_panel.png

Este contenedor es útil como nivel superior, o simplemente para añadir fondos personalizados a secciones de un diseño.

Scroll Container

Acepta un solo nodo hijo. Si este nodo es más grande que el contenedor, se añadirán barras de desplazamiento para permitir el desplazamiento del nodo (via ScrollContainer). Se respetan las flags de tamaño vertical y horizontal, y el comportamiento puede ser activado o desactivado por eje en las propiedades.

../../_images/containers_scroll.png

La rueda del ratón y el arrastre táctil (cuando el tacto está disponible) también son formas válidas de desplazar el control del hijo.

../../_images/containers_center_pan.gif

Como en el ejemplo anterior, una de las formas más comunes de usar este contenedor es junto con un VBoxContainer de hijo.

ViewportContainer

Este es un control especial que sólo aceptará un único nodo Viewport como hijo, y lo mostrará como si fuera una imagen (vía ViewportContainer).

Creando contenedores personalizados

Es posible crear fácilmente un contenedor personalizado utilizando un script. He aquí un ejemplo de un simple contenedor que se ajusta a los hijos a su tamaño de cuadrado:

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