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.

自訂 GUI 控制元件

控制元件真多呀……

不過這永遠都不嫌多。幾乎每個 GUI 開發者都熱衷於建立完全符合自己需求的自訂控制元件。Godot 提供了大量控制元件,但它們可能不完全如你所願。在向開發者提交支援斜向捲軸的 Pull Request 之前,至少應該先學會如何用腳本輕鬆建立這些控制元件。

繪製

繪製方面,建議先參考 2D 中的自訂繪圖 教學。這些原理同樣適用於控制元件的繪製。有些函式對於繪製特別實用,接下來會詳細介紹:

檢查控制元件尺寸

與 2D 節點不同,「尺寸」對控制元件來說很重要,這有助於正確地在版面配置中排列它們。為此,提供了 Control.size 屬性。在 _draw() 期間檢查這個屬性,可以確保所有內容都維持在元件範圍內。

檢查焦點

部分控制元件(如按鈕或文字編輯器)可以為鍵盤或手把輸入提供焦點。例如輸入文字或按下按鈕。這是透過 Control.focus_mode 屬性來控制。繪製時,若該控制元件支援焦點,通常會顯示某種提示(高亮、框線等),表示目前該元件獲得焦點。要檢查此狀態,可以使用 Control.has_focus() 方法。範例:

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

調整尺寸

如前所述,尺寸對控制元件來說非常重要,這能讓它們在網格、容器或錨點配置時正確排列。大多數控制元件會提供 最小尺寸 ,以協助正確地安排它們。例如,若控制元件透過 VBoxContainer 垂直堆疊,最小尺寸會確保你的自訂元件不會被其他元件擠壓變形。

要提供這個回呼,只需覆寫 Control._get_minimum_size() ,例如:

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

或者,直接用函式設定:

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

輸入

控制元件提供了一些輔助工具,讓輸入事件的處理比一般節點更方便。

輸入事件

雖然前面已經有幾個關於輸入的教學,不過值得一提的是,控制元件有一個特殊的輸入處理方法,僅在以下情況下才會觸發:

  • 滑鼠指標位於控制元件上方。

  • 滑鼠鍵在此控制元件上被按下(控制元件會持續捕捉輸入,直到按鍵釋放為止)

  • 控制元件可透過 Control.focus_mode 提供鍵盤或手把焦點。

此函式為 Control._gui_input()。要使用它,只需在你的控制元件中覆寫即可,無須額外設定處理流程。

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!")

有關事件本身的詳細資訊,請參閱 使用 InputEvent 教學。

通知

控制元件也有許多實用的通知,雖然沒有專屬的回呼函式,但可以透過 _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.