ユーザーが特定の操作 (ラベルの右クリックなど) を行った時に一揃いの選択肢を表示するには、コンテキストメニューイベント ContextualMenuManipulator
および ContextualMenuPopulateEvent
を使用します。
コンテキストメニューを有効化にするには、ContextualMenuManipulator
をビジュアル要素にアタッチします。このマニピュレーターは、右ボタンの Mouse Up イベントかメニューの Key Up イベントのいずれかの後にコンテキストメニューを表示します。また、ContextualMenuManipulator
マニピュレーターは、ContextualMenuPopulateEvent
に応答するコールバックも追加します。
以下のコード例は、ビジュアル要素にコンテクストメニューを追加します。メニューには 1 つの項目しかありません。
void InstallManipulator(VisualElement element)
{
ContextualMenuManipulator m = new ContextualMenuManipulator(MyDelegate);
m.target = element;
}
void MyDelegate(ContextualMenuPopulateEvent event)
{
// Modify event.menu
event.menu.AppendAction("My action", DisplayProperties, DropdownMenu.MenuAction.AlwaysEnabled);
}
void DisplayProperties(DropdownMenu.MenuAction menuItem)
{
// ...
}
ContextualMenuManipulator
コンストラクターに渡されるコールバックが最後に呼び出されるので、子要素のメニューへの追加が可能になります。
このマニピュレーターは、ターゲット要素階層に伝播される ContextualMenuPopulateEvent
イベントを送信します。イベントは伝播パスに沿って進みます。つまり、ビジュアルツリーのルートからターゲットに向かって進み、ルートに向かってビジュアルツリーを戻ります。伝播パス中で、ContextualMenuPopulateEvent
イベント用のコールバックを持つ要素は、コンテキストメニューの項目の追加、削除、更新を行えます。
要素は、ContextualMenuPopulateEvent
を受け取ると、[DropdownMenu.InsertAction()
](../ScriptReference/UIElements.DropdownMenu.InsertAction] か DropdownMenu.AppendAction(.html)
のいずれかを呼び出してコンテキストメニューにメニュー項目を追加します。
[DropdownMenu.InsertAction()
](../ScriptReference/UIElements.DropdownMenu.InsertAction] と DropdownMenu.AppendAction(.html)
は、パラメーターとして 2 つのコールバックを取ります。最初のコールバックは、ユーザーがメニュー内の項目を選択した時に実行されます。2 番目のコールバックは、メニューを表示する前に実行され、メニュー項目が有効になっているかどうかのチェックも行います。
これらのコールバックは両方とも MenuAction
をパラメーターとして受け取ります。MenuAction
はメニュー項目を表し、以下のプロパティを持っています。
MenuAction.userData
には、AppendAction()
や InsertAction()
で使用されるユーザーデータへの参照が含まれます。MenuAction.eventInfo
には、コンテキストメニューを表示するイベントに関する情報が含まれます。イベントに応答するアクション内で MenuAction.eventInfo
を使用してください。例えば、マウスの位置を使用して、選択されたコンテキストメニュー項目に基づいてオブジェクトを作成および配置できます。以下の例は、2 つのラベルを持つカスタムエディターウィンドウを作成し、各ラベルにコンテキストメニューを追加します。この例は、コンテキストメニューの追加、削除、更新の方法を示すものです。
任意のテンプレートで Unity プロジェクトを作成します。
Project ウィンドウに、Editor
という名前のフォルダーを作成します。
Editor
ウィンドウで、ContextualMenuDemo
という名前の C# スクリプトを作成し、その内容を以下に置き換えます。
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class ContextualMenuDemo : EditorWindow
{
[MenuItem("Window/ContextualMenuDemo")]
public static void ShowExample()
{
ContextualMenuDemo wnd = GetWindow<ContextualMenuDemo>();
wnd.titleContent = new GUIContent("ContextualMenuDemo");
}
public void CreateGUI()
{
VisualElement root = rootVisualElement;
VisualElement label = new Label("Right click me!");
root.Add(label);
AddANewContextMenu(label);
InsertIntoAnExistingMenu(label);
VisualElement second = new Label("Click me also!");
root.Add(second);
AddANewContextMenu(second);
InsertIntoAnExistingMenu(second);
// Override the default behavior by clearing the menu.
ReplaceContextMenu(second);
}
void AddANewContextMenu(VisualElement element)
{
// The manipulator handles the right click and sends a ContextualMenuPopulateEvent to the target element.
// The callback argument passed to the constructor is automatically registered on the target element.
element.AddManipulator(new ContextualMenuManipulator((evt) =>
{
evt.menu.AppendAction("First menu item", (x) => Debug.Log("First!!!!"), DropdownMenuAction.AlwaysEnabled);
evt.menu.AppendAction("Second menu item", (x) => Debug.Log("Second!!!!"), DropdownMenuAction.AlwaysEnabled);
}));
}
void InsertIntoAnExistingMenu(VisualElement element)
{
element.RegisterCallback<ContextualMenuPopulateEvent>((evt) =>
{
evt.menu.AppendSeparator();
evt.menu.AppendAction("Another action", (x) => Debug.Log("Another Action!!!!"), DropdownMenuAction.AlwaysEnabled);
});
}
void ReplaceContextMenu(VisualElement element)
{
element.RegisterCallback<ContextualMenuPopulateEvent>((evt) =>
{
evt.menu.ClearItems();
evt.menu.AppendAction("The only action", (x) => Debug.Log("The only action!"), DropdownMenuAction.AlwaysEnabled);
});
}
}
Unity でこの例を見るには、メニューから Window > UI Toolkit > ContextualMenuDemo と選択してください。