Item selection with a custom adaptor

Rotorz ReorderableList

Item selection with a custom adaptor

Item selection can be added to a reorderable list control by creating a custom reorderable list adaptor. Selection state can be efficiently represented using a hash set collection.

selectable-items
using Rotorz.ReorderableList;
using System.Collections.Generic;
using UnityEngine;

public class SelectableItemAdaptor : GenericListAdaptor<string> {

    private HashSet<int> _selectedIndices = new HashSet<int>();

    public SelectableItemAdaptor(List<string> list, float itemHeight)
        : base(list, null, itemHeight) {
    }

    public override void DrawItemBackground(Rect position, int index) {
        if (_selectedIndices.Contains(index))
            ReorderableListStyles.SelectedItem.Draw(position, GUIContent.none, false, false, false, false);
    }

    public override void DrawItem(Rect position, int index) {
        int controlID = GUIUtility.GetControlID(FocusType.Passive);

        switch (Event.current.GetTypeForControl(controlID)) {
            case EventType.MouseDown:
                if (Event.current.button == 0 && position.Contains(Event.current.mousePosition)) {
                    if (Event.current.control) {
                        // Toggle selection of this item if control key is held.
                        if (_selectedIndices.Contains(index))
                            _selectedIndices.Remove(index);
                        else
                            _selectedIndices.Add(index);
                    }
                    else {
                        // Deselect all other items and select this one instead.
                        _selectedIndices.Clear();
                        _selectedIndices.Add(index);
                    }
                    Event.current.Use();
                }
                break;

            case EventType.Repaint:
                GUI.skin.label.Draw(position, this[index], false, false, false, false);
                break;
        }
    }

}
#pragma strict
import Rotorz.ReorderableList;
import System.Collections.Generic;

class SelectableItemAdaptor extends GenericListAdaptor.<String> {

    private var _selectedIndices:HashSet.<int> = new HashSet.<int>();

    function SelectableItemAdaptor(list:List<String>, itemHeight:float) {
        super(list, null, itemHeight);
    }

    function DrawItemBackground(position:Rect, index:int) {
        if (_selectedIndices.Contains(index))
            ReorderableListStyles.SelectedItem.Draw(position, GUIContent.none, false, false, false, false);
    }

    function DrawItem(position:Rect, index:int) {
        var controlID = GUIUtility.GetControlID(FocusType.Passive);

        switch (Event.current.GetTypeForControl(controlID)) {
            case EventType.MouseDown:
                if (Event.current.button == 0 && position.Contains(Event.current.mousePosition)) {
                    if (Event.current.control) {
                        // Toggle selection of this item if control key is held.
                        if (_selectedIndices.Contains(index))
                                _selectedIndices.Remove(index);
                        else
                            _selectedIndices.Add(index);
                    }
                    else {
                        // Deselect all other items and select this one instead.
                        _selectedIndices.Clear();
                        _selectedIndices.Add(index);
                    }
                    Event.current.Use();
                }
                break;

            case EventType.Repaint:
                GUI.skin.label.Draw(position, this[index], false, false, false, false);
                break;
        }
    }

}