Dropdown with Categories

Do you think that this is possible with the default Dropdown menu or does something like this exist? It seems that I would have to make my own Dropdown Component to make this happen. If I have to I’ll post it here then.
All attempts to edit the contents didn’t really.

3277853--253495--dropdown.jpg

1 Like

Certainly possible with a bit of trickery. Although a TreeView in that instance would probably look better. I know we’ve had a request for a TreeView control on the UI Extensions project already but it hasn’t been progressed as yet.

I will take a look at your package, you can never have enough UI Code :slight_smile:

I was able to do it on my own. It is basically a list that is toggled on and off and fileld by the controller. The problem with using the existing Dropdown is that it controlls the size and position of the contet itself, not like a Vertical Layout Group and I would like to avoid that.

Got the code here, it is a bit messy with the Options handling but if somebody is interested take a look.
The list content is made with a VerticalLayoutGroup and the ContentSizeFitter.
You may add an animation to Show and Hide States.

Code

[RequireComponent(typeof(RectTransform))]
public class DropdownElement : MonoBehaviour
{
    public int ID;
    public Button Button;
    public Text Lable;
    public GameObject Checkmark;
}

-----------------------------------------------

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;


public class CustomDropdown : MonoBehaviour
{
    [SerializeField] UnityEvent OnValueChanged;
    [SerializeField] Text OptionsTitle;
    [SerializeField] GameObject List;
    [SerializeField] RectTransform Content;

    [SerializeField] DropdownElement Headline;
    [SerializeField] DropdownElement Element;
    bool DropdownOpen;

    [SerializeField] bool CloseOnSelection;

    List<string> Categories;
    List<string> Options;
    List<List<int>> CategoryOptions;
    public int SelectedOption;
    List<DropdownElement> Elements;


    void Awake()
    {
        Elements = new List<DropdownElement>();
        Categories = new List<string>();
        Options = new List<string>();
        CategoryOptions = new List<List<int>>();
        CategoryOptions.Add(new List<int>());
        HideDropdownList();
    }

    public void AddOption(string lable, int category = 0)
    {
        var options = CategoryOptions[category];
        options.Add(Options.Count);
        CategoryOptions[category] = options;
        Options.Add(lable);
    }

    public int AddCategory(string name)
    {
        Categories.Add(name);
        CategoryOptions.Add(new List<int>());
        return Categories.Count;
    }

    public void UpdateList()
    {
        DropdownElement obj; int optionCount = 0;
        for (int c = -1; c < Categories.Count; c++)
        {
            var options = CategoryOptions[c + 1];
            if (c >= 0)
            {
                obj = Instantiate(Headline, Content, false);
                obj.Lable.text = Categories[c];
            }

            for (int i = 0; i < options.Count; i++)
            {
                int eID = options[i];
                obj = Instantiate(Element, Content, false);
                obj.Lable.text = Options[eID];
                obj.Button.onClick.AddListener(delegate { OnSetValue(eID); });
                obj.ID = optionCount++;
                Elements.Add(obj);
            }
        }
    }

    void UpdateToggles()
    {
        for (int i = 0; i < Elements.Count; i++)
        {
            if (Elements[i].Checkmark != null)
                Elements[i].Checkmark.SetActive(SelectedOption == i);
        }
    }

    public void OnSetValue(int id)
    {
        SelectedOption = id;
        if (OptionsTitle != null) OptionsTitle.text = Options[id];
        UpdateToggles();
        OnValueChanged.Invoke();
        if (CloseOnSelection) HideDropdownList();
    }

    public void OnToggleList()
    {
        if (DropdownOpen) HideDropdownList();
        else ShowDropdownList();
    }

    void ShowDropdownList()
    {
        DropdownOpen = true;
        List.SetActive(DropdownOpen);
    }
    void HideDropdownList()
    {
        DropdownOpen = false;
        List.SetActive(DropdownOpen);
    }

    void ClearList()
    {
        int count = Content.childCount;
        while (count-- > 0)
        {
            GameObject.Destroy(Content.GetChild(0).gameObject);
        }
    }
}
1 Like