自定义GUI控件

这么多控制…

然而,还远远不够。创建您自己的自定义控件,使其按照您希望的方式运行,这几乎是每个GUI程序员的痴迷。Godot提供了很多,但他们可能不会完全按照你想要的方式工作。在用一个pull请求与开发人员联系以支持对角滚动条之前,至少应该知道如何从脚本轻松创建这些控件。

绘图

对于图纸,建议检查 二维自定义绘图 辅导的。同样适用。有些功能在绘图时很有用,值得一提,下面将详细介绍:

检查控件大小

与二维节点不同,“大小”对于控件很重要,因为它有助于在适当的布局中组织控件。为此, Control.rect_size 提供了属性。检查过程中 _draw() 确保一切都在界限之内是至关重要的。

检查焦点

一些控件(如按钮或文本编辑器)可能为键盘或控制面板输入提供输入焦点。例如输入文本或按下按钮。这是用 Control.focus_mode 属性。绘制时,如果控件支持输入焦点,则始终需要显示某种指示器(突出显示、框等),以指示这是当前焦点控件。要检查此状态,请 Control.has_focus() 方法存在。例子

func _draw():
    if has_focus():
         draw_selected()
    else:
         draw_normal()
public override void _Draw()
{
    if (HasFocus())
    {
        DrawSelected()
    }
    else
    {
        DrawNormal();
    }
}

上浆

如前所述,尺寸对控制很重要。这允许它们在设置到网格、容器或锚定位置时正确布局。大多数情况下,控件提供 最小尺寸 帮助正确布局。例如,如果使用 VBoxContainer 最小大小将确保自定义控件不会被容器中的其他控件压扁。

要提供此回调,只需重写 Control.get_minimum_size() 例如:

func get_minimum_size():
    return Vector2(30, 30)
public override Vector2 _GetMinimumSize()
{
    return new Vector2(20, 20);
}

或者,通过函数设置:

func _ready():
    set_custom_minimum_size(Vector2(30, 30))
public override void _Ready()
{
    SetCustomMinimumSize(new Vector2(20, 20));
}

输入

控件提供了一些帮助器,使管理输入事件比常规节点容易得多。

输入事件

在此之前有一些关于输入的教程,但值得一提的是,控件有一个特殊的输入方法,只有在以下情况下才能工作:

  • 鼠标指针在控件上。

  • 在该控件上按下了按钮(控件始终捕获输入,直到释放按钮)

  • 控件通过 Control.focus_mode .

这个功能是 Control._gui_input() . 只需在您的控件中覆盖它。不需要设置处理。

extends Control

func _gui_input(event):
   if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
       print("Left mouse button was pressed!")
public override void _GuiInput(InputEvent @event)
{
    if (@event is InputEventMouseButton mbe && mbe.ButtonIndex == (int)ButtonList.Left && mbe.Pressed)
    {
        GD.Print("Left mouse button was pressed!");
    }
}

有关事件本身的更多信息,请检查 InputEvent 辅导的。

通知

控件还具有许多有用的通知,这些通知不存在专用的回调,但可以通过通知回调进行检查:

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_CLOSED):
            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;
    }
}