Work in progress

The content of this page was not yet updated for Godot 4.6 and may be outdated. If you know how to improve this page or you can confirm that it's up to date, feel free to open a pull request.

Пользовательские элементы управления графическим интерфейсом (GUI)

Так много элементов управления...

Но их никогда не бывает достаточно. Создание собственных элементов управления, которые работают именно так, как вам нужно, — страсть практически каждого программиста GUI (графического интерфейса). Godot предоставляет множество таких элементов, но они могут работать не совсем так, как вам нужно. Прежде чем обращаться к разработчикам с запросом на добавление поддержки диагональных полос прокрутки, неплохо было бы хотя бы узнать, как легко создавать такие элементы управления из скрипта.

Отрисовка

Для рисования рекомендуется ознакомиться с руководством Пользовательская отрисовка в 2D. То же самое применимо. Некоторые функции заслуживают упоминания из-за их полезности при рисовании, поэтому мы подробно рассмотрим их далее:

Проверка размера элемента управления

В отличие от 2D-узлов, "size (размер)" важен для элементов управления, поскольку он помогает организовать их в правильные макеты. Для этого предусмотрено свойство 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 обеспечивает фокусировку клавиатуры/джойстика через 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.