Skip to content

Commit c86a67f

Browse files
authored
Merge pull request #87 from arimger/develop
Develop - 0.12.6
2 parents 830e64c + 4c23c46 commit c86a67f

File tree

7 files changed

+63
-35
lines changed

7 files changed

+63
-35
lines changed

Assets/Editor Toolbox/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.12.6 [19.10.2023]
2+
3+
### Changed:
4+
- Fix ToolboxEditorToolbar in Unity 2021.1+
5+
- Minor API changes in the SearchablePopup class
6+
17
## 0.12.5 [11.09.2023]
28

39
### Changed:

Assets/Editor Toolbox/Editor/Internal/SearchablePopup.cs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ public class SearchablePopup : PopupWindowContent
1717
/// <summary>
1818
/// Creates searchable popup using given properties.
1919
/// </summary>
20-
public static void Show(Rect activatorRect, int current, string[] options, Action<int> onSelect)
20+
public static void Show(Rect activatorRect, int current, IReadOnlyList<string> options, Action<int> onSelect)
2121
{
2222
PopupWindow.Show(activatorRect, new SearchablePopup(activatorRect, current, options, onSelect));
2323
}
2424

25-
2625
private readonly Action<int> onSelect;
2726

2827
private readonly SearchArray searchArray;
@@ -35,12 +34,11 @@ public static void Show(Rect activatorRect, int current, string[] options, Actio
3534
private Rect activatorRect;
3635
private Rect toolbarRect;
3736
private Rect contentRect;
38-
3937

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

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

60-
6158
private void SelectItem(int index)
6259
{
6360
onSelect(index);
@@ -228,7 +225,6 @@ public override void OnGUI(Rect rect)
228225
GUI.enabled = false;
229226
}
230227

231-
232228
private class SearchArray
233229
{
234230
public struct Item
@@ -243,19 +239,16 @@ public Item(int index, string label)
243239
}
244240
}
245241

246-
247242
private readonly List<Item> items;
248-
private readonly string[] options;
243+
private readonly IReadOnlyList<string> options;
249244

250-
251-
public SearchArray(string[] options)
245+
public SearchArray(IReadOnlyList<string> options)
252246
{
253247
this.options = options;
254248
items = new List<Item>();
255249
Search(string.Empty);
256250
}
257251

258-
259252
public bool Search(string filter)
260253
{
261254
if (Filter == filter)
@@ -265,7 +258,8 @@ public bool Search(string filter)
265258

266259
items.Clear();
267260
var simplifiedFilter = filter.ToLower();
268-
for (var i = 0; i < options.Length; i++)
261+
var optionsCount = options.Count;
262+
for (var i = 0; i < optionsCount; i++)
269263
{
270264
var option = options[i];
271265
if (string.IsNullOrEmpty(filter) || option.ToLower().Contains(simplifiedFilter))
@@ -291,7 +285,6 @@ public Item GetItemAt(int index)
291285
return items[index];
292286
}
293287

294-
295288
public int ItemsCount => items.Count;
296289

297290
public string Filter { get; private set; }

Assets/Editor Toolbox/Editor/ToolboxEditorToolbar.cs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ static ToolboxEditorToolbar()
2929
EditorCoroutineUtility.StartCoroutineOwnerless(Initialize());
3030
}
3131

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

5049
private static Object toolbar;
5150

52-
5351
private static IEnumerator Initialize()
5452
{
55-
while (toolbar == null)
53+
while (ToolboxEditorToolbar.toolbar == null)
5654
{
57-
//try to find aldready created Toolbar object
5855
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
5956
if (toolbars == null || toolbars.Length == 0)
6057
{
@@ -63,9 +60,31 @@ private static IEnumerator Initialize()
6360
}
6461
else
6562
{
66-
toolbar = toolbars[0];
63+
ToolboxEditorToolbar.toolbar = toolbars[0];
6764
}
6865
}
66+
67+
#if UNITY_2021_1_OR_NEWER
68+
var rootField = ToolboxEditorToolbar.toolbar.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
69+
var root = rootField.GetValue(ToolboxEditorToolbar.toolbar) as VisualElement;
70+
var toolbar = root.Q("ToolbarZoneLeftAlign");
71+
72+
var element = new VisualElement()
73+
{
74+
style =
75+
{
76+
flexGrow = 1,
77+
flexDirection = FlexDirection.Row,
78+
}
79+
};
80+
81+
var container = new IMGUIContainer();
82+
container.style.flexGrow = 1;
83+
container.onGUIHandler += OnGui;
84+
85+
element.Add(container);
86+
toolbar.Add(element);
87+
#else
6988
#if UNITY_2020_1_OR_NEWER
7089
var backend = guiBackend.GetValue(toolbar);
7190
var elements = visualTree.GetValue(backend, null) as VisualElement;
@@ -78,11 +97,11 @@ private static IEnumerator Initialize()
7897
#else
7998
var container = elements[0] as IMGUIContainer;
8099
#endif
81-
//create additional gui handler for new elements
82100
var handler = onGuiHandler.GetValue(container) as Action;
83101
handler -= OnGui;
84102
handler += OnGui;
85103
onGuiHandler.SetValue(container, handler);
104+
#endif
86105
}
87106

88107
private static void OnGui()
@@ -92,12 +111,17 @@ private static void OnGui()
92111
return;
93112
}
94113

114+
#if UNITY_2021_1_OR_NEWER
115+
using (new GUILayout.HorizontalScope())
116+
{
117+
OnToolbarGui.Invoke();
118+
}
119+
#else
95120
var screenWidth = EditorGUIUtility.currentViewWidth;
96121
var toolbarRect = new Rect(0, 0, screenWidth, Style.rowHeight);
97122
//calculations known from UnityCsReference
98123
toolbarRect.xMin += FromToolsOffset;
99124
toolbarRect.xMax = (screenWidth - FromStripOffset) / 2;
100-
//additional rect styling
101125
toolbarRect.xMin += Style.spacing;
102126
toolbarRect.xMax -= Style.spacing;
103127
toolbarRect.yMin += Style.topPadding;
@@ -108,14 +132,14 @@ private static void OnGui()
108132
return;
109133
}
110134

111-
//begin drawing in calculated area
112135
using (new GUILayout.AreaScope(toolbarRect))
113136
{
114137
using (new GUILayout.HorizontalScope())
115138
{
116139
OnToolbarGui?.Invoke();
117140
}
118141
}
142+
#endif
119143
}
120144

121145

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

127-
128151
public static event Action OnToolbarGui;
129152

130-
131153
private static class Style
132154
{
133155
internal static readonly float rowHeight = 30.0f;

Assets/Editor Toolbox/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,10 @@ public SerializedScene scene;
731731
```
732732
![inspector](https://github.com/arimger/Unity-Editor-Toolbox/blob/develop/Docs/scenedetails.png)
733733
734+
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.
735+
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.
736+
You can link SerializedScene in a ScriptableObject and trigger reserialization (`EditorUtility.SetDirty()`) if needed, it's really convinient approach.
737+
734738
#### SerializedDictionary<TK, TV>
735739

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

Assets/Editor Toolbox/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "com.browar.editor-toolbox",
33
"displayName": "Editor Toolbox",
4-
"version": "0.12.5",
4+
"version": "0.12.6",
55
"unity": "2018.1",
66
"description": "Tools, custom attributes, drawers, hierarchy overlay, and other extensions for the Unity Editor.",
77
"keywords": [

Assets/Examples/Editor/SampleToolbar.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
using UnityEngine;
2-
using UnityEngine.SceneManagement;
1+
using Toolbox.Editor;
32
using UnityEditor;
43
using UnityEditor.SceneManagement;
5-
6-
using Toolbox.Editor;
4+
using UnityEngine;
5+
using UnityEngine.SceneManagement;
76

87
[InitializeOnLoad]
98
public static class SampleToolbar
@@ -13,7 +12,6 @@ public static class SampleToolbar
1312
/// </summary>
1413
private readonly static string mySampleSceneName = "SampleScene";
1514

16-
1715
static SampleToolbar()
1816
{
1917
EditorSceneManager.sceneOpened -= SceneOpenedCallback;
@@ -23,7 +21,6 @@ static SampleToolbar()
2321
EditorApplication.update += ValidateFirstScene;
2422
}
2523

26-
2724
/// <summary>
2825
/// This method is used to validate first scene after Editor launch.
2926
/// </summary>
@@ -35,8 +32,8 @@ private static void ValidateFirstScene()
3532
}
3633

3734
EditorApplication.update -= ValidateFirstScene;
38-
39-
SceneOpenedCallback(SceneManager.GetActiveScene(), OpenSceneMode.Single);
35+
var activeScene = SceneManager.GetActiveScene();
36+
SceneOpenedCallback(activeScene, OpenSceneMode.Single);
4037
}
4138

4239
/// <summary>
@@ -51,10 +48,10 @@ private static void SceneOpenedCallback(Scene scene, OpenSceneMode mode)
5148
{
5249
return;
5350
}
51+
5452
ToolboxEditorToolbar.OnToolbarGui += OnToolbarGui;
5553
}
5654

57-
5855
/// <summary>
5956
/// Layout-based GUI call.
6057
/// </summary>
@@ -65,21 +62,23 @@ private static void OnToolbarGui()
6562
{
6663
Debug.Log("1");
6764
}
65+
6866
if (GUILayout.Button(Style.sampleContent1, Style.commandMidStyle))
6967
{
7068
Debug.Log("2");
7169
}
70+
7271
if (GUILayout.Button(Style.sampleContent2, Style.commandMidStyle))
7372
{
7473
Debug.Log("3");
7574
}
75+
7676
if (GUILayout.Button("4", Style.commandRightStyle))
7777
{
7878
Debug.Log("4");
7979
}
8080
}
8181

82-
8382
private static class Style
8483
{
8584
internal static readonly GUIStyle commandMidStyle = new GUIStyle("CommandMid")

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,10 @@ public SerializedScene scene;
731731
```
732732
![inspector](https://github.com/arimger/Unity-Editor-Toolbox/blob/develop/Docs/scenedetails.png)
733733
734+
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.
735+
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.
736+
You can link SerializedScene in a ScriptableObject and trigger reserialization (`EditorUtility.SetDirty()`) if needed, it's really convinient approach.
737+
734738
#### SerializedDictionary<TK, TV>
735739

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

0 commit comments

Comments
 (0)