224 lines
8.1 KiB
C#
224 lines
8.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEditor.AddressableAssets.Settings;
|
|
using UnityEditor.IMGUI.Controls;
|
|
using UnityEngine;
|
|
using UnityEngine.TestTools;
|
|
|
|
namespace UnityEditor.AddressableAssets.GUI
|
|
{
|
|
[InitializeOnLoad, ExcludeFromCoverage]
|
|
class GroupsPopupWindow : EditorWindow
|
|
{
|
|
private AddressableAssetSettings m_Settings;
|
|
private List<AddressableAssetEntry> m_Entries;
|
|
private bool m_SetInitialSelection;
|
|
private bool m_StayOpenAfterSelection;
|
|
private Action<AddressableAssetSettings, List<AddressableAssetEntry>, AddressableAssetGroup> m_Action;
|
|
|
|
private GroupsPopupTreeView m_Tree;
|
|
private TreeViewState m_TreeState;
|
|
private SearchField m_SearchField;
|
|
private string m_CurrentName = string.Empty;
|
|
private Texture2D m_FolderTexture;
|
|
|
|
private bool m_ShouldClose;
|
|
private void ForceClose()
|
|
{
|
|
m_ShouldClose = true;
|
|
}
|
|
|
|
public void Initialize(AddressableAssetSettings settings, List<AddressableAssetEntry> entries, bool setInitialSelection, bool stayOpenAfterSelection,
|
|
Vector2 mouseLocation, Action<AddressableAssetSettings, List<AddressableAssetEntry>, AddressableAssetGroup> action)
|
|
{
|
|
m_Settings = settings;
|
|
m_Entries = entries;
|
|
m_SetInitialSelection = setInitialSelection;
|
|
m_StayOpenAfterSelection = stayOpenAfterSelection;
|
|
|
|
Rect rect = position;
|
|
mouseLocation = GUIUtility.GUIToScreenPoint(mouseLocation);
|
|
rect.position = mouseLocation;
|
|
position = rect;
|
|
|
|
m_Action = action;
|
|
|
|
m_SearchField = new SearchField();
|
|
m_SearchField.SetFocus();
|
|
m_SearchField.downOrUpArrowKeyPressed += () => { m_Tree.SetFocus(); };
|
|
|
|
if (m_Tree != null && m_SetInitialSelection)
|
|
m_Tree.SetInitialSelection(m_Entries[0].parentGroup.Name);
|
|
|
|
m_FolderTexture = EditorGUIUtility.IconContent("Folder Icon").image as Texture2D;
|
|
|
|
m_ShouldClose = false;
|
|
}
|
|
|
|
private void OnLostFocus()
|
|
{
|
|
ForceClose();
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
Rect rect = position;
|
|
|
|
int border = 4;
|
|
int topPadding = 2;
|
|
int searchHeight = 20;
|
|
var searchRect = new Rect(border, topPadding, rect.width - border * 2, searchHeight);
|
|
var remainTop = topPadding + searchHeight + border;
|
|
var remainingRect = new Rect(border, topPadding + searchHeight + border, rect.width - border * 2, rect.height - remainTop - border);
|
|
|
|
if (m_Tree == null || m_Entries == null)
|
|
{
|
|
if (m_TreeState == null)
|
|
m_TreeState = new TreeViewState();
|
|
m_Tree = new GroupsPopupTreeView(m_TreeState, this);
|
|
m_Tree.Reload();
|
|
|
|
if (m_Entries != null && m_SetInitialSelection)
|
|
m_Tree.SetInitialSelection(m_Entries[0].parentGroup.Name);
|
|
}
|
|
|
|
bool isKeyPressed = Event.current.type == EventType.KeyDown && Event.current.isKey;
|
|
bool isEnterKeyPressed = isKeyPressed && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return);
|
|
bool isUpOrDownArrowPressed = isKeyPressed && (Event.current.keyCode == KeyCode.UpArrow || Event.current.keyCode == KeyCode.DownArrow);
|
|
|
|
if (isUpOrDownArrowPressed)
|
|
m_Tree.SetFocus();
|
|
|
|
m_CurrentName = m_SearchField.OnGUI(searchRect, m_CurrentName);
|
|
m_Tree.searchString = m_CurrentName;
|
|
m_Tree.IsEnterKeyPressed = isEnterKeyPressed;
|
|
m_Tree.OnGUI(remainingRect);
|
|
|
|
if (m_ShouldClose || isEnterKeyPressed)
|
|
{
|
|
GUIUtility.hotControl = 0;
|
|
Close();
|
|
}
|
|
}
|
|
|
|
internal class GroupsPopupTreeItem : TreeViewItem
|
|
{
|
|
internal AddressableAssetGroup m_Group;
|
|
|
|
public GroupsPopupTreeItem(int id, int depth, string displayName, AddressableAssetGroup group, Texture2D folderTexture)
|
|
: base(id, depth, displayName)
|
|
{
|
|
m_Group = group;
|
|
icon = folderTexture;
|
|
}
|
|
}
|
|
|
|
internal class GroupsPopupTreeView : TreeView
|
|
{
|
|
internal GroupsPopupWindow m_Popup;
|
|
|
|
internal bool IsEnterKeyPressed { get; set; }
|
|
|
|
public GroupsPopupTreeView(TreeViewState state, GroupsPopupWindow popup)
|
|
: base(state)
|
|
{
|
|
m_Popup = popup;
|
|
#if UNITY_2022_1_OR_NEWER
|
|
enableItemHovering = true;
|
|
#endif
|
|
}
|
|
|
|
public override void OnGUI(Rect rect)
|
|
{
|
|
base.OnGUI(rect);
|
|
if (IsEnterKeyPressed && HasFocus())
|
|
{
|
|
m_Popup.ForceClose();
|
|
}
|
|
}
|
|
|
|
protected override void DoubleClickedItem(int id)
|
|
{
|
|
var groupTreeItem = FindItem(id, rootItem) as GroupsPopupTreeItem;
|
|
if (groupTreeItem != null)
|
|
{
|
|
m_Popup.m_Action(m_Popup.m_Settings, m_Popup.m_Entries, groupTreeItem.m_Group);
|
|
}
|
|
m_Popup.ForceClose();
|
|
}
|
|
|
|
internal void SetInitialSelection(string assetString)
|
|
{
|
|
foreach (var child in rootItem.children)
|
|
{
|
|
if (child.displayName.IndexOf(assetString, StringComparison.OrdinalIgnoreCase) >= 0)
|
|
{
|
|
SetSelection(new List<int> { child.id });
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void SelectionChanged(IList<int> selectedIds)
|
|
{
|
|
if (selectedIds != null && selectedIds.Count == 1)
|
|
{
|
|
var groupTreeItem = FindItem(selectedIds[0], rootItem) as GroupsPopupTreeItem;
|
|
if (groupTreeItem != null)
|
|
{
|
|
m_Popup.m_Action(m_Popup.m_Settings, m_Popup.m_Entries, groupTreeItem.m_Group);
|
|
}
|
|
if (m_Popup.m_StayOpenAfterSelection)
|
|
SetFocus();
|
|
else
|
|
m_Popup.ForceClose();
|
|
}
|
|
}
|
|
|
|
protected override bool CanMultiSelect(TreeViewItem item)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
|
|
{
|
|
if (string.IsNullOrEmpty(searchString))
|
|
{
|
|
return base.BuildRows(root);
|
|
}
|
|
|
|
List<TreeViewItem> rows = new List<TreeViewItem>();
|
|
foreach (var child in rootItem.children)
|
|
{
|
|
if (child.displayName.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
|
|
rows.Add(child);
|
|
}
|
|
return rows;
|
|
}
|
|
|
|
protected override TreeViewItem BuildRoot()
|
|
{
|
|
var root = new TreeViewItem(-1, -1);
|
|
|
|
var aaSettings = AddressableAssetSettingsDefaultObject.Settings;
|
|
if (aaSettings == null)
|
|
{
|
|
var message = "Use 'Window->Addressables' to initialize.";
|
|
root.AddChild(new GroupsPopupTreeItem(message.GetHashCode(), 0, message, null, m_Popup.m_FolderTexture));
|
|
}
|
|
else
|
|
{
|
|
foreach (AddressableAssetGroup group in aaSettings.groups)
|
|
{
|
|
if (!group.ReadOnly)
|
|
{
|
|
var child = new GroupsPopupTreeItem(group.Guid.GetHashCode(), 0, group.name, group, m_Popup.m_FolderTexture);
|
|
root.AddChild(child);
|
|
}
|
|
}
|
|
}
|
|
return root;
|
|
}
|
|
}
|
|
}
|
|
}
|