modify
This commit is contained in:
parent
f432ee445b
commit
19135d607a
@ -22,6 +22,16 @@ public static class AppBuildHelper
|
||||
|
||||
Debug.Log("Generate AppBuilderSetting.bytes");
|
||||
|
||||
PlayerSettings.fullScreenMode = appBuildParameter.FullScreenMode;
|
||||
if (appBuildParameter.FullScreenMode == FullScreenMode.Windowed)
|
||||
{
|
||||
PlayerSettings.defaultScreenWidth = appBuildParameter.WindowedScreenSize.x;
|
||||
PlayerSettings.defaultScreenHeight = appBuildParameter.WindowedScreenSize.y;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(appBuildParameter.Version))
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using AlicizaX;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using YooAsset;
|
||||
using YooAsset.Editor;
|
||||
@ -16,6 +17,21 @@ public class AppBuildParameter
|
||||
public string FileName;
|
||||
public Language Language;
|
||||
public string[] Scenes;
|
||||
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public string Version;
|
||||
|
||||
/// <summary>
|
||||
/// 是否全屏
|
||||
/// </summary>
|
||||
public FullScreenMode FullScreenMode;
|
||||
|
||||
/// <summary>
|
||||
/// 窗口化大小
|
||||
/// </summary>
|
||||
public Vector2Int WindowedScreenSize;
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@ using System.IO;
|
||||
|
||||
public class EditorIcons : EditorWindow
|
||||
{
|
||||
[MenuItem("Tools/Editor Icons %e", priority = -1001)]
|
||||
[MenuItem("Tools/EditorExtension/Editor Icons %e", priority = -1001)]
|
||||
public static void EditorIconsOpen()
|
||||
{
|
||||
#if UNITY_2018
|
||||
@ -236,7 +236,8 @@ public class EditorIcons : EditorWindow
|
||||
|
||||
List<GUIContent> iconList;
|
||||
|
||||
if (doSearch) iconList = iconContentListAll.Where(x => x.tooltip.ToLower()
|
||||
if (doSearch)
|
||||
iconList = iconContentListAll.Where(x => x.tooltip.ToLower()
|
||||
.Contains(search.ToLower())).ToList();
|
||||
else iconList = viewBigIcons ? iconContentListBig : iconContentListSmall;
|
||||
|
||||
@ -321,7 +322,6 @@ public class EditorIcons : EditorWindow
|
||||
{
|
||||
iconSelected = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93fb9d2834752b649891dba19cba5169
|
||||
guid: fb7e9c820d4ba2b4d836ffc849b55067
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
8
Editor/ToolBarExtension.meta
Normal file
8
Editor/ToolBarExtension.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93fb9d2834752b649891dba19cba5169
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
69
Editor/ToolBarExtension/LocalizationDropdownField.cs
Normal file
69
Editor/ToolBarExtension/LocalizationDropdownField.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using AlicizaX.Localization.Runtime;
|
||||
using AlicizaX;
|
||||
using Paps.UnityToolbarExtenderUIToolkit;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
[MainToolbarElement("LocalizationDropdownField", alignment: ToolbarAlign.Right, order: 0)]
|
||||
public class LocalizationDropdownField : IMGUIContainer
|
||||
{
|
||||
private static GUIContent appConfigBtContent;
|
||||
|
||||
private static string[] _languageTypeNames;
|
||||
|
||||
public void InitializeElement()
|
||||
{
|
||||
var nameArray = Enum.GetNames(typeof(Language));
|
||||
_languageTypeNames = new string[nameArray.Length - 1];
|
||||
for (int i = 1; i < nameArray.Length; i++)
|
||||
{
|
||||
var name = nameArray[i];
|
||||
_languageTypeNames[i - 1] = name;
|
||||
}
|
||||
|
||||
appConfigBtContent =
|
||||
EditorGUIUtility.TrTextContentWithIcon("", "",
|
||||
"Settings");
|
||||
onGUIHandler = MyGUIMethod;
|
||||
}
|
||||
|
||||
private void MyGUIMethod()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
string title = _languageTypeNames[GetPrefsIndex()];
|
||||
appConfigBtContent.text = title;
|
||||
if (EditorGUILayout.DropdownButton(appConfigBtContent, FocusType.Passive, EditorStyles.toolbarPopup, GUILayout.MaxWidth(120)))
|
||||
{
|
||||
DrawEditorToolDropdownMenus();
|
||||
}
|
||||
|
||||
GUILayout.Space(5);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
static void DrawEditorToolDropdownMenus()
|
||||
{
|
||||
int index = GetPrefsIndex();
|
||||
GenericMenu popMenu = new GenericMenu();
|
||||
for (int i = 0; i < _languageTypeNames.Length; i++)
|
||||
{
|
||||
var selected = index == i;
|
||||
var toolAttr = _languageTypeNames[i];
|
||||
popMenu.AddItem(new GUIContent(toolAttr), selected, menuIdx => { ClickToolsSubmenu((int)menuIdx); }, i);
|
||||
}
|
||||
|
||||
popMenu.ShowAsContext();
|
||||
}
|
||||
|
||||
static void ClickToolsSubmenu(int menuIdx)
|
||||
{
|
||||
EditorPrefs.SetInt(LocalizationComponent.PrefsKey, menuIdx + 1);
|
||||
}
|
||||
|
||||
static int GetPrefsIndex()
|
||||
{
|
||||
return EditorPrefs.GetInt(LocalizationComponent.PrefsKey, 1) - 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2295b86f78274a84a63dc65ab4a69cb1
|
||||
timeCreated: 1742364662
|
@ -23,9 +23,7 @@ namespace AlicizaX.Editor.Extension
|
||||
|
||||
public void InitializeElement()
|
||||
{
|
||||
appConfigBtContent =
|
||||
EditorGUIUtility.TrTextContentWithIcon("Res:", "配置App运行时所需DataTable/Config/Procedure",
|
||||
"Settings");
|
||||
appConfigBtContent = EditorGUIUtility.TrTextContentWithIcon("Res:", "配置App运行时资源模式", "Settings");
|
||||
onGUIHandler = MyGUIMethod;
|
||||
}
|
||||
|
40
Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs
Normal file
40
Editor/Toolbar/ByAttributeMainToolbarElementRepository.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class ByAttributeMainToolbarElementRepository : IMainToolbarElementRepository
|
||||
{
|
||||
public MainToolbarElement[] GetAll()
|
||||
{
|
||||
return TypeCache.GetTypesWithAttribute<MainToolbarElementAttribute>()
|
||||
.Where(type => IsValidVisualElementType(type))
|
||||
.Select(type => GetMainToolbarElementFromType(type))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private MainToolbarElement GetMainToolbarElementFromType(Type type)
|
||||
{
|
||||
var elementInstance = (VisualElement)Activator.CreateInstance(type);
|
||||
var attribute = type.GetCustomAttribute<MainToolbarElementAttribute>();
|
||||
|
||||
if (string.IsNullOrEmpty(elementInstance.name))
|
||||
elementInstance.name = elementInstance.GetType().Name;
|
||||
|
||||
return new MainToolbarElement(attribute.Id, elementInstance, attribute.Alignment,
|
||||
attribute.Order, attribute.UseRecommendedStyles);
|
||||
}
|
||||
|
||||
private bool IsValidVisualElementType(Type type)
|
||||
{
|
||||
var visualElementType = typeof(VisualElement);
|
||||
|
||||
return visualElementType != type &&
|
||||
visualElementType.IsAssignableFrom(type) &&
|
||||
!type.IsAbstract;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e664729ffc0507499365cb1b3393b91
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Toolbar/ControlPanelWindow.meta
Normal file
8
Editor/Toolbar/ControlPanelWindow.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5d6770a557fcef47bfab9c1562f972c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,207 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
public class MainToolbarControlPanelWindow : EditorWindow
|
||||
{
|
||||
private const string NATIVE_ELEMENTS_CONTAINER_NAME = "UnityNativeElementsContainer";
|
||||
private const string NATIVE_ELEMENTS_FOLDOUT_TEXT = "Unity Native Elements";
|
||||
|
||||
private const string SINGLE_ELEMENTS_CONTAINER_NAME = "SingleElementsContainer";
|
||||
private const string SINGLE_ELEMENTS_FOLDOUT_TEXT = "Single Elements";
|
||||
|
||||
private const string GROUP_ELEMENTS_CONTAINER_NAME = "GroupElementsContainer";
|
||||
private const string GROUP_ELEMENTS_FOLDOUT_TEXT = "Groups";
|
||||
|
||||
private const float MAIN_CONTAINER_PADDING_TOP = 5;
|
||||
|
||||
private OrganizationalFoldableContainer _nativeElementsContainer;
|
||||
private OrganizationalFoldableContainer _singleElementsContainer;
|
||||
private OrganizationalFoldableContainer _groupElementsContainer;
|
||||
private MainToolbarElementController[] _controllers;
|
||||
|
||||
private Button _resetOverridesButton;
|
||||
|
||||
private VisualElement _noElementsMessageElement;
|
||||
private VisualElement _windowContainer;
|
||||
|
||||
public static void OpenWindow()
|
||||
{
|
||||
var window = GetWindow<MainToolbarControlPanelWindow>();
|
||||
|
||||
window.titleContent = new GUIContent("Main Toolbar Control Panel");
|
||||
}
|
||||
|
||||
private void CreateGUI()
|
||||
{
|
||||
MainToolbarAutomaticExtender.OnAddedCustomContainersToToolbar += Refresh;
|
||||
MainToolbarAutomaticExtender.OnRefresh += Refresh;
|
||||
|
||||
BuildFixedGUI();
|
||||
SetDefaultView();
|
||||
|
||||
if (MainToolbar.IsAvailable)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
MainToolbarAutomaticExtender.OnAddedCustomContainersToToolbar -= Refresh;
|
||||
MainToolbarAutomaticExtender.OnRefresh -= Refresh;
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
BuildDynamicGUI();
|
||||
SetCorrespondingView();
|
||||
}
|
||||
|
||||
private void BuildFixedGUI()
|
||||
{
|
||||
_windowContainer = GetContainer();
|
||||
|
||||
_resetOverridesButton = new Button(GlobalActions.ResetOverridesIfUserAccepts);
|
||||
_resetOverridesButton.text = "Reset Overrides";
|
||||
|
||||
_singleElementsContainer = new OrganizationalFoldableContainer(
|
||||
SINGLE_ELEMENTS_CONTAINER_NAME, SINGLE_ELEMENTS_FOLDOUT_TEXT);
|
||||
_groupElementsContainer = new OrganizationalFoldableContainer(
|
||||
GROUP_ELEMENTS_CONTAINER_NAME, GROUP_ELEMENTS_FOLDOUT_TEXT);
|
||||
_nativeElementsContainer = new OrganizationalFoldableContainer(
|
||||
NATIVE_ELEMENTS_CONTAINER_NAME, NATIVE_ELEMENTS_FOLDOUT_TEXT);
|
||||
|
||||
_noElementsMessageElement = CreateNoElementsMessageElement();
|
||||
|
||||
rootVisualElement.Add(_resetOverridesButton);
|
||||
rootVisualElement.Add(_windowContainer);
|
||||
}
|
||||
|
||||
private void SetDefaultView()
|
||||
{
|
||||
_windowContainer.Add(_noElementsMessageElement);
|
||||
}
|
||||
|
||||
private void SetCorrespondingView()
|
||||
{
|
||||
if(_controllers.Length > 0)
|
||||
{
|
||||
if(_windowContainer.Contains(_noElementsMessageElement))
|
||||
_windowContainer.Remove(_noElementsMessageElement);
|
||||
|
||||
if (!_windowContainer.Contains(_singleElementsContainer))
|
||||
{
|
||||
_windowContainer.Add(_singleElementsContainer);
|
||||
_windowContainer.Add(_groupElementsContainer);
|
||||
_windowContainer.Add(_nativeElementsContainer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_windowContainer.Contains(_singleElementsContainer))
|
||||
{
|
||||
_windowContainer.Remove(_singleElementsContainer);
|
||||
_windowContainer.Remove(_groupElementsContainer);
|
||||
_windowContainer.Remove(_nativeElementsContainer);
|
||||
}
|
||||
|
||||
if (!_windowContainer.Contains(_noElementsMessageElement))
|
||||
_windowContainer.Add(_noElementsMessageElement);
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildDynamicGUI()
|
||||
{
|
||||
_controllers = CreateControllers();
|
||||
|
||||
var controllersOfNativeElements = _controllers
|
||||
.Where(controller => controller.HoldsANativeElement);
|
||||
var controllersOfGroups = _controllers
|
||||
.Where(controller => controller.HoldsAGroup);
|
||||
var controllersOfSingleElements = _controllers
|
||||
.Where(controller => !controller.HoldsAGroup && !controller.HoldsANativeElement)
|
||||
.Where(controller => SingleControllerIsNotInsideAGroupController(controller, controllersOfGroups));
|
||||
|
||||
_singleElementsContainer.SetControllers(controllersOfSingleElements);
|
||||
_groupElementsContainer.SetControllers(controllersOfGroups);
|
||||
_nativeElementsContainer.SetControllers(controllersOfNativeElements);
|
||||
}
|
||||
|
||||
private static bool SingleControllerIsNotInsideAGroupController(MainToolbarElementController controller, IEnumerable<MainToolbarElementController> controllersOfGroups)
|
||||
{
|
||||
foreach (var groupController in controllersOfGroups)
|
||||
if (groupController.ContainsSubController(controller.Id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private VisualElement GetContainer()
|
||||
{
|
||||
var scrollView = new ScrollView(ScrollViewMode.Vertical);
|
||||
|
||||
scrollView.style.paddingTop = MAIN_CONTAINER_PADDING_TOP;
|
||||
|
||||
return scrollView;
|
||||
}
|
||||
|
||||
private MainToolbarElementController[] CreateControllers()
|
||||
{
|
||||
return GetOverridableElements()
|
||||
.OrderBy(overridableElement => overridableElement.Id)
|
||||
.Select(overridableElement => new MainToolbarElementController(
|
||||
overridableElement,
|
||||
ServicesAndRepositories.MainToolbarElementOverridesRepository,
|
||||
GetSubElementsIfAny(overridableElement))
|
||||
)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private OverridableElement[] GetSubElementsIfAny(OverridableElement overridableElement)
|
||||
{
|
||||
if(overridableElement.VisualElement is GroupElement)
|
||||
{
|
||||
return MainToolbarAutomaticExtender.GetElementsOfGroup(overridableElement.Id)
|
||||
.Select(el => new OverridableElement(
|
||||
el.Id,
|
||||
el.VisualElement,
|
||||
false)
|
||||
)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return new OverridableElement[0];
|
||||
}
|
||||
|
||||
private OverridableElement[] GetOverridableElements()
|
||||
{
|
||||
var nativeElements = MainToolbarAutomaticExtender.NativeElements
|
||||
.Select(nativeElement => new OverridableElement(
|
||||
nativeElement.Id,
|
||||
nativeElement.VisualElement,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
var customElements = MainToolbarAutomaticExtender.CustomMainToolbarElements
|
||||
.Concat(MainToolbarAutomaticExtender.GroupElements)
|
||||
.Select(mainToolbarElement => new OverridableElement(
|
||||
mainToolbarElement.Id,
|
||||
mainToolbarElement.VisualElement,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
return nativeElements.Concat(customElements)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private VisualElement CreateNoElementsMessageElement()
|
||||
{
|
||||
return new HelpBox("No main toolbar elements were found. To use the automatic toolbar extender define a main toolbar element. See the docs.", HelpBoxMessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fef14479cdf8f5a41bb3b7f4b442484e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,187 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class MainToolbarElementController : VisualElement
|
||||
{
|
||||
private const string FOLDOUT_STATE_SAVE_KEY_BASE = "main-toolbar-element-controller:foldout-state:";
|
||||
private const float LEFT_PADDING_SINGLE = 19;
|
||||
private const float RIGHT_PADDING = 10;
|
||||
|
||||
private readonly IMainToolbarElementOverrideRepository _overridesRepository;
|
||||
private Label _label;
|
||||
private Button _button;
|
||||
private Image _buttonIconImage;
|
||||
private Foldout _foldout;
|
||||
|
||||
private StyleColor _defaultButtonColor;
|
||||
private List<MainToolbarElementController> _subControllers = new List<MainToolbarElementController>();
|
||||
|
||||
public string Id { get; }
|
||||
public VisualElement ControlledVisualElement { get; }
|
||||
public bool HoldsAGroup => _foldout != null;
|
||||
public bool HoldsANativeElement { get; private set; }
|
||||
|
||||
public MainToolbarElementController(OverridableElement overridableElement,
|
||||
IMainToolbarElementOverrideRepository overridesRepository, params OverridableElement[] subElements)
|
||||
{
|
||||
Id = overridableElement.Id;
|
||||
ControlledVisualElement = overridableElement.VisualElement;
|
||||
HoldsANativeElement = overridableElement.IsNative;
|
||||
name = Id + "-Controller";
|
||||
_overridesRepository = overridesRepository;
|
||||
|
||||
_buttonIconImage = new Image();
|
||||
|
||||
style.flexDirection = FlexDirection.Row;
|
||||
style.justifyContent = Justify.SpaceBetween;
|
||||
style.paddingRight = RIGHT_PADDING;
|
||||
|
||||
_label = CreateLabel();
|
||||
_button = CreateButton();
|
||||
|
||||
_defaultButtonColor = _button.style.backgroundColor;
|
||||
|
||||
UpdateButtonStatus(VisibleValueOrDefault());
|
||||
BuildAsGroupOrSingle(subElements);
|
||||
}
|
||||
|
||||
private string GetFullFoldoutStateSaveKey() => FOLDOUT_STATE_SAVE_KEY_BASE + Id;
|
||||
|
||||
private void SaveFoldoutState(ChangeEvent<bool> eventArgs)
|
||||
{
|
||||
UserSettingsPrefs.SetBool(GetFullFoldoutStateSaveKey(), eventArgs.newValue);
|
||||
}
|
||||
|
||||
private bool GetSavedFoldoutState()
|
||||
{
|
||||
return UserSettingsPrefs.GetBool(GetFullFoldoutStateSaveKey(), false);
|
||||
}
|
||||
|
||||
public bool ContainsSubController(string id)
|
||||
{
|
||||
return _subControllers.Any(controller => controller.Id == id);
|
||||
}
|
||||
|
||||
private void BuildAsGroupOrSingle(OverridableElement[] subElements)
|
||||
{
|
||||
if (subElements.Length > 0)
|
||||
BuildFoldout(subElements);
|
||||
else
|
||||
BuildSingleElement();
|
||||
}
|
||||
|
||||
private void BuildSingleElement()
|
||||
{
|
||||
style.paddingLeft = LEFT_PADDING_SINGLE;
|
||||
|
||||
Add(_label);
|
||||
Add(_button);
|
||||
}
|
||||
|
||||
private void BuildFoldout(OverridableElement[] subElements)
|
||||
{
|
||||
_foldout = new Foldout() { text = _label.text };
|
||||
|
||||
foreach (var overridable in subElements)
|
||||
{
|
||||
var subController = new MainToolbarElementController(overridable, _overridesRepository);
|
||||
|
||||
_subControllers.Add(subController);
|
||||
|
||||
_foldout.Add(subController);
|
||||
}
|
||||
|
||||
_foldout.value = GetSavedFoldoutState();
|
||||
_foldout.RegisterCallback<ChangeEvent<bool>>(SaveFoldoutState);
|
||||
_foldout.style.flexGrow = 1;
|
||||
|
||||
Add(_foldout);
|
||||
Add(_button);
|
||||
}
|
||||
|
||||
private bool VisibleValueOrDefault()
|
||||
{
|
||||
var possibleOverride = _overridesRepository.Get(Id);
|
||||
|
||||
if (possibleOverride == null)
|
||||
return CurrentDisplayValueAsBool();
|
||||
|
||||
var overrideValue = possibleOverride.Value;
|
||||
|
||||
return overrideValue.Visible;
|
||||
}
|
||||
|
||||
private Label CreateLabel()
|
||||
{
|
||||
var label = new Label(Id);
|
||||
|
||||
label.style.alignSelf = Align.Center;
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
private Button CreateButton()
|
||||
{
|
||||
var button = new Button(ChangeVisibilityValue);
|
||||
|
||||
button.Add(_buttonIconImage);
|
||||
|
||||
button.tooltip = "Change the visibility of element with id " + Id;
|
||||
|
||||
button.style.alignSelf = Align.FlexStart;
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private Texture IconByVisibilityValue(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
return Icons.VisibilityOnOverrideIcon;
|
||||
|
||||
return Icons.VisibilityOffOverrideIcon;
|
||||
}
|
||||
|
||||
private void ChangeVisibilityValue()
|
||||
{
|
||||
var currentOverrideValue = _overridesRepository.Get(Id);
|
||||
|
||||
bool newValue;
|
||||
|
||||
if (currentOverrideValue == null)
|
||||
newValue = !CurrentDisplayValueAsBool();
|
||||
else
|
||||
newValue = !currentOverrideValue.Value.Visible;
|
||||
|
||||
_overridesRepository.Save(new MainToolbarElementOverride(Id, newValue));
|
||||
UpdateButtonStatus(newValue);
|
||||
|
||||
MainToolbarAutomaticExtender.Refresh();
|
||||
}
|
||||
|
||||
private bool CurrentDisplayValueAsBool()
|
||||
{
|
||||
if (ControlledVisualElement.style.display == DisplayStyle.None)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateButtonStatus(bool visible)
|
||||
{
|
||||
_buttonIconImage.image = IconByVisibilityValue(visible);
|
||||
_button.style.backgroundColor = GetButtonColor(visible);
|
||||
}
|
||||
|
||||
private StyleColor GetButtonColor(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
return _defaultButtonColor;
|
||||
else
|
||||
return new StyleColor(Color.black);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae80166256b03484a9bfc1ad9c4cc0dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class OrganizationalFoldableContainer : Box
|
||||
{
|
||||
private static readonly Color ORGANIZATIONAL_FOLDABLE_CONTAINER_BORDER_COLOR = new Color(153f / 255f, 153f / 255f, 153f / 255f);
|
||||
private const string FOLDOUT_STATE_SAVE_KEY_BASE = "organizational-foldable-container:foldout-state:";
|
||||
|
||||
private Foldout _foldout;
|
||||
private string _id;
|
||||
|
||||
public OrganizationalFoldableContainer(string containerId, string foldoutText)
|
||||
{
|
||||
_id = containerId;
|
||||
name = containerId;
|
||||
style.borderTopColor = ORGANIZATIONAL_FOLDABLE_CONTAINER_BORDER_COLOR;
|
||||
style.borderTopWidth = 1;
|
||||
|
||||
_foldout = new Foldout() { text = foldoutText };
|
||||
_foldout.value = GetSavedFoldoutState();
|
||||
_foldout.RegisterCallback<ChangeEvent<bool>>(SaveFoldoutState);
|
||||
|
||||
Add(_foldout);
|
||||
}
|
||||
|
||||
private string GetFullFoldoutStateSaveKey() => FOLDOUT_STATE_SAVE_KEY_BASE + _id;
|
||||
|
||||
private void SaveFoldoutState(ChangeEvent<bool> eventArgs)
|
||||
{
|
||||
UserSettingsPrefs.SetBool(GetFullFoldoutStateSaveKey(), eventArgs.newValue);
|
||||
}
|
||||
|
||||
private bool GetSavedFoldoutState()
|
||||
{
|
||||
return UserSettingsPrefs.GetBool(GetFullFoldoutStateSaveKey(), false);
|
||||
}
|
||||
|
||||
public void SetControllers(IEnumerable<MainToolbarElementController> controllers)
|
||||
{
|
||||
_foldout.Clear();
|
||||
|
||||
foreach (var controller in controllers)
|
||||
{
|
||||
_foldout.Add(controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ac00cb9059df7e43b1c2ed433ce61cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Editor/Toolbar/ControlPanelWindow/OverridableElement.cs
Normal file
18
Editor/Toolbar/ControlPanelWindow/OverridableElement.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal readonly struct OverridableElement
|
||||
{
|
||||
public string Id { get; }
|
||||
public VisualElement VisualElement { get; }
|
||||
public bool IsNative { get; }
|
||||
|
||||
public OverridableElement(string id, VisualElement visualElement, bool isNative)
|
||||
{
|
||||
Id = id;
|
||||
VisualElement = visualElement;
|
||||
IsNative = isNative;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/ControlPanelWindow/OverridableElement.cs.meta
Normal file
11
Editor/Toolbar/ControlPanelWindow/OverridableElement.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 542f1fb68120090489ba1613162eb17b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Toolbar/Extensions.meta
Normal file
8
Editor/Toolbar/Extensions.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0a074f24b9c98d488341e6258c0c0b0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
17
Editor/Toolbar/Extensions/EditorWindowExtensions.cs
Normal file
17
Editor/Toolbar/Extensions/EditorWindowExtensions.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
public static class EditorWindowExtensions
|
||||
{
|
||||
public static void ShowAsDropdownForMainToolbar(this EditorWindow window, Rect activatorRect, Vector2 size)
|
||||
{
|
||||
window.ShowAsDropDown(activatorRect, size);
|
||||
|
||||
var rect = GUIUtility.GUIToScreenRect(activatorRect);
|
||||
rect.y += activatorRect.size.y;
|
||||
window.position = new Rect(rect.position, window.position.size);
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Extensions/EditorWindowExtensions.cs.meta
Normal file
11
Editor/Toolbar/Extensions/EditorWindowExtensions.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3333a000c60ebce4aa038ee0945d0072
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Toolbar/GroupDefinitions.meta
Normal file
8
Editor/Toolbar/GroupDefinitions.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a83afb20ef0f5f40b22a93ff124fe1f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
39
Editor/Toolbar/GroupDefinitions/GroupDefinition.cs
Normal file
39
Editor/Toolbar/GroupDefinitions/GroupDefinition.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal readonly struct GroupDefinition
|
||||
{
|
||||
public string GroupId { get; }
|
||||
public string GroupName { get; }
|
||||
public ToolbarAlign Alignment { get; }
|
||||
public int Order { get; }
|
||||
public string[] ToolbarElementsIds { get; }
|
||||
|
||||
public GroupDefinition(string groupId, string groupName, ToolbarAlign alignment, int order, string[] toolbarElementsIds)
|
||||
{
|
||||
GroupId = groupId;
|
||||
GroupName = string.IsNullOrEmpty(groupName) ? groupId : groupName;
|
||||
Alignment = alignment;
|
||||
Order = order;
|
||||
ToolbarElementsIds = toolbarElementsIds;
|
||||
}
|
||||
|
||||
public bool AreEquals(GroupDefinition other)
|
||||
{
|
||||
return GroupId == other.GroupId &&
|
||||
GroupName == other.GroupName &&
|
||||
Alignment == other.Alignment &&
|
||||
Order == other.Order &&
|
||||
AreEquals(ToolbarElementsIds, other.ToolbarElementsIds);
|
||||
}
|
||||
|
||||
private bool AreEquals(string[] types, string[] types2)
|
||||
{
|
||||
if(types.Length != types2.Length)
|
||||
return false;
|
||||
|
||||
return types.All(typeName => types2.Contains(typeName));
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/GroupDefinitions/GroupDefinition.cs.meta
Normal file
11
Editor/Toolbar/GroupDefinitions/GroupDefinition.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e3f2e82a96ef3246860b2861fa19b15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
92
Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs
Normal file
92
Editor/Toolbar/GroupDefinitions/GroupDropdownWindowPopup.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class GroupDropdownWindowPopup : EditorWindow
|
||||
{
|
||||
private VisualElement[] _groupElements;
|
||||
private ScrollView _scrollView;
|
||||
|
||||
public void Initialize(VisualElement[] groupElements)
|
||||
{
|
||||
_groupElements = groupElements;
|
||||
hideFlags = HideFlags.DontSave;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
AssemblyReloadEvents.beforeAssemblyReload += Close;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
AssemblyReloadEvents.beforeAssemblyReload -= Close;
|
||||
}
|
||||
|
||||
private void CreateGUI()
|
||||
{
|
||||
_scrollView = new ScrollView(ScrollViewMode.Vertical);
|
||||
_scrollView.contentContainer.style.alignContent = Align.Center;
|
||||
_scrollView.contentContainer.style.alignItems = Align.Center;
|
||||
_scrollView.horizontalScrollerVisibility = ScrollerVisibility.Hidden;
|
||||
|
||||
foreach (var groupElement in _groupElements)
|
||||
{
|
||||
var container = CreateGroupElementContainer();
|
||||
container.Add(groupElement);
|
||||
groupElement.style.flexWrap = Wrap.Wrap;
|
||||
container.style.display = groupElement.style.display;
|
||||
_scrollView.Add(container);
|
||||
}
|
||||
|
||||
var baseContainer = CreateBaseContainer();
|
||||
baseContainer.Add(_scrollView);
|
||||
|
||||
rootVisualElement.Add(baseContainer);
|
||||
}
|
||||
|
||||
private VisualElement CreateBaseContainer()
|
||||
{
|
||||
return new VisualElement()
|
||||
{
|
||||
style =
|
||||
{
|
||||
flexGrow = 1,
|
||||
borderBottomColor = Color.black,
|
||||
borderTopColor = Color.black,
|
||||
borderLeftColor = Color.black,
|
||||
borderRightColor = Color.black,
|
||||
borderBottomWidth = 2,
|
||||
borderTopWidth = 2,
|
||||
borderLeftWidth = 2,
|
||||
borderRightWidth = 2,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private VisualElement CreateGroupElementContainer()
|
||||
{
|
||||
return new Box()
|
||||
{
|
||||
style =
|
||||
{
|
||||
alignContent = Align.Center,
|
||||
alignItems = Align.Center,
|
||||
flexDirection = FlexDirection.Row,
|
||||
flexGrow = 1,
|
||||
width = Length.Percent(100),
|
||||
height = Length.Auto(),
|
||||
justifyContent = Justify.Center,
|
||||
borderTopColor = Color.black,
|
||||
borderTopWidth = 1,
|
||||
paddingTop = 3f,
|
||||
paddingBottom = 3f,
|
||||
paddingLeft = 8,
|
||||
paddingRight = 8,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8509c9dbf1627b74c9e521402a3de28b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using PopupWindow = UnityEditor.PopupWindow;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class GroupDropdownWindowPopupManager
|
||||
{
|
||||
private const string POPUP_WINDOW_CONTENT_FIELD_NAME = "m_WindowContent";
|
||||
private static readonly string[] SPECIAL_EDITOR_WINDOW_TYPE_NAMES =
|
||||
{
|
||||
"UnityEditor.UIElements.Debugger.UIElementsDebugger",
|
||||
"UnityEditor.UIElements.EditorMenuExtensions+ContextMenu",
|
||||
"UnityEditor.ObjectSelector",
|
||||
"UnityEditor.Search.SearchPickerWindow"
|
||||
};
|
||||
private static readonly string[] SPECIAL_POPUP_WINDOW_CONTENT_TYPE_NAMES =
|
||||
{
|
||||
"UnityEditor.UIElements.EditorGenericDropdownMenuWindowContent"
|
||||
};
|
||||
|
||||
private static FieldInfo _popupWindowContentField;
|
||||
private static Type[] _subWindowTypes = new Type[0];
|
||||
private static Type[] _specialWindowTypes = new Type[0];
|
||||
private static List<GroupDropdownWindowPopup> _windows = new List<GroupDropdownWindowPopup>();
|
||||
|
||||
static GroupDropdownWindowPopupManager()
|
||||
{
|
||||
_popupWindowContentField = typeof(PopupWindow)
|
||||
.GetField(POPUP_WINDOW_CONTENT_FIELD_NAME,
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
InitializeSpecialWindowTypes();
|
||||
LoadSubWindowTypes();
|
||||
EditorApplication.update += Update;
|
||||
}
|
||||
|
||||
private static void LoadSubWindowTypes()
|
||||
{
|
||||
_subWindowTypes = TypeCache.GetTypesWithAttribute<GroupPopupSubWindowAttribute>()
|
||||
.Where(type => IsValidSubWindowType(type))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static void InitializeSpecialWindowTypes()
|
||||
{
|
||||
var typeList = new List<Type>();
|
||||
|
||||
typeList.AddRange(TypeCache.GetTypesDerivedFrom<EditorWindow>()
|
||||
.Where(type => SPECIAL_EDITOR_WINDOW_TYPE_NAMES.Contains(type.Name) || SPECIAL_EDITOR_WINDOW_TYPE_NAMES.Contains(type.FullName)));
|
||||
|
||||
typeList.AddRange(TypeCache.GetTypesDerivedFrom<PopupWindowContent>()
|
||||
.Where(type => SPECIAL_POPUP_WINDOW_CONTENT_TYPE_NAMES.Contains(type.Name) || SPECIAL_POPUP_WINDOW_CONTENT_TYPE_NAMES.Contains(type.FullName)));
|
||||
|
||||
_specialWindowTypes = typeList.Where(t => t != null).ToArray();
|
||||
}
|
||||
|
||||
private static bool IsValidSubWindowType(Type type)
|
||||
{
|
||||
return typeof(EditorWindow).IsAssignableFrom(type) ||
|
||||
typeof(PopupWindowContent).IsAssignableFrom(type);
|
||||
}
|
||||
|
||||
private static bool ContainsValidPopupWindowContent(EditorWindow window)
|
||||
{
|
||||
if(window is PopupWindow popupWindow)
|
||||
{
|
||||
var popupContent = _popupWindowContentField.GetValue(popupWindow) as PopupWindowContent;
|
||||
|
||||
var popupContentSpecificType = popupContent.GetType();
|
||||
|
||||
return _subWindowTypes.Contains(popupContentSpecificType) || _specialWindowTypes.Contains(popupContentSpecificType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
if (_windows.Count == 0)
|
||||
return;
|
||||
|
||||
if (EditorWindow.focusedWindow == null || !FocusedWindowIsValid())
|
||||
CloseAll();
|
||||
else if(_windows.Contains(EditorWindow.focusedWindow))
|
||||
{
|
||||
var focusedWindow = EditorWindow.focusedWindow;
|
||||
|
||||
var downMostWindow = _windows.Last();
|
||||
|
||||
while(downMostWindow != focusedWindow)
|
||||
{
|
||||
_windows.Remove(downMostWindow);
|
||||
downMostWindow.Close();
|
||||
downMostWindow = _windows.Last();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CloseAll()
|
||||
{
|
||||
foreach(var window in _windows)
|
||||
{
|
||||
if(window != null)
|
||||
window.Close();
|
||||
}
|
||||
|
||||
_windows.Clear();
|
||||
}
|
||||
|
||||
private static bool FocusedWindowIsValid()
|
||||
{
|
||||
return _windows.Contains(EditorWindow.focusedWindow) ||
|
||||
_subWindowTypes.Contains(EditorWindow.focusedWindow.GetType()) ||
|
||||
_specialWindowTypes.Contains(EditorWindow.focusedWindow.GetType()) ||
|
||||
ContainsValidPopupWindowContent(EditorWindow.focusedWindow);
|
||||
}
|
||||
|
||||
public static void Show(Rect activatorRect, VisualElement[] elements)
|
||||
{
|
||||
var window = ScriptableObject.CreateInstance<GroupDropdownWindowPopup>();
|
||||
|
||||
var rect = GUIUtility.GUIToScreenRect(activatorRect);
|
||||
rect.y += activatorRect.size.y;
|
||||
window.position = new Rect(rect.position, window.position.size);
|
||||
|
||||
_windows.Add(window);
|
||||
|
||||
window.Initialize(elements);
|
||||
|
||||
#if UNITY_EDITOR_WIN
|
||||
window.ShowPopup();
|
||||
#elif UNITY_EDITOR_OSX
|
||||
window.ShowAsDropdownForMainToolbar(activatorRect, window.position.size);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88333c3cc209cb143bc93891e1664b41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
29
Editor/Toolbar/GroupDefinitions/GroupElement.cs
Normal file
29
Editor/Toolbar/GroupDefinitions/GroupElement.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System.Linq;
|
||||
using UnityEditor.Toolbars;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class GroupElement : EditorToolbarDropdown
|
||||
{
|
||||
private VisualElement[] _groupedElements;
|
||||
public VisualElement[] GroupedElements => _groupedElements.ToArray();
|
||||
|
||||
public GroupElement(string name)
|
||||
{
|
||||
this.name = name;
|
||||
text = name;
|
||||
clicked += ShowDropdown;
|
||||
}
|
||||
|
||||
public void Initialize(VisualElement[] groupedElements)
|
||||
{
|
||||
_groupedElements = groupedElements;
|
||||
}
|
||||
|
||||
private void ShowDropdown()
|
||||
{
|
||||
GroupDropdownWindowPopupManager.Show(worldBound, _groupedElements);
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/GroupDefinitions/GroupElement.cs.meta
Normal file
11
Editor/Toolbar/GroupDefinitions/GroupElement.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c782e5c3d1d2bd7499b358c6aa5703cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public class GroupPopupSubWindowAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6e542ea23caed94c92fab5ac0d0f1c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,7 @@
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal interface IGroupDefinitionRepository
|
||||
{
|
||||
public GroupDefinition[] GetAll();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15164a1a1815ea04c9ae72e65e0a9fe9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
||||
internal class MainToolbarElementDropdownAttribute : PropertyAttribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffb57bb326f1c1247b6e1341c5caecf3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(MainToolbarElementDropdownAttribute))]
|
||||
internal class MainToolbarElementDropdownDrawer : PropertyDrawer
|
||||
{
|
||||
private string _groupId;
|
||||
private IEnumerable<string> _mainToolbarElementsIds;
|
||||
private IEnumerable<string> _groupIds;
|
||||
private IEnumerable<string> _allIds;
|
||||
|
||||
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
||||
{
|
||||
_groupId = property.serializedObject.FindProperty("_groupId").stringValue;
|
||||
|
||||
CacheAllIds();
|
||||
|
||||
var availableIds = GetAvailableIds();
|
||||
|
||||
var popupField = new PopupField<string>(
|
||||
choices: availableIds,
|
||||
0);
|
||||
|
||||
Restore(property, availableIds, popupField);
|
||||
|
||||
popupField.RegisterCallback<ChangeEvent<string>>(ev =>
|
||||
{
|
||||
property.stringValue = ev.newValue;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
ScriptableGroupDefinitionHelper.Refresh();
|
||||
CacheAllIds();
|
||||
var newAvailableIds = GetAvailableIds();
|
||||
newAvailableIds.Add(property.stringValue);
|
||||
popupField.choices = newAvailableIds.OrderBy(id => id).ToList();
|
||||
});
|
||||
|
||||
return popupField;
|
||||
}
|
||||
|
||||
private void Restore(SerializedProperty property, List<string> availableIds, PopupField<string> popupField)
|
||||
{
|
||||
if (string.IsNullOrEmpty(property.stringValue))
|
||||
{
|
||||
property.stringValue = popupField.value;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_allIds.Contains(property.stringValue))
|
||||
{
|
||||
availableIds.Add(property.stringValue);
|
||||
popupField.choices = availableIds.OrderBy(id => id).ToList();
|
||||
popupField.SetValueWithoutNotify(property.stringValue);
|
||||
}
|
||||
else
|
||||
popupField.SetValueWithoutNotify("");
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheAllIds()
|
||||
{
|
||||
_mainToolbarElementsIds = MainToolbarAutomaticExtender.CustomMainToolbarElements.Select(el => el.Id);
|
||||
_groupIds = ScriptableGroupDefinitionHelper.GetGroupIds();
|
||||
|
||||
_allIds = _mainToolbarElementsIds
|
||||
.Concat(_groupIds);
|
||||
}
|
||||
|
||||
private List<string> GetAvailableIds()
|
||||
{
|
||||
var unusedMainToolbarElementIds = ScriptableGroupDefinitionHelper.GetUnusedMainToolbarElementIds(_mainToolbarElementsIds);
|
||||
var unusedGroupIds = ScriptableGroupDefinitionHelper.GetEligibleGroupChildsFor(_groupId);
|
||||
|
||||
return unusedMainToolbarElementIds
|
||||
.Concat(unusedGroupIds)
|
||||
.OrderBy(id => id)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb51db686d5e79d4295bc1a510395e2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
52
Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs
Normal file
52
Editor/Toolbar/GroupDefinitions/ScriptableGroupDefinition.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
[CreateAssetMenu(menuName = ToolInfo.EDITOR_MENU_BASE + "/Group Definition")]
|
||||
public sealed class ScriptableGroupDefinition : ScriptableObject
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("Id of group. It must be unique")]
|
||||
private string _groupId;
|
||||
[SerializeField]
|
||||
[Tooltip("Text to display in group element dropdown")]
|
||||
private string _groupName;
|
||||
[SerializeField]
|
||||
[Tooltip("Alignment when used as root element. Ignored inside other groups")]
|
||||
private ToolbarAlign _alignment;
|
||||
[Tooltip("Order when used as root element. Ignored inside other groups. Order of elements inside a group is determined by ToolbarElementsIds array elements order.")]
|
||||
[SerializeField] private int _order;
|
||||
[SerializeField]
|
||||
[Tooltip("Elements ids of this group. Order of elements in array determines the order in which the elements will be displayed")]
|
||||
[MainToolbarElementDropdown] private string[] _toolbarElementsIds;
|
||||
|
||||
public string GroupId => _groupId;
|
||||
public string GroupName => _groupName;
|
||||
public ToolbarAlign Alignment => _alignment;
|
||||
public int Order => _order;
|
||||
public string[] ToolbarElementsIds => _toolbarElementsIds == null ? new string[0] : _toolbarElementsIds;
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
SetEqualValuesToEmptyInOrder();
|
||||
}
|
||||
|
||||
private void SetEqualValuesToEmptyInOrder()
|
||||
{
|
||||
for (int i = 0; i < _toolbarElementsIds.Length; i++)
|
||||
{
|
||||
var value = _toolbarElementsIds[i];
|
||||
for (int j = 0; j < _toolbarElementsIds.Length; j++)
|
||||
{
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
if (_toolbarElementsIds[j] == value)
|
||||
{
|
||||
_toolbarElementsIds[j] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6df7c06c2de586e41bb0c33bfd80766f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class ScriptableGroupDefinitionHelper
|
||||
{
|
||||
private static ScriptableGroupDefinition[] _projectGroupDefinitions;
|
||||
|
||||
static ScriptableGroupDefinitionHelper()
|
||||
{
|
||||
LoadProjectGroupDefinitions();
|
||||
|
||||
EditorApplication.projectChanged += OnProjectChange;
|
||||
}
|
||||
|
||||
public static void Refresh()
|
||||
{
|
||||
LoadProjectGroupDefinitions();
|
||||
}
|
||||
|
||||
private static void LoadProjectGroupDefinitions()
|
||||
{
|
||||
var paths = AssetDatabase.FindAssets("t:" + nameof(ScriptableGroupDefinition))
|
||||
.Select(guid => AssetDatabase.GUIDToAssetPath(guid));
|
||||
|
||||
_projectGroupDefinitions = paths
|
||||
.Select(path => AssetDatabase.LoadAssetAtPath<ScriptableGroupDefinition>(path))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetUnusedMainToolbarElementIds(IEnumerable<string> allIds)
|
||||
{
|
||||
return allIds.Except(GetUsedMainToolbarElementIds());
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GetUsedMainToolbarElementIds()
|
||||
{
|
||||
return _projectGroupDefinitions
|
||||
.SelectMany(groupDefinition => groupDefinition.ToolbarElementsIds);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetGroupIds()
|
||||
{
|
||||
return _projectGroupDefinitions.Select(g => g.GroupId);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetEligibleGroupChildsFor(string groupId)
|
||||
{
|
||||
var allUsedIds = _projectGroupDefinitions.SelectMany(g => g.ToolbarElementsIds);
|
||||
|
||||
return _projectGroupDefinitions.Select(g => g.GroupId)
|
||||
.Where(id => !allUsedIds.Contains(id))
|
||||
.Where(id => id != groupId);
|
||||
}
|
||||
|
||||
private static void OnProjectChange()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12a0d38180307184e87497e8fbb28985
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,38 @@
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class ScriptableObjectGroupDefinitionRepository : IGroupDefinitionRepository
|
||||
{
|
||||
public GroupDefinition[] GetAll()
|
||||
{
|
||||
var paths = AssetDatabase.FindAssets("t:" + nameof(ScriptableGroupDefinition))
|
||||
.Select(guid => AssetDatabase.GUIDToAssetPath(guid));
|
||||
|
||||
return paths
|
||||
.Select(path => AssetDatabase.LoadAssetAtPath<ScriptableGroupDefinition>(path))
|
||||
.Where(scriptableGroupDefinition => !string.IsNullOrEmpty(scriptableGroupDefinition.GroupId))
|
||||
.GroupBy(scriptableGroupDefinition => scriptableGroupDefinition.GroupId)
|
||||
.Select(scriptableGroupDefinition => scriptableGroupDefinition.First())
|
||||
.Select(scriptableGroupDefinition => new GroupDefinition(
|
||||
scriptableGroupDefinition.GroupId,
|
||||
scriptableGroupDefinition.GroupName,
|
||||
scriptableGroupDefinition.Alignment,
|
||||
scriptableGroupDefinition.Order,
|
||||
FilterIds(scriptableGroupDefinition)
|
||||
)
|
||||
)
|
||||
.Where(m => m.ToolbarElementsIds.Length > 0)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private string[] FilterIds(ScriptableGroupDefinition scriptableGroupDefinition)
|
||||
{
|
||||
return scriptableGroupDefinition.ToolbarElementsIds
|
||||
.Where(id => !string.IsNullOrEmpty(id))
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 225393fc4d1ad744c972f3a876dce3df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Toolbar/Helpers.meta
Normal file
8
Editor/Toolbar/Helpers.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efeeca875749f6d46905cc399ed76bae
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
34
Editor/Toolbar/Helpers/GlobalActions.cs
Normal file
34
Editor/Toolbar/Helpers/GlobalActions.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class GlobalActions
|
||||
{
|
||||
public static void ResetOverrides()
|
||||
{
|
||||
ServicesAndRepositories.MainToolbarElementOverridesRepository.Clear();
|
||||
MainToolbarAutomaticExtender.Refresh();
|
||||
}
|
||||
|
||||
public static void ResetOverridesIfUserAccepts()
|
||||
{
|
||||
ShowDialog(
|
||||
"Reset Overrides",
|
||||
"You are about to reset all toolbar elements overrides.\nAre you sure you want to continue?",
|
||||
"Reset",
|
||||
"Cancel",
|
||||
ResetOverrides
|
||||
);
|
||||
}
|
||||
|
||||
public static void ShowDialog(string title, string message, string okMessage,
|
||||
string cancelMessage, Action onOk = null, Action onCancel = null)
|
||||
{
|
||||
if (EditorUtility.DisplayDialog(title, message, okMessage, cancelMessage))
|
||||
onOk?.Invoke();
|
||||
else
|
||||
onCancel?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Helpers/GlobalActions.cs.meta
Normal file
11
Editor/Toolbar/Helpers/GlobalActions.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfe995773a109214db8292f8ce74d342
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Editor/Toolbar/Helpers/Icons.cs
Normal file
18
Editor/Toolbar/Helpers/Icons.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class Icons
|
||||
{
|
||||
private static readonly Lazy<Texture> VISIBILITY_ON_OVERRIDE_ICON_LAZY =
|
||||
new Lazy<Texture>(() => EditorGUIUtility.IconContent("animationvisibilitytoggleon").image);
|
||||
|
||||
private static readonly Lazy<Texture> VISIBILITY_OFF_OVERRIDE_ICON_LAZY =
|
||||
new Lazy<Texture>(() => EditorGUIUtility.IconContent("animationvisibilitytoggleoff").image);
|
||||
|
||||
public static Texture VisibilityOnOverrideIcon => VISIBILITY_ON_OVERRIDE_ICON_LAZY.Value;
|
||||
public static Texture VisibilityOffOverrideIcon => VISIBILITY_OFF_OVERRIDE_ICON_LAZY.Value;
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Helpers/Icons.cs.meta
Normal file
11
Editor/Toolbar/Helpers/Icons.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 51ede7e0c6a32a74faa6298082ed29cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Editor/Toolbar/Helpers/MenuItems.cs
Normal file
19
Editor/Toolbar/Helpers/MenuItems.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using UnityEditor;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class MenuItems
|
||||
{
|
||||
[MenuItem(ToolInfo.EDITOR_MENU_BASE + "/Refresh Toolbar Extender", priority = 1)]
|
||||
public static void Refresh()
|
||||
{
|
||||
MainToolbarAutomaticExtender.Refresh();
|
||||
}
|
||||
|
||||
[MenuItem(ToolInfo.EDITOR_MENU_BASE + "/Main Toolbar Control Panel", priority = 12)]
|
||||
public static void OpenControlPanel()
|
||||
{
|
||||
MainToolbarControlPanelWindow.OpenWindow();
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Helpers/MenuItems.cs.meta
Normal file
11
Editor/Toolbar/Helpers/MenuItems.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a74255adbb601344cb6b565d617de6f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class RefreshToolbarAutomaticExtenderOnSave : AssetModificationProcessor
|
||||
{
|
||||
private static string[] OnWillSaveAssets(string[] paths)
|
||||
{
|
||||
var groupDefinitionsAssetsPaths = AssetDatabase.FindAssets("t:" + nameof(ScriptableGroupDefinition))
|
||||
.Select(guid => AssetDatabase.GUIDToAssetPath(guid))
|
||||
.ToArray();
|
||||
|
||||
if (GroupDefinitionAssetIsBeingSaved(paths, groupDefinitionsAssetsPaths))
|
||||
{
|
||||
EditorApplication.update += RefreshOneTime;
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
private static bool GroupDefinitionAssetIsBeingSaved(string[] savingAssetsPaths, string[] groupDefinitionsAssetsPaths)
|
||||
{
|
||||
return savingAssetsPaths.Any(path => groupDefinitionsAssetsPaths.Contains(path));
|
||||
}
|
||||
|
||||
private static void RefreshOneTime()
|
||||
{
|
||||
EditorApplication.update -= RefreshOneTime;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private static void Refresh()
|
||||
{
|
||||
MainToolbarAutomaticExtender.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e74405729947e434fb3760be36ad262e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
23
Editor/Toolbar/Helpers/ServicesAndRepositories.cs
Normal file
23
Editor/Toolbar/Helpers/ServicesAndRepositories.cs
Normal file
@ -0,0 +1,23 @@
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class ServicesAndRepositories
|
||||
{
|
||||
public static IMainToolbarElementOverrideRepository MainToolbarElementOverridesRepository =
|
||||
new UserSettingsFileMainToolbarElementOverrideRepository();
|
||||
|
||||
public static IGroupDefinitionRepository GroupDefinitionRepository =
|
||||
new ScriptableObjectGroupDefinitionRepository();
|
||||
|
||||
public static IMainToolbarElementRepository MainToolbarElementRepository =
|
||||
new ByAttributeMainToolbarElementRepository();
|
||||
|
||||
public static IValueSerializer ValueSerializer =
|
||||
new UnitySerializationValueSerializer();
|
||||
|
||||
public static IMainToolbarElementVariableSerializer MainToolbarElementVariableSerializer =
|
||||
new UnitySerializationMainToolbarElementVariableSerializer(ValueSerializer);
|
||||
|
||||
public static IMainToolbarElementVariableRepository MainToolbarElementVariableRepository =
|
||||
new UserSettingsFileMainToolbarElementVariableRepository(MainToolbarElementVariableSerializer);
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Helpers/ServicesAndRepositories.cs.meta
Normal file
11
Editor/Toolbar/Helpers/ServicesAndRepositories.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f95a2c4cbecd4f419ae142074dbb03f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Toolbar/Helpers/ToolInfo.cs
Normal file
8
Editor/Toolbar/Helpers/ToolInfo.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class ToolInfo
|
||||
{
|
||||
public const string COMPANY_NAME = "Tools/EditorExtension/Toolbar";
|
||||
public const string EDITOR_MENU_BASE = COMPANY_NAME + "/" ;
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Helpers/ToolInfo.cs.meta
Normal file
11
Editor/Toolbar/Helpers/ToolInfo.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c363bf3b832d93c45b14669aa6ae573c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
120
Editor/Toolbar/Helpers/UnityNativeElementsIds.cs
Normal file
120
Editor/Toolbar/Helpers/UnityNativeElementsIds.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal static class UnityNativeElementsIds
|
||||
{
|
||||
// ------------------- ELEMENTS TYPES ---------------------
|
||||
|
||||
// LEFT
|
||||
private const string ACCOUNT_DROPDOWN_TYPE_NAME = "AccountDropdown";
|
||||
private const string CLOUD_BUTTON_TYPE_NAME = "CloudButton";
|
||||
private const string VERSION_CONTROL_BUTTON_TYPE_NAME = "MainToolbarImguiContainer";
|
||||
private const string STORE_BUTTON_TYPE_NAME = "StoreButton";
|
||||
|
||||
// RIGHT
|
||||
private const string LAYOUT_DROPDOWN_TYPE_NAME = "LayoutDropdown";
|
||||
private const string LAYERS_DROPDOWN_TYPE_NAME = "LayersDropdown";
|
||||
private const string SEARCH_BUTTON_TYPE_NAME = "SearchButton";
|
||||
private const string MODES_DROPDOWN_TYPE_NAME = "ModesDropdown";
|
||||
private const string PREVIEW_PACKAGES_IN_USE_DROPDOWN_TYPE_NAME = "PreviewPackagesInUseDropdown";
|
||||
private const string UNDO_BUTTON_TYPE_NAME = "UndoButton";
|
||||
private const string MULTIPLAYER_ROLE_DROPDOWN_TYPE_NAME = "MultiplayerRoleDropdown";
|
||||
|
||||
// ------------------- ELEMENTS NAMES ---------------------
|
||||
|
||||
// LEFT
|
||||
private const string TOOLBAR_PRODUCT_CAPTION_NAME = "ToolbarProductCaption";
|
||||
private const string ACCOUNT_DROPDOWN_ELEMENT_NAME = "AccountDropdown";
|
||||
private const string CLOUD_BUTTON_ELEMENT_NAME = "Cloud";
|
||||
|
||||
// CENTER
|
||||
private const string PLAY_BUTTON_ELEMENT_NAME = "Play";
|
||||
private const string PAUSE_BUTTON_ELEMENT_NAME = "Pause";
|
||||
private const string FRAME_STEP_BUTTON_ELEMENT_NAME = "Step";
|
||||
|
||||
// RIGHT
|
||||
private const string LAYOUT_DROPDOWN_ELEMENT_NAME = "LayoutDropdown";
|
||||
private const string LAYERS_DROPDOWN_ELEMENT_NAME = "LayersDropdown";
|
||||
private const string MODES_DROPDOWN_ELEMENT_NAME = "ModesDropdown";
|
||||
private const string PREVIEW_PACKAGES_IN_USE_DROPDOWN_ELEMENT_NAME = "PreviewPackagesInUseDropdown";
|
||||
private const string UNDO_BUTTON_ELEMENT_NAME = "History";
|
||||
|
||||
// ------------------- FIXED IDS ---------------------
|
||||
|
||||
// LEFT
|
||||
public const string TOOLBAR_PRODUCT_CAPTION = "ToolbarProductCaption";
|
||||
public const string ACCOUNT_DROPDOWN_ID = "AccountDropdown";
|
||||
public const string CLOUD_BUTTON_ID = "CloudButton";
|
||||
public const string VERSION_CONTROL_ID = "VersionControlButton";
|
||||
public const string STORE_BUTTON_ID = "StoreButton";
|
||||
|
||||
// CENTER
|
||||
public const string PLAY_BUTTON_ID = "PlayButton";
|
||||
public const string PAUSE_BUTTON_ID = "PauseButton";
|
||||
public const string FRAME_STEP_BUTTON_ID = "FrameStepButton";
|
||||
|
||||
// RIGHT
|
||||
public const string LAYOUT_DROPDOWN_ID = "LayoutDropdown";
|
||||
public const string LAYERS_DROPDOWN_ID = "LayersDropdown";
|
||||
public const string SEARCH_BUTTON_ID = "SearchButton";
|
||||
public const string MODES_DROPDOWN_ID = "ModesDropdown";
|
||||
public const string PREVIEW_PACKAGES_IN_USE_DROPDOWN_ID = "PreviewPackagesInUseDropdown";
|
||||
public const string UNDO_BUTTON_ID = "UndoButton";
|
||||
public const string MULTIPLAYER_ROLE_DROPDOWN = "MultiplayerRoleDropdown";
|
||||
|
||||
private static readonly Dictionary<string, string> IDS_BY_TYPE = new Dictionary<string, string>()
|
||||
{
|
||||
// LEFT
|
||||
{ ACCOUNT_DROPDOWN_TYPE_NAME, ACCOUNT_DROPDOWN_ID },
|
||||
{ CLOUD_BUTTON_TYPE_NAME, CLOUD_BUTTON_ID },
|
||||
{ VERSION_CONTROL_BUTTON_TYPE_NAME, VERSION_CONTROL_ID },
|
||||
{ STORE_BUTTON_TYPE_NAME, STORE_BUTTON_ID },
|
||||
|
||||
// RIGHT
|
||||
{ LAYOUT_DROPDOWN_TYPE_NAME, LAYOUT_DROPDOWN_ID },
|
||||
{ LAYERS_DROPDOWN_TYPE_NAME, LAYERS_DROPDOWN_ID },
|
||||
{ SEARCH_BUTTON_TYPE_NAME, SEARCH_BUTTON_ID },
|
||||
{ MODES_DROPDOWN_TYPE_NAME, MODES_DROPDOWN_ID },
|
||||
{ PREVIEW_PACKAGES_IN_USE_DROPDOWN_TYPE_NAME, PREVIEW_PACKAGES_IN_USE_DROPDOWN_ID },
|
||||
{ UNDO_BUTTON_TYPE_NAME, UNDO_BUTTON_ID },
|
||||
{ MULTIPLAYER_ROLE_DROPDOWN_TYPE_NAME, MULTIPLAYER_ROLE_DROPDOWN }
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, string> IDS_BY_NAME = new Dictionary<string, string>()
|
||||
{
|
||||
// LEFT
|
||||
{ TOOLBAR_PRODUCT_CAPTION_NAME, TOOLBAR_PRODUCT_CAPTION },
|
||||
{ ACCOUNT_DROPDOWN_ELEMENT_NAME, ACCOUNT_DROPDOWN_ID },
|
||||
{ CLOUD_BUTTON_ELEMENT_NAME, CLOUD_BUTTON_ID },
|
||||
|
||||
// CENTER
|
||||
{ PLAY_BUTTON_ELEMENT_NAME, PLAY_BUTTON_ID },
|
||||
{ PAUSE_BUTTON_ELEMENT_NAME, PAUSE_BUTTON_ID },
|
||||
{ FRAME_STEP_BUTTON_ELEMENT_NAME, FRAME_STEP_BUTTON_ID },
|
||||
|
||||
// RIGHT
|
||||
{ LAYOUT_DROPDOWN_ELEMENT_NAME, LAYOUT_DROPDOWN_ID },
|
||||
{ LAYERS_DROPDOWN_ELEMENT_NAME, LAYERS_DROPDOWN_ID },
|
||||
{ MODES_DROPDOWN_ELEMENT_NAME, MODES_DROPDOWN_ID },
|
||||
{ PREVIEW_PACKAGES_IN_USE_DROPDOWN_ELEMENT_NAME, PREVIEW_PACKAGES_IN_USE_DROPDOWN_ID },
|
||||
{ UNDO_BUTTON_ELEMENT_NAME, UNDO_BUTTON_ID },
|
||||
};
|
||||
|
||||
public static string IdOf(VisualElement visualElement)
|
||||
{
|
||||
var typeName = visualElement.GetType().Name;
|
||||
|
||||
if(IDS_BY_TYPE.ContainsKey(typeName))
|
||||
return IDS_BY_TYPE[typeName];
|
||||
|
||||
var elementName = visualElement.name;
|
||||
|
||||
if(IDS_BY_NAME.ContainsKey(elementName))
|
||||
return IDS_BY_NAME[elementName];
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Helpers/UnityNativeElementsIds.cs.meta
Normal file
11
Editor/Toolbar/Helpers/UnityNativeElementsIds.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62370caf7a9d1274ba18d9556d83fd07
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
118
Editor/Toolbar/Helpers/UserSettingsPrefs.cs
Normal file
118
Editor/Toolbar/Helpers/UserSettingsPrefs.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Unity.Serialization.Json;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
public static class UserSettingsPrefs
|
||||
{
|
||||
private static readonly string DIRECTORY = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "UserSettings/", "unity-toolbar-extender-ui-toolkit", "user-settings-prefs");
|
||||
private static readonly string FILE = Path.Combine(DIRECTORY, "user-settings-prefs.json");
|
||||
|
||||
private static Dictionary<string, object> _prefs;
|
||||
private static Dictionary<string, object> Prefs
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_prefs == null)
|
||||
_prefs = Load();
|
||||
|
||||
return _prefs;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetInt(string key, int value)
|
||||
{
|
||||
Prefs[key] = value;
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void SetFloat(string key, float value)
|
||||
{
|
||||
Prefs[key] = value;
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void SetDouble(string key, double value)
|
||||
{
|
||||
Prefs[key] = value;
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void SetBool(string key, bool value)
|
||||
{
|
||||
Prefs[key] = value;
|
||||
Save();
|
||||
}
|
||||
|
||||
public static void SetString(string key, string value)
|
||||
{
|
||||
Prefs[key] = value;
|
||||
Save();
|
||||
}
|
||||
|
||||
public static string GetString(string key, string defaultValue = null)
|
||||
{
|
||||
if (Prefs.ContainsKey(key))
|
||||
return (string)Prefs[key];
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static bool GetBool(string key, bool defaultValue = false)
|
||||
{
|
||||
if (Prefs.ContainsKey(key))
|
||||
return (bool)Prefs[key];
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static int GetInt(string key, int defaultValue = 0)
|
||||
{
|
||||
if (Prefs.ContainsKey(key))
|
||||
return Convert.ToInt32(Prefs[key]);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static float GetFloat(string key, float defaultValue = 0.0f)
|
||||
{
|
||||
if (Prefs.ContainsKey(key))
|
||||
return Convert.ToSingle(Prefs[key]);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static double GetDouble(string key, double defaultValue = 0.0)
|
||||
{
|
||||
if (Prefs.ContainsKey(key))
|
||||
return Convert.ToDouble(Prefs[key]);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static Dictionary<string, object> Load()
|
||||
{
|
||||
if (!Directory.Exists(DIRECTORY))
|
||||
Directory.CreateDirectory(DIRECTORY);
|
||||
|
||||
if (!File.Exists(FILE))
|
||||
return JsonSerialization.FromJson<Dictionary<string, object>>("{}");
|
||||
|
||||
var json = File.ReadAllText(FILE);
|
||||
|
||||
var serializedDictionary = JsonSerialization.FromJson<Dictionary<string, object>>(json);
|
||||
|
||||
return serializedDictionary;
|
||||
}
|
||||
|
||||
private static void Save()
|
||||
{
|
||||
var json = JsonSerialization.ToJson(Prefs);
|
||||
|
||||
File.WriteAllText(FILE, json);
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Helpers/UserSettingsPrefs.cs.meta
Normal file
11
Editor/Toolbar/Helpers/UserSettingsPrefs.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fad7572312c85da4e80e115c63b2d164
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
7
Editor/Toolbar/IMainToolbarElementRepository.cs
Normal file
7
Editor/Toolbar/IMainToolbarElementRepository.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal interface IMainToolbarElementRepository
|
||||
{
|
||||
public MainToolbarElement[] GetAll();
|
||||
}
|
||||
}
|
11
Editor/Toolbar/IMainToolbarElementRepository.cs.meta
Normal file
11
Editor/Toolbar/IMainToolbarElementRepository.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6fdece3308162d4994b872bcb838c72
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
88
Editor/Toolbar/MainToolbar.cs
Normal file
88
Editor/Toolbar/MainToolbar.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class MainToolbar
|
||||
{
|
||||
private const string TOOLBAR_ROOT_ELEMENT_FIELD_NAME = "m_Root";
|
||||
private const string TOOLBAR_CENTER_CONTAINER_NAME = "ToolbarZonePlayMode";
|
||||
private const string TOOLBAR_LEFT_CONTAINER_NAME = "ToolbarZoneLeftAlign";
|
||||
private const string TOOLBAR_RIGHT_CONTAINER_NAME = "ToolbarZoneRightAlign";
|
||||
private const string TOOLBAR_PLAY_BUTTON_NAME = "Play";
|
||||
|
||||
private static Type _toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
|
||||
private static ScriptableObject _innerToolbarObject;
|
||||
|
||||
public static event Action OnInitialized;
|
||||
public static event Action OnRefresh;
|
||||
|
||||
public static VisualElement UnityToolbarRoot { get; private set; }
|
||||
|
||||
public static VisualElement LeftContainer { get; private set; }
|
||||
public static VisualElement CenterContainer { get; private set; }
|
||||
public static VisualElement RightContainer { get; private set; }
|
||||
public static VisualElement PlayModeButtonsContainer { get; private set; }
|
||||
|
||||
public static bool IsAvailable => _innerToolbarObject != null;
|
||||
|
||||
private static bool _initialized;
|
||||
|
||||
static MainToolbar()
|
||||
{
|
||||
EditorApplication.update -= OnUpdate;
|
||||
EditorApplication.update += OnUpdate;
|
||||
}
|
||||
|
||||
private static void WrapNativeToolbar()
|
||||
{
|
||||
FindUnityToolbar();
|
||||
if (_innerToolbarObject == null)
|
||||
return;
|
||||
CacheNativeToolbarContainers();
|
||||
|
||||
if(!_initialized)
|
||||
{
|
||||
_initialized = true;
|
||||
OnInitialized?.Invoke();
|
||||
}
|
||||
else
|
||||
OnRefresh?.Invoke();
|
||||
}
|
||||
|
||||
private static void FindUnityToolbar()
|
||||
{
|
||||
var toolbars = Resources.FindObjectsOfTypeAll(_toolbarType);
|
||||
_innerToolbarObject = toolbars.Length > 0 ? (ScriptableObject)toolbars[0] : null;
|
||||
}
|
||||
|
||||
private static void CacheNativeToolbarContainers()
|
||||
{
|
||||
var unityToolbarRootFieldInfo = _innerToolbarObject.GetType()
|
||||
.GetField(TOOLBAR_ROOT_ELEMENT_FIELD_NAME, BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
UnityToolbarRoot = unityToolbarRootFieldInfo.GetValue(_innerToolbarObject) as VisualElement;
|
||||
|
||||
LeftContainer = UnityToolbarRoot.Q(TOOLBAR_LEFT_CONTAINER_NAME);
|
||||
CenterContainer = UnityToolbarRoot.Q(TOOLBAR_CENTER_CONTAINER_NAME);
|
||||
RightContainer = UnityToolbarRoot.Q(TOOLBAR_RIGHT_CONTAINER_NAME);
|
||||
PlayModeButtonsContainer = CenterContainer.Q(TOOLBAR_PLAY_BUTTON_NAME).parent;
|
||||
}
|
||||
|
||||
private static void OnUpdate()
|
||||
{
|
||||
if (NeedsWrap())
|
||||
{
|
||||
WrapNativeToolbar();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool NeedsWrap()
|
||||
{
|
||||
return _innerToolbarObject == null;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/MainToolbar.cs.meta
Normal file
11
Editor/Toolbar/MainToolbar.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce77a44ce866ce34d9ce10f93b19c256
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
330
Editor/Toolbar/MainToolbarAutomaticExtender.cs
Normal file
330
Editor/Toolbar/MainToolbarAutomaticExtender.cs
Normal file
@ -0,0 +1,330 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public static class MainToolbarAutomaticExtender
|
||||
{
|
||||
private static MainToolbarElement[] _mainToolbarElements = new MainToolbarElement[0];
|
||||
private static MainToolbarElement[] _groupElements = new MainToolbarElement[0];
|
||||
private static GroupDefinition[] _groupDefinitions = new GroupDefinition[0];
|
||||
private static MainToolbarElement[] _rootElements = new MainToolbarElement[0];
|
||||
private static NativeToolbarElement[] _nativeElements = new NativeToolbarElement[0];
|
||||
private static MainToolbarElement[] _singleElements = new MainToolbarElement[0];
|
||||
private static MainToolbarElementOverrideApplier _overrideApplier = new MainToolbarElementOverrideApplier(ServicesAndRepositories.MainToolbarElementOverridesRepository);
|
||||
private static Dictionary<string, MainToolbarElement[]> _elementsByGroup = new Dictionary<string, MainToolbarElement[]>();
|
||||
private static MainToolbarElementVariableWatcher _variableWatcher = new MainToolbarElementVariableWatcher(ServicesAndRepositories.MainToolbarElementVariableRepository, ServicesAndRepositories.ValueSerializer);
|
||||
|
||||
internal static MainToolbarCustomContainer LeftCustomContainer { get; private set; } = new MainToolbarCustomContainer("ToolbarAutomaticExtenderLeftContainer", FlexDirection.RowReverse);
|
||||
internal static MainToolbarCustomContainer RightCustomContainer { get; private set; } = new MainToolbarCustomContainer("ToolbarAutomaticExtenderRightContainer", FlexDirection.Row);
|
||||
|
||||
internal static MainToolbarElement[] CustomMainToolbarElements => _mainToolbarElements.ToArray();
|
||||
internal static MainToolbarElement[] GroupElements => _groupElements.ToArray();
|
||||
internal static NativeToolbarElement[] NativeElements => _nativeElements.ToArray();
|
||||
|
||||
public static event Action OnRefresh;
|
||||
public static event Action OnAddedCustomContainersToToolbar;
|
||||
|
||||
static MainToolbarAutomaticExtender()
|
||||
{
|
||||
MainToolbar.OnInitialized += Initialize;
|
||||
}
|
||||
|
||||
private static void Initialize()
|
||||
{
|
||||
BuildCustomToolbarContainers();
|
||||
|
||||
if (_mainToolbarElements.Length == 0)
|
||||
return;
|
||||
|
||||
EditorApplication.projectChanged += OnProjectChange;
|
||||
MainToolbar.OnRefresh += ApplyFixedChangesToToolbar;
|
||||
|
||||
CacheNativeElements();
|
||||
ApplyFixedChangesToToolbar();
|
||||
}
|
||||
|
||||
private static void CacheNativeElements()
|
||||
{
|
||||
var nativeElements = GetNativeElements();
|
||||
if (nativeElements.Length != 0)
|
||||
{
|
||||
_nativeElements = nativeElements;
|
||||
_overrideApplier.SetNativeElements(_nativeElements);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Refresh()
|
||||
{
|
||||
if (!MainToolbar.IsAvailable)
|
||||
return;
|
||||
|
||||
ResetCustomContainers();
|
||||
BuildCustomToolbarContainers();
|
||||
_overrideApplier.ApplyOverrides();
|
||||
OnRefresh?.Invoke();
|
||||
}
|
||||
|
||||
internal static MainToolbarElement[] GetElementsOfGroup(string id)
|
||||
{
|
||||
return _elementsByGroup[id].ToArray();
|
||||
}
|
||||
|
||||
private static void ResetCustomContainers()
|
||||
{
|
||||
LeftCustomContainer.ClearContainer();
|
||||
RightCustomContainer.ClearContainer();
|
||||
}
|
||||
|
||||
private static void BuildCustomToolbarContainers()
|
||||
{
|
||||
_mainToolbarElements = ServicesAndRepositories.MainToolbarElementRepository.GetAll();
|
||||
|
||||
if (_mainToolbarElements.Count() == 0)
|
||||
return;
|
||||
|
||||
_groupDefinitions = LoadGroupDefinitions();
|
||||
_groupElements = GetGroups();
|
||||
_elementsByGroup = GetElementsByGroup();
|
||||
InitializeGroups();
|
||||
_singleElements = GetSingles();
|
||||
_rootElements = GetRootElements();
|
||||
_overrideApplier.SetCustomElements(_mainToolbarElements.Concat(_groupElements).ToArray());
|
||||
_variableWatcher.RestoreValues(CustomMainToolbarElements);
|
||||
|
||||
InitializeCustomElements();
|
||||
RegisterElementsForRecommendedStyles();
|
||||
|
||||
AddRootElementsToContainers();
|
||||
|
||||
EditorApplication.update += Update;
|
||||
}
|
||||
|
||||
private static void InitializeCustomElements()
|
||||
{
|
||||
foreach(var customElement in CustomMainToolbarElements)
|
||||
{
|
||||
var typeOfElement = customElement.VisualElement.GetType();
|
||||
|
||||
var initializeMethod = typeOfElement.GetMethod("InitializeElement", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
initializeMethod?.Invoke(customElement.VisualElement, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
_variableWatcher.Update();
|
||||
}
|
||||
|
||||
private static void InitializeGroups()
|
||||
{
|
||||
foreach (var group in _groupElements)
|
||||
{
|
||||
var groupElement = group.VisualElement as GroupElement;
|
||||
var elementsOfThisGroup = _elementsByGroup[group.Id]
|
||||
.Select(e => e.VisualElement)
|
||||
.ToArray();
|
||||
|
||||
groupElement.Initialize(elementsOfThisGroup);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterElementsForRecommendedStyles()
|
||||
{
|
||||
var eligibleElements = _mainToolbarElements
|
||||
.Concat(_groupElements)
|
||||
.Where(element => element.UseRecommendedStyles)
|
||||
.Select(element => new RecommendedStyleVisualElement(element.VisualElement, IsInGroup(element)))
|
||||
.ToArray();
|
||||
|
||||
RecommendedStyles.SetElements(eligibleElements);
|
||||
}
|
||||
|
||||
private static bool IsInGroup(MainToolbarElement mainToolbarElement)
|
||||
{
|
||||
return !_rootElements.Contains(mainToolbarElement);
|
||||
}
|
||||
|
||||
private static MainToolbarElement[] GetRootElements()
|
||||
{
|
||||
return GetRootGroups()
|
||||
.Concat(_singleElements)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static MainToolbarElement[] GetRootGroups()
|
||||
{
|
||||
var rootGroups = new List<MainToolbarElement>();
|
||||
|
||||
var allGroupElements = _groupElements.Select(group => group.VisualElement as GroupElement);
|
||||
|
||||
foreach (var group in _groupElements)
|
||||
{
|
||||
var groupElement = group.VisualElement as GroupElement;
|
||||
|
||||
if (!allGroupElements.Any(g => g.GroupedElements.Contains(groupElement)))
|
||||
rootGroups.Add(group);
|
||||
}
|
||||
|
||||
return rootGroups.ToArray();
|
||||
}
|
||||
|
||||
private static NativeToolbarElement[] GetNativeElements()
|
||||
{
|
||||
return MainToolbar.LeftContainer.Children()
|
||||
.Concat(MainToolbar.RightContainer.Children())
|
||||
.Concat(MainToolbar.PlayModeButtonsContainer.Children())
|
||||
.Where(visualElement => UnityNativeElementsIds.IdOf(visualElement) != null)
|
||||
.Select(visualElement => new NativeToolbarElement(UnityNativeElementsIds.IdOf(visualElement), visualElement))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static void ApplyFixedChangesToToolbar()
|
||||
{
|
||||
ConfigureStyleOfContainers();
|
||||
AddCustomContainers();
|
||||
_overrideApplier.ApplyOverrides();
|
||||
OnAddedCustomContainersToToolbar?.Invoke();
|
||||
}
|
||||
|
||||
private static void AddCustomContainers()
|
||||
{
|
||||
MainToolbar.CenterContainer.Insert(0, LeftCustomContainer);
|
||||
MainToolbar.CenterContainer.Add(RightCustomContainer);
|
||||
}
|
||||
|
||||
private static void AddRootElementsToContainers()
|
||||
{
|
||||
var leftElements = _rootElements.Where(el => el.Alignment == ToolbarAlign.Left)
|
||||
.OrderBy(el => el.Order);
|
||||
|
||||
var rightElements = _rootElements.Where(el => el.Alignment == ToolbarAlign.Right)
|
||||
.OrderBy(el => el.Order);
|
||||
|
||||
foreach (var orderedAlignedElement in leftElements)
|
||||
LeftCustomContainer.AddToContainer(orderedAlignedElement.VisualElement);
|
||||
|
||||
foreach (var orderedAlignedElement in rightElements)
|
||||
RightCustomContainer.AddToContainer(orderedAlignedElement.VisualElement);
|
||||
}
|
||||
|
||||
private static MainToolbarElement[] GetGroups()
|
||||
{
|
||||
var groups = new List<MainToolbarElement>();
|
||||
|
||||
foreach (var groupDefinition in _groupDefinitions)
|
||||
{
|
||||
if (groupDefinition.ToolbarElementsIds.Length == 0)
|
||||
continue;
|
||||
|
||||
var groupToolbarElement = new MainToolbarElement(
|
||||
groupDefinition.GroupId,
|
||||
new GroupElement(groupDefinition.GroupName),
|
||||
groupDefinition.Alignment,
|
||||
groupDefinition.Order,
|
||||
true
|
||||
);
|
||||
|
||||
groups.Add(groupToolbarElement);
|
||||
}
|
||||
|
||||
return groups.ToArray();
|
||||
}
|
||||
|
||||
private static MainToolbarElement[] GetSingles()
|
||||
{
|
||||
var elementsInGroups = _elementsByGroup.Values.SelectMany(list => list);
|
||||
|
||||
return _mainToolbarElements
|
||||
.Where(mainToolbarElement => !elementsInGroups.Contains(mainToolbarElement))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static Dictionary<string, MainToolbarElement[]> GetElementsByGroup()
|
||||
{
|
||||
var elementsByGroup = new Dictionary<string, MainToolbarElement[]>();
|
||||
|
||||
foreach (var groupDefinition in _groupDefinitions)
|
||||
{
|
||||
var elementsOfThisGroup = groupDefinition.ToolbarElementsIds
|
||||
.Select(id =>
|
||||
{
|
||||
var element = _mainToolbarElements.FirstOrDefault(e => e.Id == id);
|
||||
|
||||
if (element != null)
|
||||
return element;
|
||||
|
||||
element = _groupElements.FirstOrDefault(e => e.Id == id);
|
||||
|
||||
return element;
|
||||
})
|
||||
.Where(mainToolbarElement => mainToolbarElement != null)
|
||||
.ToList();
|
||||
|
||||
elementsByGroup.Add(groupDefinition.GroupId, elementsOfThisGroup.ToArray());
|
||||
}
|
||||
|
||||
return elementsByGroup;
|
||||
}
|
||||
|
||||
private static GroupDefinition[] LoadGroupDefinitions()
|
||||
{
|
||||
return ServicesAndRepositories.GroupDefinitionRepository.GetAll();
|
||||
}
|
||||
|
||||
private static void ConfigureStyleOfContainers()
|
||||
{
|
||||
MainToolbar.LeftContainer.style.flexGrow = 0;
|
||||
MainToolbar.LeftContainer.style.width = Length.Auto();
|
||||
|
||||
MainToolbar.RightContainer.style.flexGrow = 0;
|
||||
MainToolbar.RightContainer.style.width = Length.Auto();
|
||||
|
||||
MainToolbar.CenterContainer.style.flexGrow = 1;
|
||||
|
||||
MainToolbar.CenterContainer.parent.style.paddingTop = 0;
|
||||
MainToolbar.CenterContainer.parent.style.paddingBottom = 0;
|
||||
}
|
||||
|
||||
private static void OnProjectChange()
|
||||
{
|
||||
if(ShouldRefresh())
|
||||
Refresh();
|
||||
}
|
||||
|
||||
private static bool ShouldRefresh()
|
||||
{
|
||||
return GroupsChanged();
|
||||
}
|
||||
|
||||
private static bool GroupsChanged()
|
||||
{
|
||||
var groups = ServicesAndRepositories.GroupDefinitionRepository.GetAll();
|
||||
|
||||
if (_groupDefinitions.Length != groups.Length)
|
||||
return true;
|
||||
|
||||
if (_groupDefinitions.Length == 0 && groups.Length == 0)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < _groupDefinitions.Length; i++)
|
||||
{
|
||||
var savedGroupDefinition = _groupDefinitions[i];
|
||||
var retrievedGroupDefinition = groups[i];
|
||||
|
||||
if (!savedGroupDefinition.AreEquals(retrievedGroupDefinition))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/MainToolbarAutomaticExtender.cs.meta
Normal file
11
Editor/Toolbar/MainToolbarAutomaticExtender.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6fd1abb4edafb6a4793209e0f154d8a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
95
Editor/Toolbar/MainToolbarCustomContainer.cs
Normal file
95
Editor/Toolbar/MainToolbarCustomContainer.cs
Normal file
@ -0,0 +1,95 @@
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class MainToolbarCustomContainer : VisualElement
|
||||
{
|
||||
private const string LAST_SCROLLER_POSITION_SAVE_KEY_BASE = "main-toolbar-custom-container:last-scroller-position:";
|
||||
|
||||
private const float SCROLL_VIEW_SCROLLER_HEIGHT = 1;
|
||||
private const float SCROLLER_HEIGHT = 5;
|
||||
private const float SCROLL_VIEW_HORIZONTAL_PADDING = 5;
|
||||
private const float SCROLL_VIEW_SCROLLER_BORDER_TOP_WIDTH = 0;
|
||||
|
||||
private string _id;
|
||||
private ScrollView _scrollView;
|
||||
private Scroller _scroller;
|
||||
private VisualElement _container;
|
||||
|
||||
public MainToolbarCustomContainer(string id, FlexDirection flexDirection)
|
||||
{
|
||||
_id = id;
|
||||
name = id;
|
||||
|
||||
style.flexDirection = flexDirection;
|
||||
style.flexGrow = 1;
|
||||
style.width = 0;
|
||||
|
||||
_container = CreateAndAddContainer(flexDirection);
|
||||
}
|
||||
|
||||
private VisualElement CreateAndAddContainer(FlexDirection flexDirection)
|
||||
{
|
||||
_scrollView = new ScrollView(ScrollViewMode.Horizontal);
|
||||
|
||||
_scrollView.style.paddingLeft = SCROLL_VIEW_HORIZONTAL_PADDING;
|
||||
_scrollView.style.paddingRight = SCROLL_VIEW_HORIZONTAL_PADDING;
|
||||
|
||||
_scrollView.verticalScrollerVisibility = ScrollerVisibility.Hidden;
|
||||
_scrollView.contentContainer.style.flexDirection = flexDirection;
|
||||
|
||||
_scroller = _scrollView.horizontalScroller;
|
||||
|
||||
var leftButton = _scroller.lowButton;
|
||||
var rightButton = _scroller.highButton;
|
||||
var slider = _scroller.slider;
|
||||
|
||||
_scroller.style.height = SCROLL_VIEW_SCROLLER_HEIGHT;
|
||||
_scroller.style.borderTopWidth = SCROLL_VIEW_SCROLLER_BORDER_TOP_WIDTH;
|
||||
leftButton.style.height = SCROLLER_HEIGHT;
|
||||
rightButton.style.height = SCROLLER_HEIGHT;
|
||||
slider.style.height = SCROLLER_HEIGHT;
|
||||
|
||||
Add(_scrollView);
|
||||
_scrollView.RegisterCallback<GeometryChangedEvent>(LoadLastScrollerPosition);
|
||||
|
||||
return _scrollView;
|
||||
}
|
||||
|
||||
private void LoadLastScrollerPosition(GeometryChangedEvent eventArgs)
|
||||
{
|
||||
_scroller.value = (float)LastScrollerPosition();
|
||||
_scroller.valueChanged += SaveScrollerPosition;
|
||||
|
||||
_scrollView.UnregisterCallback<GeometryChangedEvent>(LoadLastScrollerPosition);
|
||||
}
|
||||
|
||||
private double LastScrollerPosition()
|
||||
{
|
||||
return UserSettingsPrefs.GetDouble(GetFullKey(), 0d);
|
||||
}
|
||||
|
||||
private void SaveScrollerPosition(float newPosition)
|
||||
{
|
||||
UserSettingsPrefs.SetDouble(GetFullKey(), newPosition);
|
||||
}
|
||||
|
||||
private string GetFullKey() => LAST_SCROLLER_POSITION_SAVE_KEY_BASE + _id;
|
||||
|
||||
public void AddToContainer(VisualElement child)
|
||||
{
|
||||
_container.Add(child);
|
||||
}
|
||||
|
||||
public void ClearContainer()
|
||||
{
|
||||
_container.Clear();
|
||||
}
|
||||
|
||||
public VisualElement[] GetContainerChilds()
|
||||
{
|
||||
return _container.Children().ToArray();
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/MainToolbarCustomContainer.cs.meta
Normal file
11
Editor/Toolbar/MainToolbarCustomContainer.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a0122c91e132b8478c5d18c85d0df6f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
23
Editor/Toolbar/MainToolbarElement.cs
Normal file
23
Editor/Toolbar/MainToolbarElement.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class MainToolbarElement
|
||||
{
|
||||
public string Id { get; }
|
||||
public VisualElement VisualElement { get; }
|
||||
public ToolbarAlign Alignment { get; }
|
||||
public int Order { get; }
|
||||
public bool UseRecommendedStyles { get; }
|
||||
|
||||
public MainToolbarElement(string id, VisualElement visualElement,
|
||||
ToolbarAlign alignment, int order, bool useRecommendedStyles)
|
||||
{
|
||||
Id = id;
|
||||
VisualElement = visualElement;
|
||||
Alignment = alignment;
|
||||
Order = order;
|
||||
UseRecommendedStyles = useRecommendedStyles;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/MainToolbarElement.cs.meta
Normal file
11
Editor/Toolbar/MainToolbarElement.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f67ca04efaf7f044fa5a17a7627aca0b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
31
Editor/Toolbar/MainToolbarElementAttribute.cs
Normal file
31
Editor/Toolbar/MainToolbarElementAttribute.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
public class MainToolbarElementAttribute : Attribute
|
||||
{
|
||||
public string Id { get; }
|
||||
public ToolbarAlign Alignment { get; }
|
||||
public int Order { get; }
|
||||
public bool UseRecommendedStyles { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Mark a class derived from VisualElement to be found by toolbar extender
|
||||
/// </summary>
|
||||
/// <param name="id">Id of element. Must be unique. In case of collision, first found is used</param>
|
||||
/// <param name="alignment">Left or right to play buttons. Ignored if inside a group</param>
|
||||
/// <param name="order">Order in which this element will be displayed in toolbar. Ignored if inside a group</param>
|
||||
/// <param name="useRecommendedStyles">True if this element should use recommended styles. Set it to false if you want to style the visual element yourself.</param>
|
||||
/// <param name="name"></param>
|
||||
public MainToolbarElementAttribute(string id, ToolbarAlign alignment = ToolbarAlign.Left,
|
||||
int order = 0,
|
||||
bool useRecommendedStyles = true)
|
||||
{
|
||||
Id = id;
|
||||
Alignment = alignment;
|
||||
Order = order;
|
||||
UseRecommendedStyles = useRecommendedStyles;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/MainToolbarElementAttribute.cs.meta
Normal file
11
Editor/Toolbar/MainToolbarElementAttribute.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4059a4ac36791549810df04f72dcc75
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
179
Editor/Toolbar/MainToolbarElementOverrideApplier.cs
Normal file
179
Editor/Toolbar/MainToolbarElementOverrideApplier.cs
Normal file
@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class MainToolbarElementOverrideApplier
|
||||
{
|
||||
private class HiddenRemovedElement
|
||||
{
|
||||
public VisualElement RemovedVisualElement;
|
||||
public VisualElement Parent;
|
||||
public int Index;
|
||||
}
|
||||
|
||||
private static readonly string[] EXCEPTIONAL_ELEMENTS_FOR_VISIBILITY =
|
||||
{
|
||||
UnityNativeElementsIds.ACCOUNT_DROPDOWN_ID,
|
||||
UnityNativeElementsIds.CLOUD_BUTTON_ID
|
||||
};
|
||||
private readonly IMainToolbarElementOverrideRepository _mainToolbarElementOverrideRepository;
|
||||
private MainToolbarElement[] _mainToolbarElements = new MainToolbarElement[0];
|
||||
private NativeToolbarElement[] _nativeElements = new NativeToolbarElement[0];
|
||||
private readonly Dictionary<string, MainToolbarElementOverride> _nativeElementsInitialState = new Dictionary<string, MainToolbarElementOverride>();
|
||||
private readonly Dictionary<string, HiddenRemovedElement> _hiddenElementsByRemotion = new Dictionary<string, HiddenRemovedElement>();
|
||||
|
||||
public MainToolbarElementOverrideApplier(IMainToolbarElementOverrideRepository mainToolbarElementOverrideRepository)
|
||||
{
|
||||
_mainToolbarElementOverrideRepository = mainToolbarElementOverrideRepository;
|
||||
}
|
||||
|
||||
public void SetNativeElements(NativeToolbarElement[] nativeElements)
|
||||
{
|
||||
_nativeElements = nativeElements.ToArray();
|
||||
|
||||
SaveNativeElementsInitialState();
|
||||
SetNativeElementsDefaultState(); // necesito hacer esto?
|
||||
}
|
||||
|
||||
public void SetCustomElements(MainToolbarElement[] mainToolbarElements)
|
||||
{
|
||||
_mainToolbarElements = mainToolbarElements.ToArray();
|
||||
}
|
||||
|
||||
public void ApplyOverrides()
|
||||
{
|
||||
SetNativeElementsDefaultState();
|
||||
|
||||
ApplyOverridesOnCustomElements();
|
||||
ApplyOverridesOnNativeElements();
|
||||
}
|
||||
|
||||
private void ApplyOverridesOnCustomElements()
|
||||
{
|
||||
foreach (var mainToolbarElement in _mainToolbarElements)
|
||||
{
|
||||
ApplyOverride(mainToolbarElement.Id, mainToolbarElement.VisualElement);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyOverridesOnNativeElements()
|
||||
{
|
||||
foreach (var nativeElement in _nativeElements)
|
||||
{
|
||||
ApplyOverride(nativeElement.Id, nativeElement.VisualElement);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveNativeElementsInitialState()
|
||||
{
|
||||
if (_nativeElementsInitialState.Count > 0)
|
||||
return;
|
||||
|
||||
foreach (var nativeElement in _nativeElements)
|
||||
{
|
||||
_nativeElementsInitialState[nativeElement.Id] =
|
||||
new MainToolbarElementOverride(
|
||||
nativeElement.Id,
|
||||
nativeElement.VisualElement.resolvedStyle.display == DisplayStyle.Flex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetNativeElementsDefaultState()
|
||||
{
|
||||
foreach (var nativeElement in _nativeElements)
|
||||
{
|
||||
var defaultStateOverride = _nativeElementsInitialState[nativeElement.Id];
|
||||
|
||||
ApplyOverride(nativeElement, defaultStateOverride);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyOverride(NativeToolbarElement nativeElement, MainToolbarElementOverride overrideData)
|
||||
{
|
||||
ApplyVisibilityOverride(nativeElement.Id, nativeElement.VisualElement, overrideData.Visible);
|
||||
}
|
||||
|
||||
private void ApplyOverride(string id, VisualElement visualElement)
|
||||
{
|
||||
var userOverride = _mainToolbarElementOverrideRepository
|
||||
.Get(id);
|
||||
|
||||
if (userOverride == null)
|
||||
return;
|
||||
|
||||
ApplyVisibilityOverride(id, visualElement, userOverride.Value.Visible);
|
||||
}
|
||||
|
||||
private void ApplyVisibilityOverride(string elementId, VisualElement visualElement, bool visible)
|
||||
{
|
||||
if (IsExceptionElementForVisibility(elementId))
|
||||
HandleVisibilityApplicationOnExceptions(elementId, visualElement, visible);
|
||||
else
|
||||
visualElement.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
}
|
||||
|
||||
private bool IsExceptionElementForVisibility(string elementId)
|
||||
{
|
||||
return EXCEPTIONAL_ELEMENTS_FOR_VISIBILITY.Contains(elementId);
|
||||
}
|
||||
|
||||
private void HandleVisibilityApplicationOnExceptions(string elementId, VisualElement visualElement, bool visible)
|
||||
{
|
||||
if (visible)
|
||||
HandleExceptionalElementVisibleCase(elementId, visualElement);
|
||||
else
|
||||
HandleExceptionalElementInvisibleCase(elementId, visualElement);
|
||||
}
|
||||
|
||||
private void HandleExceptionalElementInvisibleCase(string elementId, VisualElement visualElement)
|
||||
{
|
||||
var parent = visualElement.parent;
|
||||
var index = parent.IndexOf(visualElement);
|
||||
|
||||
if (parent.Contains(visualElement))
|
||||
parent.Remove(visualElement);
|
||||
|
||||
if (!_hiddenElementsByRemotion.ContainsKey(elementId))
|
||||
_hiddenElementsByRemotion.Add(elementId, new HiddenRemovedElement()
|
||||
{
|
||||
RemovedVisualElement = visualElement,
|
||||
Parent = parent,
|
||||
Index = index
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleExceptionalElementVisibleCase(string elementId, VisualElement visualElement)
|
||||
{
|
||||
if (_hiddenElementsByRemotion.ContainsKey(elementId))
|
||||
{
|
||||
var removedElement = _hiddenElementsByRemotion[elementId];
|
||||
|
||||
var parent = removedElement.Parent;
|
||||
|
||||
if (!parent.Contains(visualElement))
|
||||
{
|
||||
var bestIndex = GetIndexEqualOrLessThan(removedElement.Index, parent);
|
||||
|
||||
parent.Insert(bestIndex, visualElement);
|
||||
}
|
||||
|
||||
_hiddenElementsByRemotion.Remove(elementId);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetIndexEqualOrLessThan(int removedElementIndex, VisualElement parent)
|
||||
{
|
||||
for (int i = parent.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
if (removedElementIndex <= i)
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/MainToolbarElementOverrideApplier.cs.meta
Normal file
11
Editor/Toolbar/MainToolbarElementOverrideApplier.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24d310911f14d4d45a02bd5586c371bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
16
Editor/Toolbar/NativeToolbarElement.cs
Normal file
16
Editor/Toolbar/NativeToolbarElement.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class NativeToolbarElement
|
||||
{
|
||||
public string Id { get; }
|
||||
public VisualElement VisualElement { get; }
|
||||
|
||||
public NativeToolbarElement(string id, VisualElement visualElement)
|
||||
{
|
||||
Id = id;
|
||||
VisualElement = visualElement;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/NativeToolbarElement.cs.meta
Normal file
11
Editor/Toolbar/NativeToolbarElement.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b9dec15dbb8eea42b0c2254ce4b7177
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Toolbar/Override.meta
Normal file
8
Editor/Toolbar/Override.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f722a3e209ed5649a219e2282177125
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal interface IMainToolbarElementOverrideRepository
|
||||
{
|
||||
public MainToolbarElementOverride? Get(string elementId);
|
||||
public MainToolbarElementOverride[] GetAll();
|
||||
public void Save(MainToolbarElementOverride elementOverride);
|
||||
public void Clear();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 280c883dcd1944448a1b93cecc8877f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
14
Editor/Toolbar/Override/MainToolbarElementOverride.cs
Normal file
14
Editor/Toolbar/Override/MainToolbarElementOverride.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal readonly struct MainToolbarElementOverride
|
||||
{
|
||||
public string ElementId { get; }
|
||||
public bool Visible { get; }
|
||||
|
||||
public MainToolbarElementOverride(string elementId, bool visible)
|
||||
{
|
||||
ElementId = elementId;
|
||||
Visible = visible;
|
||||
}
|
||||
}
|
||||
}
|
11
Editor/Toolbar/Override/MainToolbarElementOverride.cs.meta
Normal file
11
Editor/Toolbar/Override/MainToolbarElementOverride.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e51009f5c83b62f419eee2089fd6e63f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Unity.Serialization.Json;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class UserSettingsFileMainToolbarElementOverrideRepository : IMainToolbarElementOverrideRepository
|
||||
{
|
||||
private static readonly string DIRECTORY = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "UserSettings/", "unity-toolbar-extender-ui-toolkit", "overrides");
|
||||
private static readonly string FILE = Path.Combine(DIRECTORY, "overrides.json");
|
||||
|
||||
private struct SerializableOverride
|
||||
{
|
||||
public string ElementId;
|
||||
public bool Visible;
|
||||
}
|
||||
|
||||
private Dictionary<string, MainToolbarElementOverride> _overrides = new Dictionary<string, MainToolbarElementOverride>();
|
||||
|
||||
public UserSettingsFileMainToolbarElementOverrideRepository()
|
||||
{
|
||||
_overrides = LoadOverrides();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_overrides.Clear();
|
||||
DeleteSave();
|
||||
}
|
||||
|
||||
public MainToolbarElementOverride? Get(string elementId)
|
||||
{
|
||||
if(_overrides.ContainsKey(elementId))
|
||||
return _overrides[elementId];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public MainToolbarElementOverride[] GetAll()
|
||||
{
|
||||
return _overrides.Values.ToArray();
|
||||
}
|
||||
|
||||
public void Save(MainToolbarElementOverride elementOverride)
|
||||
{
|
||||
_overrides[elementOverride.ElementId] = elementOverride;
|
||||
SaveOverrides();
|
||||
}
|
||||
|
||||
private MainToolbarElementOverride FromSerialized(SerializableOverride serializableOverride)
|
||||
{
|
||||
return new MainToolbarElementOverride(serializableOverride.ElementId, serializableOverride.Visible);
|
||||
}
|
||||
|
||||
private SerializableOverride ToSerialized(MainToolbarElementOverride mainToolbarElementOverride)
|
||||
{
|
||||
return new SerializableOverride() {
|
||||
ElementId = mainToolbarElementOverride.ElementId,
|
||||
Visible = mainToolbarElementOverride.Visible
|
||||
};
|
||||
}
|
||||
|
||||
private void DeleteSave()
|
||||
{
|
||||
File.Delete(FILE);
|
||||
}
|
||||
|
||||
private Dictionary<string, MainToolbarElementOverride> LoadOverrides()
|
||||
{
|
||||
if (!Directory.Exists(DIRECTORY))
|
||||
Directory.CreateDirectory(DIRECTORY);
|
||||
|
||||
if (!File.Exists(FILE))
|
||||
return JsonSerialization.FromJson<Dictionary<string, MainToolbarElementOverride>>("{}");
|
||||
|
||||
var json = File.ReadAllText(FILE);
|
||||
|
||||
var serializedDictionary = JsonSerialization.FromJson<Dictionary<string, SerializableOverride>>(json);
|
||||
|
||||
return serializedDictionary.Values
|
||||
.ToDictionary(serializedOverride => serializedOverride.ElementId,
|
||||
serializedOverride => FromSerialized(serializedOverride));
|
||||
}
|
||||
|
||||
private void SaveOverrides()
|
||||
{
|
||||
var serializableDictionary = _overrides.Values.ToDictionary(
|
||||
mainToolbarElementOverride => mainToolbarElementOverride.ElementId,
|
||||
mainToolbarElementOverride => ToSerialized(mainToolbarElementOverride)
|
||||
);
|
||||
|
||||
var json = JsonSerialization.ToJson(serializableDictionary);
|
||||
|
||||
File.WriteAllText(FILE, json);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 267c04a3d47600c488137859ea7af2a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef
Normal file
18
Editor/Toolbar/Paps.UnityToolbarExtenderUIToolkit.asmdef
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Paps.UnityToolbarExtenderUIToolkit",
|
||||
"rootNamespace": "Paps.UnityToolbarExtenderUIToolkit",
|
||||
"references": [
|
||||
"Unity.Serialization"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d62da4aabd2a19419c7378d23ea5849
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Editor/Toolbar/RecommendedStyles.meta
Normal file
8
Editor/Toolbar/RecommendedStyles.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21a21acb2ce38fb46bd178a11e0cc483
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
19
Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs
Normal file
19
Editor/Toolbar/RecommendedStyles/ButtonRecommendedStyle.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class ButtonRecommendedStyle : RecommendedStyle
|
||||
{
|
||||
private Button _button;
|
||||
|
||||
public ButtonRecommendedStyle(Button button)
|
||||
{
|
||||
_button = button;
|
||||
}
|
||||
|
||||
protected override void ApplyRootElementStyle()
|
||||
{
|
||||
_button.style.overflow = Overflow.Visible;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcaec52f220ee13458fa862e8f9f31b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,20 @@
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class ColorFieldRecommendedStyle : RecommendedStyle
|
||||
{
|
||||
private readonly ColorField _colorField;
|
||||
|
||||
public ColorFieldRecommendedStyle(ColorField colorField)
|
||||
{
|
||||
_colorField = colorField;
|
||||
}
|
||||
|
||||
protected override void ApplyRootElementStyle()
|
||||
{
|
||||
_colorField.labelElement.style.minWidth = Length.Auto();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee22b5ac49a830e4a8e35f5e98b656d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,27 @@
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Paps.UnityToolbarExtenderUIToolkit
|
||||
{
|
||||
internal class DropdownFieldRecommendedStyle : RecommendedStyle
|
||||
{
|
||||
private DropdownField _dropdownField;
|
||||
|
||||
public DropdownFieldRecommendedStyle(DropdownField dropdownField)
|
||||
{
|
||||
_dropdownField = dropdownField;
|
||||
}
|
||||
|
||||
protected override void ApplyRootElementStyle()
|
||||
{
|
||||
_dropdownField.labelElement.style.minWidth = Length.Auto();
|
||||
|
||||
var inputFieldIndex = 1;
|
||||
|
||||
if (string.IsNullOrEmpty(_dropdownField.label))
|
||||
inputFieldIndex = 0;
|
||||
|
||||
var inputElement = _dropdownField[inputFieldIndex];
|
||||
inputElement.style.overflow = Overflow.Visible;
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user