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.
Checking the stable version of the documentation...
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()
public override void _Draw()
{
if (HasFocus())
{
DrawSelected()
}
else
{
DrawNormal();
}
}
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)
public override Vector2 _GetMinimumSize()
{
return new Vector2(20, 20);
}
Alternativamente, impostalo tramite una funzione:
func _ready():
set_custom_minimum_size(Vector2(30, 30))
public override void _Ready()
{
CustomMinimumSize = new Vector2(20, 20);
}
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!")
public override void _GuiInput(InputEvent @event)
{
if (@event is InputEventMouseButton mbe && mbe.ButtonIndex == MouseButton.Left && mbe.Pressed)
{
GD.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.
public override void _Notification(int what)
{
switch (what)
{
case NotificationMouseEnter:
// Mouse entered the area of this control.
break;
case NotificationMouseExit:
// Mouse exited the area of this control.
break;
case NotificationFocusEnter:
// Control gained focus.
break;
case NotificationFocusExit:
// Control lost focus.
break;
case NotificationThemeChanged:
// Theme used to draw the control changed;
// update and redraw is recommended if using a theme.
break;
case NotificationVisibilityChanged:
// Control became visible/invisible;
// check new status with is_visible().
break;
case NotificationResized:
// Control changed size; check new size with get_size().
break;
case NotificationModalClose:
// For modal pop-ups, notification that the pop-up was closed.
break;
}
}