Customize context menu

Rotorz ReorderableList

Customize context menu

This example demonstrates how to add to, or even replace entirely, the list field's context menu.

First we need to implement a subclass of ReorderableListControl so that we can override the default context menu and add some custom items.

using Rotorz.ReorderableList;
using UnityEditor;

public class CustomContextMenuList : ReorderableListControl {

    private static readonly GUIContent s_MenuItem1 = new GUIContent("MenuItem1");
    private static readonly GUIContent s_MenuItem2 = new GUIContent("MenuItem2");

    protected override void AddItemsToMenu(GenericMenu menu, int itemIndex, IReorderableListAdaptor adaptor) {
        // Remove if default menu items are not wanted.
        base.AddItemsToMenu(menu, itemIndex, adaptor);

        menu.AddSeparator("");

        // Custom menu item the usual way:
        menu.AddItem(s_MenuItem1, false, () => Debug.Log("You selected menu item #1!"));
        // Or... implement as command:
        menu.AddItem(s_MenuItem2, false, defaultContextHandler, s_MenuItem2);
    }

    protected override bool HandleCommand(string commandName, int itemIndex,IReorderableListAdaptor adaptor) {
        // Remove if default commands are not wanted.
        if (base.HandleCommand(commandName, itemIndex, adaptor))
            return true;

        // Place custom command handler here...
        switch (commandName) {
            case "MenuItem2":
                Debug.Log("You selected menu item #2!");
                return true;
        }

        return false;
    }

}
#pragma strict
import Rotorz.ReorderableList;

class CustomContextMenuList extends ReorderableListControl {

    static var s_MenuItem1:GUIContent = new GUIContent('MenuItem1');
    static var s_MenuItem2:GUIContent = new GUIContent('MenuItem2');

    protected function AddItemsToMenu(menu:GenericMenu, itemIndex:int, adaptor:IReorderableListAdaptor) {
        // Remove if default menu items are not wanted.
        super.AddItemsToMenu(menu, itemIndex, adaptor);

        menu.AddSeparator('');

        // Custom menu item the usual way:
        menu.AddItem(s_MenuItem1, false, function() {
            Debug.Log('You selected menu item #1!');
        });

        // Or... implement as command:
        menu.AddItem(s_MenuItem2, false, defaultContextHandler, s_MenuItem2);
    }

    protected function HandleCommand(commandName:String, itemIndex:int, adaptor:IReorderableListAdaptor):boolean {
        // Remove if default commands are not wanted.
        if (super.HandleCommand(commandName, itemIndex, adaptor))
            return true;

        // Place custom command handler here...
        switch (commandName) {
            case 'MenuItem2':
                Debug.Log('You selected menu item #2!');
                return true;
        }

        return false;
    }

}

In order to use our custom reorderable list we will also need to instantiate an adaptor for our list. We can cache this adaptor alongside our custom list control instance.

private SerializedProperty _someListProperty;

private CustomContextMenuList _customListControl;
private IReorderableListAdaptor _someListAdaptor;

void OnEnable() {
    _someListProperty = serializedObject.FindProperty("someList");

    _customListControl = new CustomContextMenuList();
    _someListAdaptor = new SerializedPropertyAdaptor(someListProperty);
}

public override void OnInspectorGUI() {
    serializedObject.Update();

    _customListControl.Draw(_someListAdaptor);

    serializedObject.ApplyModifiedProperties();
}
var _someListProperty:SerializedProperty;

var _customListControl:CustomContextMenuList;
var _someListAdaptor:IReorderableListAdaptor;

function OnEnable() {
    _someListProperty = serializedObject.FindProperty('someList');

    _customListControl = new CustomContextMenuList();
    _someListAdaptor = new SerializedPropertyAdaptor(_someListProperty);
}

function OnInspectorGUI() {
    serializedObject.Update();

    _customListControl.Draw(_someListAdaptor);

    serializedObject.ApplyModifiedProperties();
}