Skip to content

Commit

Permalink
Merge pull request #87 from arimger/develop
Browse files Browse the repository at this point in the history
Develop - 0.12.6
  • Loading branch information
arimger authored Oct 19, 2023
2 parents 830e64c + 4c23c46 commit c86a67f
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 35 deletions.
6 changes: 6 additions & 0 deletions Assets/Editor Toolbox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.12.6 [19.10.2023]

### Changed:
- Fix ToolboxEditorToolbar in Unity 2021.1+
- Minor API changes in the SearchablePopup class

## 0.12.5 [11.09.2023]

### Changed:
Expand Down
21 changes: 7 additions & 14 deletions Assets/Editor Toolbox/Editor/Internal/SearchablePopup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ public class SearchablePopup : PopupWindowContent
/// <summary>
/// Creates searchable popup using given properties.
/// </summary>
public static void Show(Rect activatorRect, int current, string[] options, Action<int> onSelect)
public static void Show(Rect activatorRect, int current, IReadOnlyList<string> options, Action<int> onSelect)
{
PopupWindow.Show(activatorRect, new SearchablePopup(activatorRect, current, options, onSelect));
}


private readonly Action<int> onSelect;

private readonly SearchArray searchArray;
Expand All @@ -35,12 +34,11 @@ public static void Show(Rect activatorRect, int current, string[] options, Actio
private Rect activatorRect;
private Rect toolbarRect;
private Rect contentRect;


/// <summary>
/// Constructor should be called only internally by the <see cref="Show(Rect, int, string[], Action{int})"/> method.
/// Constructor should be called only internally by the <see cref="Show(Rect, int, IReadOnlyList{String}, Action{int})"/> method.
/// </summary>
private SearchablePopup(Rect activatorRect, int startIndex, string[] options, Action<int> onSelect)
private SearchablePopup(Rect activatorRect, int startIndex, IReadOnlyList<string> options, Action<int> onSelect)
{
this.activatorRect = activatorRect;

Expand All @@ -57,7 +55,6 @@ private SearchablePopup(Rect activatorRect, int startIndex, string[] options, Ac
};
}


private void SelectItem(int index)
{
onSelect(index);
Expand Down Expand Up @@ -228,7 +225,6 @@ public override void OnGUI(Rect rect)
GUI.enabled = false;
}


private class SearchArray
{
public struct Item
Expand All @@ -243,19 +239,16 @@ public Item(int index, string label)
}
}


private readonly List<Item> items;
private readonly string[] options;
private readonly IReadOnlyList<string> options;


public SearchArray(string[] options)
public SearchArray(IReadOnlyList<string> options)
{
this.options = options;
items = new List<Item>();
Search(string.Empty);
}


public bool Search(string filter)
{
if (Filter == filter)
Expand All @@ -265,7 +258,8 @@ public bool Search(string filter)

items.Clear();
var simplifiedFilter = filter.ToLower();
for (var i = 0; i < options.Length; i++)
var optionsCount = options.Count;
for (var i = 0; i < optionsCount; i++)
{
var option = options[i];
if (string.IsNullOrEmpty(filter) || option.ToLower().Contains(simplifiedFilter))
Expand All @@ -291,7 +285,6 @@ public Item GetItemAt(int index)
return items[index];
}


public int ItemsCount => items.Count;

public string Filter { get; private set; }
Expand Down
42 changes: 32 additions & 10 deletions Assets/Editor Toolbox/Editor/ToolboxEditorToolbar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ static ToolboxEditorToolbar()
EditorCoroutineUtility.StartCoroutineOwnerless(Initialize());
}


private static readonly Type containterType = typeof(IMGUIContainer);
private static readonly Type toolbarType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.Toolbar");
private static readonly Type guiViewType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.GUIView");
Expand All @@ -49,12 +48,10 @@ static ToolboxEditorToolbar()

private static Object toolbar;


private static IEnumerator Initialize()
{
while (toolbar == null)
while (ToolboxEditorToolbar.toolbar == null)
{
//try to find aldready created Toolbar object
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
if (toolbars == null || toolbars.Length == 0)
{
Expand All @@ -63,9 +60,31 @@ private static IEnumerator Initialize()
}
else
{
toolbar = toolbars[0];
ToolboxEditorToolbar.toolbar = toolbars[0];
}
}

#if UNITY_2021_1_OR_NEWER
var rootField = ToolboxEditorToolbar.toolbar.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
var root = rootField.GetValue(ToolboxEditorToolbar.toolbar) as VisualElement;
var toolbar = root.Q("ToolbarZoneLeftAlign");

var element = new VisualElement()
{
style =
{
flexGrow = 1,
flexDirection = FlexDirection.Row,
}
};

var container = new IMGUIContainer();
container.style.flexGrow = 1;
container.onGUIHandler += OnGui;

element.Add(container);
toolbar.Add(element);
#else
#if UNITY_2020_1_OR_NEWER
var backend = guiBackend.GetValue(toolbar);
var elements = visualTree.GetValue(backend, null) as VisualElement;
Expand All @@ -78,11 +97,11 @@ private static IEnumerator Initialize()
#else
var container = elements[0] as IMGUIContainer;
#endif
//create additional gui handler for new elements
var handler = onGuiHandler.GetValue(container) as Action;
handler -= OnGui;
handler += OnGui;
onGuiHandler.SetValue(container, handler);
#endif
}

private static void OnGui()
Expand All @@ -92,12 +111,17 @@ private static void OnGui()
return;
}

#if UNITY_2021_1_OR_NEWER
using (new GUILayout.HorizontalScope())
{
OnToolbarGui.Invoke();
}
#else
var screenWidth = EditorGUIUtility.currentViewWidth;
var toolbarRect = new Rect(0, 0, screenWidth, Style.rowHeight);
//calculations known from UnityCsReference
toolbarRect.xMin += FromToolsOffset;
toolbarRect.xMax = (screenWidth - FromStripOffset) / 2;
//additional rect styling
toolbarRect.xMin += Style.spacing;
toolbarRect.xMax -= Style.spacing;
toolbarRect.yMin += Style.topPadding;
Expand All @@ -108,14 +132,14 @@ private static void OnGui()
return;
}

//begin drawing in calculated area
using (new GUILayout.AreaScope(toolbarRect))
{
using (new GUILayout.HorizontalScope())
{
OnToolbarGui?.Invoke();
}
}
#endif
}


Expand All @@ -124,10 +148,8 @@ private static void OnGui()
public static float FromToolsOffset { get; set; } = 400.0f;
public static float FromStripOffset { get; set; } = 150.0f;


public static event Action OnToolbarGui;


private static class Style
{
internal static readonly float rowHeight = 30.0f;
Expand Down
4 changes: 4 additions & 0 deletions Assets/Editor Toolbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,10 @@ public SerializedScene scene;
```
![inspector](https://github.com/arimger/Unity-Editor-Toolbox/blob/develop/Docs/scenedetails.png)
Keep in mind that SerializedScene stores Scene's index, name and path. These properties are updated each time scenes collection in the Build Settings is updated or any SceneAsset is created/removed/reimported.
Unfortunately, you need to handle associated objects reserialization by yourself, otherwise e.g. updated indexes won't be saved. I prepared for you a static event `SceneSerializationUtility.OnCacheRefreshed` that can be used to validate SerializedScenes in your project.
You can link SerializedScene in a ScriptableObject and trigger reserialization (`EditorUtility.SetDirty()`) if needed, it's really convinient approach.

#### SerializedDictionary<TK, TV>

Allows to serialize and use Dictionaries. The presented class implements the IDictionary interface, so it can be easily used like the standard version.
Expand Down
2 changes: 1 addition & 1 deletion Assets/Editor Toolbox/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "com.browar.editor-toolbox",
"displayName": "Editor Toolbox",
"version": "0.12.5",
"version": "0.12.6",
"unity": "2018.1",
"description": "Tools, custom attributes, drawers, hierarchy overlay, and other extensions for the Unity Editor.",
"keywords": [
Expand Down
19 changes: 9 additions & 10 deletions Assets/Examples/Editor/SampleToolbar.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using Toolbox.Editor;
using UnityEditor;
using UnityEditor.SceneManagement;

using Toolbox.Editor;
using UnityEngine;
using UnityEngine.SceneManagement;

[InitializeOnLoad]
public static class SampleToolbar
Expand All @@ -13,7 +12,6 @@ public static class SampleToolbar
/// </summary>
private readonly static string mySampleSceneName = "SampleScene";


static SampleToolbar()
{
EditorSceneManager.sceneOpened -= SceneOpenedCallback;
Expand All @@ -23,7 +21,6 @@ static SampleToolbar()
EditorApplication.update += ValidateFirstScene;
}


/// <summary>
/// This method is used to validate first scene after Editor launch.
/// </summary>
Expand All @@ -35,8 +32,8 @@ private static void ValidateFirstScene()
}

EditorApplication.update -= ValidateFirstScene;

SceneOpenedCallback(SceneManager.GetActiveScene(), OpenSceneMode.Single);
var activeScene = SceneManager.GetActiveScene();
SceneOpenedCallback(activeScene, OpenSceneMode.Single);
}

/// <summary>
Expand All @@ -51,10 +48,10 @@ private static void SceneOpenedCallback(Scene scene, OpenSceneMode mode)
{
return;
}

ToolboxEditorToolbar.OnToolbarGui += OnToolbarGui;
}


/// <summary>
/// Layout-based GUI call.
/// </summary>
Expand All @@ -65,21 +62,23 @@ private static void OnToolbarGui()
{
Debug.Log("1");
}

if (GUILayout.Button(Style.sampleContent1, Style.commandMidStyle))
{
Debug.Log("2");
}

if (GUILayout.Button(Style.sampleContent2, Style.commandMidStyle))
{
Debug.Log("3");
}

if (GUILayout.Button("4", Style.commandRightStyle))
{
Debug.Log("4");
}
}


private static class Style
{
internal static readonly GUIStyle commandMidStyle = new GUIStyle("CommandMid")
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,10 @@ public SerializedScene scene;
```
![inspector](https://github.com/arimger/Unity-Editor-Toolbox/blob/develop/Docs/scenedetails.png)
Keep in mind that SerializedScene stores Scene's index, name and path. These properties are updated each time scenes collection in the Build Settings is updated or any SceneAsset is created/removed/reimported.
Unfortunately, you need to handle associated objects reserialization by yourself, otherwise e.g. updated indexes won't be saved. I prepared for you a static event `SceneSerializationUtility.OnCacheRefreshed` that can be used to validate SerializedScenes in your project.
You can link SerializedScene in a ScriptableObject and trigger reserialization (`EditorUtility.SetDirty()`) if needed, it's really convinient approach.

#### SerializedDictionary<TK, TV>

Allows to serialize and use Dictionaries. The presented class implements the IDictionary interface, so it can be easily used like the standard version.
Expand Down

0 comments on commit c86a67f

Please sign in to comment.