Skip to content

Commit 8884626

Browse files
committed
feat: convert gui to odin in BlockLibraryWindow
1 parent a12301f commit 8884626

File tree

5 files changed

+154
-151
lines changed

5 files changed

+154
-151
lines changed

Assets/Code/LevelEditor/BlockLibraryWindow.cs

Lines changed: 105 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,87 @@
22
using UnityEngine;
33
using System;
44
using System.Collections.Generic;
5+
using Sirenix.OdinInspector;
6+
using Sirenix.OdinInspector.Editor;
7+
using Sirenix.Utilities.Editor;
58

69
namespace Code.LevelEditor.Editor
710
{
8-
public class BlockLibraryWindow : EditorWindow
11+
public class BlockLibraryWindow : OdinEditorWindow
912
{
13+
[MenuItem("Tools/Block Library 🧱")]
14+
public static void ShowWindow()
15+
{
16+
var window = GetWindow<BlockLibraryWindow>(false, "Block Library", true);
17+
window.minSize = new Vector2(400, 500);
18+
}
19+
20+
[BoxGroup("📦 Block Library", centerLabel: true)]
21+
[ReadOnly, ShowInInspector, HideLabel]
1022
private BlockLibrary _blockLibrary;
1123

24+
[BoxGroup("🧱 Create Block", centerLabel: true)]
25+
[LabelText("Block ID")] [ShowInInspector]
1226
private string _newBlockId = "";
27+
[BoxGroup("🧱 Create Block")]
28+
[LabelText("Icon")] [ShowInInspector]
1329
private Sprite _newBlockSprite;
30+
[BoxGroup("🧱 Create Block")]
31+
[LabelText("Prefab")] [ShowInInspector]
1432
private GameObject _newBlockPrefab;
1533

16-
private Vector2 _scrollPosition;
34+
[BoxGroup("🔍 Search & Sort", centerLabel: true)]
35+
[LabelText("Filter")] [ShowInInspector]
1736
private string _searchFilter = "";
18-
19-
private enum SortMode { ByID, ByPrefabName, ByIconName }
37+
[BoxGroup("🔍 Search & Sort")]
38+
[HorizontalGroup("🔍 Search & Sort/SortRow")]
39+
[EnumToggleButtons, HideLabel]
40+
[PropertyOrder(0)]
41+
[SerializeField]
2042
private SortMode _sortMode = SortMode.ByID;
43+
2144
private bool _sortAscending = true;
45+
private Vector2 _scroll;
2246

23-
[MenuItem("Tools/Block Library 🧱")]
24-
public static void ShowWindow()
47+
private enum SortMode
2548
{
26-
var window = GetWindow<BlockLibraryWindow>(false, "Block Library", true);
27-
window.minSize = new Vector2(350, 400);
49+
ByID,
50+
ByPrefabName,
51+
ByIconName
2852
}
2953

30-
private void OnEnable()
54+
protected override void OnEnable()
3155
{
56+
base.OnEnable();
3257
LoadOrCreateLibrary();
3358
}
3459

35-
private void OnGUI()
60+
protected override void DrawEditor(int index)
3661
{
62+
base.DrawEditor(index);
63+
3764
if (_blockLibrary == null)
3865
{
39-
EditorGUILayout.HelpBox("No BlockLibrary asset found.", MessageType.Warning);
66+
SirenixEditorGUI.ErrorMessageBox("No BlockLibrary asset found.");
4067
if (GUILayout.Button("Create BlockLibrary"))
4168
{
4269
CreateLibrary();
4370
}
71+
4472
return;
4573
}
4674

47-
DrawSearchField();
48-
DrawSortControls();
49-
5075
GUILayout.Space(10);
51-
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
76+
77+
SirenixEditorGUI.BeginBox();
78+
SirenixEditorGUI.BeginBoxHeader();
79+
SirenixEditorGUI.Title("📦 Existing Blocks", null, TextAlignment.Center, true);
80+
SirenixEditorGUI.EndBoxHeader();
81+
_scroll = EditorGUILayout.BeginScrollView(_scroll);
5282
DrawExistingBlocks();
83+
GUILayout.FlexibleSpace();
5384
EditorGUILayout.EndScrollView();
54-
55-
GUILayout.Space(15);
56-
DrawCreateBlockSection();
85+
SirenixEditorGUI.EndBox();
5786
}
5887

5988
private void LoadOrCreateLibrary()
@@ -85,63 +114,59 @@ private void CreateLibrary()
85114
Debug.Log("✅ BlockLibrary created at " + path);
86115
}
87116

88-
private void DrawSearchField()
89-
{
90-
GUILayout.Label("Search Blocks", EditorStyles.boldLabel);
91-
_searchFilter = EditorGUILayout.TextField("Filter", _searchFilter);
92-
}
93-
94-
private void DrawSortControls()
117+
[HorizontalGroup("🔍 Search & Sort/SortRow", width: 25)]
118+
[Button("@_sortAscending ? \"\" : \"\"", ButtonSizes.Medium)]
119+
[PropertyOrder(1)]
120+
private void ToggleSortDirection()
95121
{
96-
GUILayout.BeginHorizontal("box");
97-
GUILayout.Label("Sort By:", GUILayout.Width(60));
98-
_sortMode = (SortMode)EditorGUILayout.EnumPopup(_sortMode);
99-
100-
string arrow = _sortAscending ? "▲" : "▼";
101-
if (GUILayout.Button(arrow, GUILayout.Width(25)))
102-
{
103-
_sortAscending = !_sortAscending;
104-
}
105-
GUILayout.EndHorizontal();
122+
_sortAscending = !_sortAscending;
106123
}
107124

108125
private void DrawExistingBlocks()
109126
{
110-
GUILayout.Label("Existing Blocks", EditorStyles.boldLabel);
111-
112127
if (_blockLibrary.AllBlocks == null || _blockLibrary.AllBlocks.Count == 0)
113128
{
114-
GUILayout.Label("No blocks found.");
129+
SirenixEditorGUI.InfoMessageBox("No blocks found.");
115130
return;
116131
}
117132

118-
List<BlockDataEditor> blocksToShow = new List<BlockDataEditor>(_blockLibrary.AllBlocks);
133+
var blocks = new List<BlockDataEditor>(_blockLibrary.AllBlocks);
119134

120135
if (!string.IsNullOrEmpty(_searchFilter))
121136
{
122-
blocksToShow = blocksToShow.FindAll(block =>
123-
block != null && block.ID.ToLower().Contains(_searchFilter.ToLower()));
137+
blocks = blocks.FindAll(b => b != null && b.ID.ToLower().Contains(_searchFilter.ToLower()));
124138
}
125139

126-
SortBlocks();
127-
128-
if (!_sortAscending)
129-
blocksToShow.Reverse();
130-
131-
for (int i = blocksToShow.Count - 1; i >= 0; i--)
140+
blocks.Sort((a, b) =>
132141
{
133-
var block = blocksToShow[i];
134-
if (block == null)
142+
switch (_sortMode)
135143
{
136-
_blockLibrary.AllBlocks.RemoveAt(i);
137-
continue;
144+
case SortMode.ByID: return string.Compare(a.ID, b.ID, StringComparison.OrdinalIgnoreCase);
145+
case SortMode.ByIconName:
146+
return string.Compare(a.Icon?.name ?? "", b.Icon?.name ?? "",
147+
StringComparison.OrdinalIgnoreCase);
148+
case SortMode.ByPrefabName:
149+
return SafeCompare(a.Prefab, b.Prefab);
150+
default: return 0;
138151
}
152+
});
139153

140-
EditorGUILayout.BeginHorizontal("box");
154+
if (!_sortAscending)
155+
blocks.Reverse();
156+
157+
foreach (var block in blocks)
158+
{
159+
if (block == null) continue;
141160

142-
GUILayout.Label(block.Icon != null ? block.Icon.texture : Texture2D.grayTexture,
143-
GUILayout.Width(32), GUILayout.Height(32));
161+
SirenixEditorGUI.BeginBox();
162+
SirenixEditorGUI.BeginBoxHeader();
144163
GUILayout.Label(block.ID);
164+
SirenixEditorGUI.EndBoxHeader();
165+
166+
GUILayout.BeginHorizontal();
167+
168+
GUILayout.Label(block.Icon != null ? block.Icon.texture : Texture2D.grayTexture, GUILayout.Width(32),
169+
GUILayout.Height(32));
145170

146171
GUILayout.FlexibleSpace();
147172

@@ -150,69 +175,31 @@ private void DrawExistingBlocks()
150175

151176
if (GUILayout.Button("X", GUILayout.Width(20)))
152177
{
153-
if (EditorUtility.DisplayDialog("Delete Block", $"Are you sure you want to delete '{block.ID}'?", "Yes", "No"))
178+
if (EditorUtility.DisplayDialog("Delete Block", $"Are you sure you want to delete '{block.ID}'?",
179+
"Yes", "No"))
154180
{
155181
string path = AssetDatabase.GetAssetPath(block);
156182
_blockLibrary.AllBlocks.Remove(block);
157-
AssetDatabase.DeleteAsset(path);
158183
EditorUtility.SetDirty(_blockLibrary);
184+
AssetDatabase.DeleteAsset(path);
159185
AssetDatabase.SaveAssets();
160186
AssetDatabase.Refresh();
161187
GUIUtility.ExitGUI();
162188
}
163189
}
164190

165-
EditorGUILayout.EndHorizontal();
166-
}
167-
}
168-
169-
private void SortBlocks()
170-
{
171-
_blockLibrary.AllBlocks.Sort((a, b) =>
172-
{
173-
switch (_sortMode)
174-
{
175-
case SortMode.ByID:
176-
return string.Compare(a.ID, b.ID, StringComparison.OrdinalIgnoreCase);
177-
case SortMode.ByIconName:
178-
var aSprite = a.Icon != null ? a.Icon.name : string.Empty;
179-
var bSprite = b.Icon != null ? b.Icon.name : string.Empty;
180-
return string.Compare(aSprite, bSprite, StringComparison.OrdinalIgnoreCase);
181-
case SortMode.ByPrefabName:
182-
var aPrefab = a.Prefab != null ? a.Prefab.name : string.Empty;
183-
var bPrefab = b.Prefab != null ? b.Prefab.name : string.Empty;
184-
return string.Compare(aPrefab, bPrefab, StringComparison.OrdinalIgnoreCase);
185-
default:
186-
return 0;
187-
}
188-
});
189-
}
190-
191-
private void DrawCreateBlockSection()
192-
{
193-
GUILayout.Label("Create New Block", EditorStyles.boldLabel);
194-
195-
_newBlockId = EditorGUILayout.TextField("ID", _newBlockId);
196-
_newBlockSprite = (Sprite)EditorGUILayout.ObjectField("Sprite", _newBlockSprite, typeof(Sprite), false);
197-
_newBlockPrefab = (GameObject)EditorGUILayout.ObjectField("Prefab", _newBlockPrefab, typeof(GameObject), false);
198-
199-
GUI.enabled = !string.IsNullOrEmpty(_newBlockId) && _newBlockSprite != null;
200-
if (GUILayout.Button("Create Block", GUILayout.Height(30)))
201-
{
202-
CreateNewBlock();
191+
GUILayout.EndHorizontal();
192+
SirenixEditorGUI.EndBox();
203193
}
204-
GUI.enabled = true;
205194
}
206195

196+
[BoxGroup("🧱 Create Block")]
197+
[GUIColor(0.2f, 0.8f, 0.2f)]
198+
[Button("🚀 Create New Block", ButtonSizes.Large)]
199+
[EnableIf("@!string.IsNullOrEmpty(_newBlockId) && _newBlockSprite != null")]
207200
private void CreateNewBlock()
208201
{
209-
if (_blockLibrary == null)
210-
{
211-
Debug.LogError("BlockLibrary not assigned or found.");
212-
return;
213-
}
214-
215-
string folderPath = "Assets/Resources/StaticData/BlocksData";
202+
var folderPath = "Assets/Resources/StaticData/BlocksData";
216203
if (!AssetDatabase.IsValidFolder(folderPath))
217204
AssetDatabase.CreateFolder("Assets/Resources/StaticData", "BlocksData");
218205

@@ -229,11 +216,26 @@ private void CreateNewBlock()
229216

230217
_blockLibrary.AllBlocks.Add(newBlock);
231218
EditorUtility.SetDirty(_blockLibrary);
219+
AssetDatabase.SaveAssets();
232220

233221
Debug.Log($"✅ Created new block: {_newBlockId}");
234222
_newBlockId = "";
235223
_newBlockSprite = null;
236224
_newBlockPrefab = null;
237225
}
226+
227+
private int SafeCompare(UnityEngine.Object a, UnityEngine.Object b)
228+
{
229+
try
230+
{
231+
string nameA = a != null ? a.name : string.Empty;
232+
string nameB = b != null ? b.name : string.Empty;
233+
return string.Compare(nameA, nameB, StringComparison.OrdinalIgnoreCase);
234+
}
235+
catch
236+
{
237+
return 0;
238+
}
239+
}
238240
}
239-
}
241+
}

Assets/Resources/StaticData/BlocksData/Amar_1.asset renamed to Assets/Resources/StaticData/BlocksData/Amur_1.asset

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ MonoBehaviour:
1010
m_Enabled: 1
1111
m_EditorHideFlags: 0
1212
m_Script: {fileID: 11500000, guid: 73698c54e77f2b34ea84f49756a68126, type: 3}
13-
m_Name: Amar_1
13+
m_Name: Amur_1
1414
m_EditorClassIdentifier:
15-
id: Amar_1
16-
icon: {fileID: 21300000, guid: 7717b28d4af90ce4e9eae2c8ae0876ce, type: 3}
15+
id: Amur_1
16+
icon: {fileID: 21300000, guid: 46ccb3ef822a43d429313a5a80c54504, type: 3}
1717
prefab: {fileID: 0}

Assets/Resources/StaticData/BlocksData/Amar_1.asset.meta renamed to Assets/Resources/StaticData/BlocksData/Amur_1.asset.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Resources/StaticData/BlocksData/BlockLibrary.asset

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ MonoBehaviour:
1313
m_Name: BlockLibrary
1414
m_EditorClassIdentifier:
1515
AllBlocks:
16-
- {fileID: 11400000, guid: 4e69c2dd531702e42a33d4a6c94c811a, type: 2}
1716
- {fileID: 11400000, guid: 96e05a53fcff82746af78cdfbda8503f, type: 2}
1817
- {fileID: 11400000, guid: fc5914abd9f97564983e7d01b39ed2fa, type: 2}
18+
- {fileID: 11400000, guid: 0e943a1debd390b4e8db09cf5ef9663f, type: 2}
19+
- {fileID: 11400000, guid: d60ba8fafcb78f8479dca900173055bc, type: 2}

0 commit comments

Comments
 (0)