カスタムGUIコントロール

非常に多くのコントロール...

まだ十分ではありません。希望どおりに動作する独自のカスタムコントロールを作成することは、ほとんどすべてのGUIプログラマーの執念です。 Godotはそれらの多くを提供しますが、期待どおりに動作しない場合があります。斜めスクロールバーをサポートするためのプルリクエストで開発者に連絡する前に、少なくともスクリプトからこれらのコントロールを簡単に作成する方法を知っておくとよいでしょう。

描画

描画については、2Dカスタム描画 チュートリアルを確認することをお勧めします。同じことが当てはまります。一部の関数は、描画時の有用性から特に言及する価値があるため、次で詳しく説明します。

コントロールサイズの確認

2Dノードとは異なり、コントロールでは適切なレイアウトで整理することに役立つため、「サイズ」が重要です。このために、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() class_Control_method_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(入力イベント) チュートリアルを確認してください。

通知

コントロールには専用のコールバックは存在しませんが、_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_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;
    }
}