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 提供了大量的控件,但它们可能并不完全如你所愿的方式工作。在使用支持对角滚动条的拉取请求与开发人员联系之前,至少应该了解如何从脚本轻松地创建这些控件。

绘制

谈到绘制, 推荐看看这篇 2D 中的自定义绘图 的教程. 同样的原理适用与控件绘制. 这里有些函数值得一提, 因为它们在绘制时有用, 所以接下来将进行详细说明:

检查控件的大小

与普通的 2D 节点不同,"尺寸(size)" 对于控件(Control)来说非常重要,因为它能帮助控件在布局中进行合理的排版。为此,Godot 专门提供了 Control.size 这个属性。在 _draw() 函数中检查这个尺寸数值是至关重要的,这样才能确保你绘制的所有内容都老老实实地待在控件的边界之内。

检查输入焦点

一些控件(如按钮或文本编辑器)可为键盘或手柄输入提供输入焦点. 这方面的例子是输入文本或按下一个按钮. 这可以通过 Control.focus_mode 属性来控制. 绘制时, 如果控件支持输入焦点, 总是希望显示某种指示来表明(高亮, 方框等), 当前这是焦点控件. 为了检查这个状态, 存在一个 Control.has_focus() 的方法. 例子

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

调整大小

如前所述, 尺寸对控件是很重要的. 这可以让它们在设置网格, 容器或锚定时以正确布局. 控件, 在大多数情况下, 提供了一个 minimum size , 以帮助它们正确布局. 例如, 如果控件被垂直放置在彼此的顶部, 使用 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() 。要想使用它,你只需要在自己的控件脚本里重写(override)它就行啦。而且完全不需要额外设置任何‘处理模式’(processing)。

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.