You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
8.7 KiB
292 lines
8.7 KiB
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UnityEditor.Rendering
|
|
{
|
|
[UxmlElement]
|
|
internal partial class ToggleDropdown : VisualElement
|
|
{
|
|
const string k_StylesheetPathFormat = "Packages/com.unity.render-pipelines.core/Editor/Controls/ToggleDropdown.uss";
|
|
const string k_MainClass = "toggle-dropdown";
|
|
const string k_ToggleButtonClass = k_MainClass + "__toggle-button";
|
|
const string k_DropdownButtonClass = k_MainClass + "__dropdown-button";
|
|
const string k_SeparatorClass = k_MainClass + "__separator";
|
|
const string k_EnabledClass = k_MainClass + "--enabled";
|
|
|
|
private Button m_ToggleButton;
|
|
private Button m_DropdownButton;
|
|
private VisualElement m_DropdownArrow;
|
|
private VisualElement m_Separator;
|
|
private List<string> m_Options = new List<string>();
|
|
private HashSet<int> m_SelectedIndices = new HashSet<int>();
|
|
private int m_SelectedIndex = 0;
|
|
private bool m_IsEnabled = false;
|
|
private string m_Text = "Toggle Dropdown";
|
|
|
|
[UxmlAttribute]
|
|
public string text
|
|
{
|
|
get => m_Text;
|
|
set
|
|
{
|
|
if (m_Text == value)
|
|
return;
|
|
m_Text = value;
|
|
m_ToggleButton.text = m_Text;
|
|
}
|
|
}
|
|
|
|
[UxmlAttribute]
|
|
private string options { get; set; } = "";
|
|
|
|
[UxmlAttribute("selected-index")]
|
|
private int selectedIndex
|
|
{
|
|
get => m_SelectedIndex;
|
|
set
|
|
{
|
|
if (m_SelectedIndex == value || value < 0)
|
|
return;
|
|
m_SelectedIndex = value;
|
|
}
|
|
}
|
|
|
|
[UxmlAttribute("selected-indices")]
|
|
public string selectedIndices
|
|
{
|
|
get
|
|
{
|
|
var indices = new List<string>();
|
|
foreach (int index in m_SelectedIndices)
|
|
{
|
|
indices.Add(index.ToString());
|
|
}
|
|
return string.Join(",", indices.ToArray());
|
|
}
|
|
set
|
|
{
|
|
m_SelectedIndices.Clear();
|
|
if (!string.IsNullOrEmpty(value))
|
|
{
|
|
var indices = value.Split(',');
|
|
foreach (var indexStr in indices)
|
|
{
|
|
if (int.TryParse(indexStr.Trim(), out int index) && index >= 0)
|
|
{
|
|
m_SelectedIndices.Add(index);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[UxmlAttribute]
|
|
public bool value
|
|
{
|
|
get => m_IsEnabled;
|
|
set
|
|
{
|
|
if (m_IsEnabled == value)
|
|
return;
|
|
m_IsEnabled = value;
|
|
UpdateEnabledState();
|
|
}
|
|
}
|
|
|
|
/// <summary>Get the currently selected option text (first selected)</summary>
|
|
public string selectedOption
|
|
{
|
|
get
|
|
{
|
|
foreach (int index in m_SelectedIndices)
|
|
{
|
|
if (index < m_Options.Count)
|
|
return m_Options[index];
|
|
}
|
|
return "";
|
|
}
|
|
}
|
|
|
|
/// <summary>Get all selected options</summary>
|
|
public string[] selectedOptions
|
|
{
|
|
get
|
|
{
|
|
var result = new List<string>();
|
|
foreach (int index in m_SelectedIndices)
|
|
{
|
|
if (index < m_Options.Count)
|
|
result.Add(m_Options[index]);
|
|
}
|
|
return result.ToArray();
|
|
}
|
|
}
|
|
|
|
/// <summary>Get all selected indices</summary>
|
|
public int[] GetSelectedIndices()
|
|
{
|
|
var result = new int[m_SelectedIndices.Count];
|
|
int i = 0;
|
|
foreach (int index in m_SelectedIndices)
|
|
{
|
|
result[i++] = index;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>Event fired when selection changes</summary>
|
|
public event System.Action<int[]> selectionChanged;
|
|
|
|
/// <summary>Event fired when toggle state changes</summary>
|
|
public event System.Action<bool> toggleChanged;
|
|
|
|
/// <summary>Constructor</summary>
|
|
public ToggleDropdown()
|
|
{
|
|
styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(k_StylesheetPathFormat));
|
|
AddToClassList(k_MainClass);
|
|
|
|
RegisterCallback<AttachToPanelEvent>(DelayedInit);
|
|
|
|
m_ToggleButton = new Button(OnToggleClicked);
|
|
m_ToggleButton.AddToClassList(k_ToggleButtonClass);
|
|
Add(m_ToggleButton);
|
|
|
|
m_DropdownButton = new Button(ShowCustomDropdown);
|
|
m_DropdownButton.AddToClassList(k_DropdownButtonClass);
|
|
|
|
m_DropdownArrow = new VisualElement();
|
|
m_DropdownArrow.AddToClassList("unity-toolbar-menu__arrow");
|
|
m_DropdownButton.Add(m_DropdownArrow);
|
|
|
|
m_Separator = new VisualElement();
|
|
m_Separator.AddToClassList(k_SeparatorClass);
|
|
Add(m_Separator);
|
|
|
|
Add(m_DropdownButton);
|
|
}
|
|
|
|
void DelayedInit(AttachToPanelEvent evt)
|
|
{
|
|
if (!string.IsNullOrEmpty(options))
|
|
{
|
|
var optionArray = options.Split(',');
|
|
for (int i = 0; i < optionArray.Length; i++)
|
|
{
|
|
optionArray[i] = optionArray[i].Trim();
|
|
}
|
|
SetOptions(optionArray);
|
|
}
|
|
|
|
if (selectedIndex >= 0)
|
|
{
|
|
m_SelectedIndices.Add(selectedIndex);
|
|
}
|
|
|
|
m_IsEnabled = value;
|
|
m_ToggleButton.text = m_Text;
|
|
UpdateEnabledState();
|
|
}
|
|
|
|
/// <summary>Set the available options for the dropdown</summary>
|
|
public void SetOptions(string[] newOptions)
|
|
{
|
|
m_Options.Clear();
|
|
if (newOptions != null)
|
|
m_Options.AddRange(newOptions);
|
|
|
|
if (m_SelectedIndex >= m_Options.Count)
|
|
m_SelectedIndex = 0;
|
|
}
|
|
|
|
/// <summary>Set the selected indices for multi-select</summary>
|
|
public void SetSelectedIndices(int[] indices)
|
|
{
|
|
m_SelectedIndices.Clear();
|
|
if (indices != null)
|
|
{
|
|
foreach (int index in indices)
|
|
{
|
|
if (index >= 0 && index < m_Options.Count)
|
|
{
|
|
m_SelectedIndices.Add(index);
|
|
}
|
|
}
|
|
}
|
|
selectionChanged?.Invoke(GetSelectedIndices());
|
|
}
|
|
|
|
/// <summary>Toggle selection of a specific index</summary>
|
|
public void ToggleSelection(int index)
|
|
{
|
|
if (index >= 0 && index < m_Options.Count)
|
|
{
|
|
if (m_SelectedIndices.Contains(index))
|
|
{
|
|
m_SelectedIndices.Remove(index);
|
|
}
|
|
else
|
|
{
|
|
m_SelectedIndices.Add(index);
|
|
}
|
|
selectionChanged?.Invoke(GetSelectedIndices());
|
|
}
|
|
}
|
|
|
|
/// <summary>Check if an index is selected</summary>
|
|
public bool IsSelected(int index)
|
|
{
|
|
return m_SelectedIndices.Contains(index);
|
|
}
|
|
|
|
/// <summary>Set the enabled state</summary>
|
|
public new void SetEnabled(bool enabled)
|
|
{
|
|
if (enabled != m_IsEnabled)
|
|
{
|
|
m_IsEnabled = enabled;
|
|
UpdateEnabledState();
|
|
toggleChanged?.Invoke(enabled);
|
|
}
|
|
}
|
|
|
|
void OnToggleClicked()
|
|
{
|
|
SetEnabled(!m_IsEnabled);
|
|
}
|
|
|
|
void UpdateEnabledState()
|
|
{
|
|
if (m_IsEnabled)
|
|
{
|
|
AddToClassList(k_EnabledClass);
|
|
}
|
|
else
|
|
{
|
|
RemoveFromClassList(k_EnabledClass);
|
|
}
|
|
|
|
MarkDirtyRepaint();
|
|
}
|
|
|
|
void ShowCustomDropdown()
|
|
{
|
|
var menu = new GenericMenu();
|
|
|
|
for (int i = 0; i < m_Options.Count; i++)
|
|
{
|
|
int index = i;
|
|
string optionName = m_Options[i];
|
|
bool isSelected = m_SelectedIndices.Contains(index);
|
|
|
|
menu.AddItem(new GUIContent(optionName), isSelected, () => {
|
|
ToggleSelection(index);
|
|
});
|
|
}
|
|
|
|
var rect = this.worldBound;
|
|
menu.DropDown(rect);
|
|
}
|
|
}
|
|
}
|