自定义 GUI 控件
控件真多呀……
不过这是永远不嫌多的。每个 GUI 程序员几乎都痴迷于创建自己的自定义控件,让这些控件让自己的要求工作。Godot 提供了大量的控件,但它们可能并不完全如你所愿的方式工作。在使用支持对角滚动条的拉取请求与开发人员联系之前,至少应该了解如何从脚本轻松地创建这些控件。
绘制
谈到绘制, 推荐看看这篇 2D 中的自定义绘图 的教程. 同样的原理适用与控件绘制. 这里有些函数值得一提, 因为它们在绘制时有用, 所以接下来将进行详细说明:
检查控件的大小
Unlike 2D nodes, “size” is important with controls, as it helps to organize them in proper layouts. For this, the Control.size property is provided. Checking it during _draw()
is vital to ensure everything is kept in-bounds.
检查输入焦点
一些控件(如按钮或文本编辑器)可为键盘或手柄输入提供输入焦点. 这方面的例子是输入文本或按下一个按钮. 这可以通过 Control.focus_mode 属性来控制. 绘制时, 如果控件支持输入焦点, 总是希望显示某种指示来表明(高亮, 方框等), 当前这是焦点控件. 为了检查这个状态, 存在一个 Control.has_focus() 的方法. 例子
GDScriptC#
func _draw():
if has_focus():
draw_selected()
else:
draw_normal()
public override void _Draw()
{
if (HasFocus())
{
DrawSelected()
}
else
{
DrawNormal();
}
}
调整大小
如前所述, 尺寸对控件是很重要的. 这可以让它们在设置网格, 容器或锚定时以正确布局. 控件, 在大多数情况下, 提供了一个 minimum size , 以帮助它们正确布局. 例如, 如果控件被垂直放置在彼此的顶部, 使用 VBoxContainer , 最小尺寸将确保你的自定义控件不会被容器中的其他控件挤压.
To provide this callback, just override Control._get_minimum_size(), for example:
GDScriptC#
func _get_minimum_size():
return Vector2(30, 30)
public override Vector2 _GetMinimumSize()
{
return new Vector2(20, 20);
}
或者, 使用函数进行设置:
GDScriptC#
func _ready():
set_custom_minimum_size(Vector2(30, 30))
public override void _Ready()
{
CustomMinimumSize = new Vector2(20, 20);
}
输入
控件为输入事件的管理提供了一些辅助工具,比普通节点要方便一点。
输入事件
在此之前有几个关于输入的教程, 但值得一提的是, 控件有一个特殊的输入方法, 只有在以下情况下才起作用:
鼠标指针悬停在控件上.
鼠标按键在此控件上被按下 (控件始终捕获输入, 直到按钮被释放)
控件通过以下方式提供键盘和手柄焦点 Control.focus_mode.
This function is Control._gui_input(). Simply override it in your control. No processing needs to be set.
GDScriptC#
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!");
}
}
有关事件本身的详细信息,请查看 使用 InputEvent 教程。
通知
控件也有许多有用的通知, 这些通知不存在专门的回调, 但可以用_notification回调来检查:
GDScriptC#
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;
}
}