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 Disegno personalizzato 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

Come accennato prima, le dimensioni sono importanti per i controlli. Gli consentono di disporsi correttamente, quando sono inseriti in griglie, contenitori o ancorati. I controlli solitamente forniscono una dimensione minima per aiutarli a disporsi correttamente. Ad esempio, se i controlli sono posizionati verticalmente uno sopra l'altro tramite un VBoxContainer, la dimensione minima garantirà che il controllo personalizzato non sia schiacciato dagli altri controlli nel contenitore.

Per fornire questo callback, basta sovrascrivere Control._get_minimum_size(), ad esempio:

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

Alternativamente, impostalo tramite una funzione:

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

Input

I controlli forniscono alcuni mezzi per aiutare molto a gestire gli eventi di input rispetto ai nodi regolari.

Eventi di input

Ci sono già alcuni tutorial sugli input prima di questo, ma vale la pena menzionare che i controlli hanno un metodo di input speciale che funziona solo quando:

  • Il puntatore del mouse si trova sopra il controllo.

  • Il pulsante è stato premuto sopra il controllo (il controllo acquisisce sempre l'input finché il pulsante non viene rilasciato)

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

Questa funzione è Control._gui_input(). Per utilizzarla, basta sovrascriverla nel proprio controllo. Non c'è bisogno di attivare alcuna elaborazione.

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.