Usando 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):
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:
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.
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¶
Organiza los controles secundarios de forma vertical u horizontal (mediante HBoxContainer y VBoxContainer). En la dirección opuesta a la designada (es decir, vertical para un contenedor horizontal), simplemente expande los hijos. Esta disposición te permite alinear y distribuir los controles de manera conveniente en tus interfaces gráficas.
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.
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.
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:
Tab Container¶
Permite colocar varios controles hijo apilados unos encima de otros (vía TabContainer), con sólo el corriente visible.
El cambio de la corriente se realiza a través de las pestañas situadas en la parte superior del contenedor, mediante un clic:
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.
El divisor puede ser arrastrado para cambiar la relación de tamaño entre ambos niños:
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.
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.
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.
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()