Work in progress

The content of this page was not yet updated for Godot 4.2 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

Controles GUI personalizados

Tantos controles...

Sin embargo, nunca hay suficientes. Crear tus propios controles personalizados que actúen como tú quieres es una obsesión de casi todos los programadores de GUI. Godot proporciona muchos de ellos, pero puede que no funcionen exactamente de la manera que quieres. Antes de contactar a los desarrolladores con una solicitud de soporte para barras de desplazamiento diagonales, al menos será bueno saber cómo crear estos controles fácilmente desde el script.

Dibujando

Para dibujar, se recomienda consultar el tutorial Dibujos personalizados en 2D. Lo mismo se aplica. Algunas funciones son dignas de mención por su utilidad a la hora de dibujar, por lo que se detallarán a continuación:

Comprobando el tamaño del control

Unlike 2D nodes, "size" is important with controls, as it helps to organize them in proper layouts. For this, the Control.size property is provided. Checking it during _draw() is vital to ensure everything is kept in-bounds.

Comprobando el enfoque

Algunos controles (como los botones o los editores de texto) pueden proporcionar un enfoque de entrada para el teclado o el joypad de entrada. Ejemplos de ello son la introducción de texto o la pulsación de un botón. Esto se controla con la propiedad Control.focus_mode. Cuando se dibuja, y si el control soporta el enfoque de entrada, siempre se desea mostrar algún tipo de indicador (resaltado, cuadro, etc.) para indicar que este es el control actualmente enfocado. Para comprobar este estado, existe el método Control.has_focus(). Ejemplo

func _draw():
    if has_focus():
         draw_selected()
    else:
         draw_normal()

Escalando

Como se mencionó anteriormente, el tamaño es importante para los Control. Esto les permite colocarse correctamente, cuando se colocan en rejillas, contenedores o cuando están anclados. La mayoría de las veces, proporcionan un tamaño mínimo para ayudar a colocarlos correctamente. Por ejemplo, se colocan verticalmente uno encima del otro usando un VBoxContainer, el tamaño mínimo se asegurará de que su control personalizado no sea aplastado por los otros controles en el contenedor.

To provide this callback, just override Control._get_minimum_size(), for example:

func _get_minimum_size():
    return Vector2(30, 30)

Alternativamente, configúralo usando una función:

func _ready():
    set_custom_minimum_size(Vector2(30, 30))

Entrada

Los controles proporcionan unos cuantos ayudantes para que la gestión de los eventos de entrada sea mucho más fácil que la de los nodos regulares.

Eventos de entrada

Hay algunos tutoriales sobre la entrada de datos antes de este, pero vale la pena mencionar que los controles tienen un método especial de entrada de datos que sólo funciona cuando:

  • El puntero del mouse está sobre el control.

  • El botón fue presionado sobre este control (el control siempre captura la entrada hasta que se suelta el botón)

  • Control proporciona el foco del teclado/joypad a través de Control.focus_mode.

This function is Control._gui_input(). Simply override it in your control. No processing needs to be set.

extends Control

func _gui_input(event):
   if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
       print("Left mouse button was pressed!")

Para obtener más información sobre los eventos propios, consulte el tutorial Usando InputEvent.

Notificaciones

Los nodos Control también tienen muchas notificaciones útiles para los que no existe ninguna llamada de retorno, pero que se pueden verificar con la llamada de retorno _notification:

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.