Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Controlli GUI personalizzati

Così tanti controlli...

Eppure non ce ne sono mai abbastanza. Creare controlli personalizzati che funzionino esattamente come desiderato è un'ossessione di quasi tutti i programmatori di interfacce grafiche. Godot ne fornisce molti, ma potrebbero non funzionare esattamente come desiderato. Prima di contattare gli sviluppatori con una pull-request per supportare le barre di scorrimento diagonali, sarebbe almeno utile sapere come creare facilmente questi controlli da uno script.

Disegnare

Per il disegno, si consiglia di consultare il tutorial Custom drawing in 2D. Lo stesso si applica qui. Alcune funzioni meritano di essere menzionate per la loro utilità durante il disegno, quindi saranno descritte in dettaglio di seguito:

Verificar le dimensioni del controllo

A differenza dei nodi 2D, le "dimensioni" sono importanti con i controlli, poiché aiuta a organizzarli in layout appropriati. A questo scopo, è fornita la proprietà Control.size. Verificarla durante _draw() è fondamentale per garantire che tutto rimanga nei limiti.

Verifica del focus

Alcuni controlli (come pulsanti o editor di testo) potrebbero permettere di catturare gli l'input da tastiera o joypad. Esempi di ciò sono l'inserimento di testo o la pressione di un pulsante. Questo è controllato dalla proprietà Control.focus_mode. Durante il disegno, e se il controllo supporta il focus tramite input, è sempre opportuno visualizzare un qualche tipo di indicatore (evidenziazione, riquadro, ecc.) per indicare che questo è il controllo attualmente attivo. Per verificare questo stato, esiste il metodo Control.has_focus(). Esempio

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

Dimensionamento

As mentioned before, size is important to controls. This allows them to lay out properly, when set into grids, containers, or anchored. Controls, most of the time, provide a minimum size to help properly lay them out. For example, if controls are placed vertically on top of each other using a VBoxContainer, the minimum size will make sure your custom control is not squished by the other controls in the container.

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

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

Alternativamente, impostalo tramite una funzione:

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

Input

Controls provide a few helpers to make managing input events much easier than regular nodes.

Eventi di input

There are a few tutorials about input before this one, but it's worth mentioning that controls have a special input method that only works when:

  • The mouse pointer is over the control.

  • The button was pressed over this control (control always captures input until button is released)

  • I controlli forniscono il focus su tastiera/joypad tramite Control.focus_mode.

This function is Control._gui_input(). To use it, 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!")

Per ulteriori informazioni sugli eventi stessi, consulta il tutorial Utilizzo di InputEvent.

Notifiche

I controlli dispongono anche di numerose utili notifiche per le quali non esiste un callback dedicato, ma che si possono verificare attraverso il callback _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.