Skip to content

Commit 8757a42

Browse files
committed
Add object up/down moving
1 parent 9a9794a commit 8757a42

File tree

5 files changed

+181
-63
lines changed

5 files changed

+181
-63
lines changed

Editor/DataVisualizer/DataVisualizer.cs

Lines changed: 124 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ internal DataVisualizerSettings Settings
166166
private string _lastSearchString;
167167

168168
private Button _addTypeButton;
169+
private Label _emptyObjectLabel;
169170
private Button _addTypesFromScriptFolderButton;
170171
private Button _addTypesFromDataFolderButton;
171172
private Button _createObjectButton;
@@ -3075,29 +3076,37 @@ private void HandleDeleteConfirmed()
30753076

30763077
int index = _selectedObjects.IndexOf(objectToDelete);
30773078
_selectedObjects.Remove(objectToDelete);
3079+
_selectedObjects.RemoveAll(obj => obj == null);
30783080
_objectVisualElementMap.Remove(objectToDelete, out VisualElement visualElement);
3081+
int targetIndex = _selectedObject == objectToDelete ? Mathf.Max(0, index - 1) : 0;
3082+
30793083
bool deleted = AssetDatabase.DeleteAsset(path);
30803084
if (deleted)
30813085
{
30823086
Debug.Log($"Asset '{path}' deleted successfully.");
30833087
AssetDatabase.Refresh();
3088+
VisualElement parent = visualElement?.parent;
30843089
visualElement?.RemoveFromHierarchy();
3085-
if (_selectedObject == objectToDelete)
3090+
if (parent != null)
30863091
{
3087-
int targetIndex = Mathf.Max(0, index - 1);
3088-
if (targetIndex < _selectedObjects.Count)
3089-
{
3090-
SelectObject(_selectedObjects[targetIndex]);
3091-
}
3092-
else if (0 < _selectedObjects.Count)
3093-
{
3094-
SelectObject(_selectedObjects[0]);
3095-
}
3096-
else
3092+
foreach (VisualElement child in parent.Children())
30973093
{
3098-
SelectObject(null);
3094+
NamespaceController.RecalibrateVisualElements(child, offset: 1);
30993095
}
31003096
}
3097+
if (targetIndex < _selectedObjects.Count)
3098+
{
3099+
SelectObject(_selectedObjects[targetIndex]);
3100+
}
3101+
else if (0 < _selectedObjects.Count)
3102+
{
3103+
SelectObject(_selectedObjects[0]);
3104+
}
3105+
else
3106+
{
3107+
_emptyObjectLabel.style.display = DisplayStyle.Flex;
3108+
SelectObject(null);
3109+
}
31013110
}
31023111
else
31033112
{
@@ -3927,8 +3936,7 @@ private VisualElement CreateObjectColumn()
39273936
_createObjectButton.AddToClassList("create-button");
39283937
_createObjectButton.AddToClassList("icon-button");
39293938
_createObjectButton.AddToClassList(StyleConstants.ClickableClass);
3930-
_createObjectButton.style.display =
3931-
_namespaceController.SelectedType != null ? DisplayStyle.Flex : DisplayStyle.None;
3939+
UpdateCreateObjectButtonStyle();
39323940
objectHeader.Add(_createObjectButton);
39333941
objectColumn.Add(objectHeader);
39343942
_objectScrollView = new ScrollView(ScrollViewMode.Vertical)
@@ -4112,6 +4120,7 @@ private void BuildNamespaceView()
41124120

41134121
internal void BuildObjectsView()
41144122
{
4123+
_selectedObjects.RemoveAll(obj => obj == null);
41154124
if (_objectListContainer == null)
41164125
{
41174126
return;
@@ -4122,53 +4131,109 @@ internal void BuildObjectsView()
41224131
_objectScrollView.scrollOffset = Vector2.zero;
41234132

41244133
Type selectedType = _namespaceController.SelectedType;
4134+
_emptyObjectLabel = new Label(
4135+
$"No objects of type '{selectedType?.Name}' found.\nUse the '+' button above to create one."
4136+
)
4137+
{
4138+
name = "empty-object-list-label",
4139+
};
4140+
_emptyObjectLabel.AddToClassList("empty-object-list-label");
4141+
_objectListContainer.Add(_emptyObjectLabel);
41254142
if (selectedType != null && _selectedObjects.Count == 0)
41264143
{
4127-
Label emptyLabel = new(
4128-
$"No objects of type '{selectedType.Name}' found.\nUse the '+' button above to create one."
4129-
)
4130-
{
4131-
name = "empty-object-list-label",
4132-
};
4133-
emptyLabel.AddToClassList("empty-object-list-label");
4134-
_objectListContainer.Add(emptyLabel);
4144+
_emptyObjectLabel.style.display = DisplayStyle.Flex;
4145+
}
4146+
else
4147+
{
4148+
_emptyObjectLabel.style.display = DisplayStyle.None;
41354149
}
41364150

4137-
foreach (ScriptableObject dataObject in _selectedObjects)
4151+
for (int i = 0; i < _selectedObjects.Count; i++)
41384152
{
4153+
ScriptableObject dataObject = _selectedObjects[i];
41394154
if (dataObject == null)
41404155
{
41414156
continue;
41424157
}
41434158

4144-
ScriptableObject localDataObject = dataObject;
4159+
string dataObjectName;
4160+
if (dataObject is IDisplayable displayable)
4161+
{
4162+
dataObjectName = displayable.Title;
4163+
}
4164+
else
4165+
{
4166+
dataObjectName = dataObject.name;
4167+
}
41454168

41464169
VisualElement objectItemRow = new()
41474170
{
4148-
name = $"object-item-row-{localDataObject.GetInstanceID()}",
4171+
name = $"object-item-row-{dataObject.GetInstanceID()}",
41494172
};
41504173
objectItemRow.AddToClassList(ObjectItemClass);
41514174
objectItemRow.AddToClassList(StyleConstants.ClickableClass);
41524175
objectItemRow.style.flexDirection = FlexDirection.Row;
41534176
objectItemRow.style.alignItems = Align.Center;
4154-
objectItemRow.userData = localDataObject;
4177+
objectItemRow.userData = dataObject;
41554178
objectItemRow.RegisterCallback<PointerDownEvent>(OnObjectPointerDown);
41564179

4157-
VisualElement contentArea = new() { name = "content" };
4158-
contentArea.AddToClassList(ObjectItemContentClass);
4159-
contentArea.AddToClassList(StyleConstants.ClickableClass);
4160-
objectItemRow.Add(contentArea);
4180+
Button goUpButton = new(() =>
4181+
{
4182+
_objectListContainer.Remove(objectItemRow);
4183+
_objectListContainer.Insert(1, objectItemRow);
4184+
foreach (VisualElement child in _objectListContainer.Children())
4185+
{
4186+
NamespaceController.RecalibrateVisualElements(child, offset: 1);
4187+
}
4188+
})
4189+
{
4190+
name = "go-up-button",
4191+
text = "↑",
4192+
tooltip = $"Move {dataObjectName} to top",
4193+
};
4194+
if (_selectedObjects.Count == 1 || i == 0)
4195+
{
4196+
goUpButton.AddToClassList("go-button-disabled");
4197+
}
4198+
else
4199+
{
4200+
goUpButton.AddToClassList(StyleConstants.ActionButtonClass);
4201+
goUpButton.AddToClassList("go-button");
4202+
}
41614203

4162-
string dataObjectName;
4163-
if (localDataObject is IDisplayable displayable)
4204+
objectItemRow.Add(goUpButton);
4205+
4206+
Button goDownButton = new(() =>
41644207
{
4165-
dataObjectName = displayable.Title;
4208+
_objectListContainer.Remove(objectItemRow);
4209+
_objectListContainer.Insert(_objectListContainer.childCount, objectItemRow);
4210+
foreach (VisualElement child in _objectListContainer.Children())
4211+
{
4212+
NamespaceController.RecalibrateVisualElements(child, offset: 1);
4213+
}
4214+
})
4215+
{
4216+
name = "go-down-button",
4217+
text = "↓",
4218+
tooltip = $"Move {dataObjectName} to bottom",
4219+
};
4220+
if (_selectedObjects.Count == 1 || i == _selectedObjects.Count - 1)
4221+
{
4222+
goDownButton.AddToClassList("go-button-disabled");
41664223
}
41674224
else
41684225
{
4169-
dataObjectName = localDataObject.name;
4226+
goDownButton.AddToClassList(StyleConstants.ActionButtonClass);
4227+
goDownButton.AddToClassList("go-button");
41704228
}
41714229

4230+
objectItemRow.Add(goDownButton);
4231+
4232+
VisualElement contentArea = new() { name = "content" };
4233+
contentArea.AddToClassList(ObjectItemContentClass);
4234+
contentArea.AddToClassList(StyleConstants.ClickableClass);
4235+
objectItemRow.Add(contentArea);
4236+
41724237
Label titleLabel = new(dataObjectName) { name = "object-item-label" };
41734238
titleLabel.AddToClassList("object-item__label");
41744239
titleLabel.AddToClassList(StyleConstants.ClickableClass);
@@ -4187,7 +4252,7 @@ internal void BuildObjectsView()
41874252
actionsArea.AddToClassList(ObjectItemActionsClass);
41884253
objectItemRow.Add(actionsArea);
41894254

4190-
Button cloneButton = new(() => CloneObject(localDataObject))
4255+
Button cloneButton = new(() => CloneObject(dataObject))
41914256
{
41924257
text = "++",
41934258
tooltip = "Clone Object",
@@ -4197,7 +4262,7 @@ internal void BuildObjectsView()
41974262
actionsArea.Add(cloneButton);
41984263

41994264
Button renameButton = null;
4200-
renameButton = new Button(() => OpenRenamePopover(renameButton, localDataObject))
4265+
renameButton = new Button(() => OpenRenamePopover(renameButton, dataObject))
42014266
{
42024267
text = "@",
42034268
tooltip = "Rename Object",
@@ -4206,15 +4271,14 @@ internal void BuildObjectsView()
42064271
renameButton.AddToClassList("rename-button");
42074272
actionsArea.Add(renameButton);
42084273

4209-
Button moveButton = null;
4210-
moveButton = new Button(() =>
4274+
Button moveButton = new(() =>
42114275
{
4212-
if (localDataObject == null)
4276+
if (dataObject == null)
42134277
{
42144278
return;
42154279
}
42164280

4217-
string assetPath = AssetDatabase.GetAssetPath(localDataObject);
4281+
string assetPath = AssetDatabase.GetAssetPath(dataObject);
42184282
string startDirectory = Path.GetDirectoryName(assetPath) ?? string.Empty;
42194283
string selectedAbsolutePath = EditorUtility.OpenFolderPanel(
42204284
title: "Select New Location (Must be inside Assets)",
@@ -4267,7 +4331,7 @@ internal void BuildObjectsView()
42674331
relativePath = relativePath.Replace("//", "/");
42684332
}
42694333

4270-
string targetPath = $"{relativePath}/{localDataObject.name}.asset";
4334+
string targetPath = $"{relativePath}/{dataObject.name}.asset";
42714335
if (string.Equals(assetPath, targetPath, StringComparison.OrdinalIgnoreCase))
42724336
{
42734337
// Ignore same path operation
@@ -4278,7 +4342,7 @@ internal void BuildObjectsView()
42784342
if (!string.IsNullOrWhiteSpace(errorMessage))
42794343
{
42804344
Debug.LogError(
4281-
$"Error moving asset {localDataObject.name} from '{assetPath}' to '{targetPath}': {errorMessage}"
4345+
$"Error moving asset {dataObject.name} from '{assetPath}' to '{targetPath}': {errorMessage}"
42824346
);
42834347
EditorUtility.DisplayDialog("Invalid Move Operation", errorMessage, "OK");
42844348
}
@@ -4292,9 +4356,7 @@ internal void BuildObjectsView()
42924356
actionsArea.Add(moveButton);
42934357

42944358
Button deleteButton = null;
4295-
deleteButton = new Button(
4296-
() => OpenConfirmDeletePopover(deleteButton, localDataObject)
4297-
)
4359+
deleteButton = new Button(() => OpenConfirmDeletePopover(deleteButton, dataObject))
42984360
{
42994361
text = "X",
43004362
tooltip = "Delete Object",
@@ -4303,10 +4365,10 @@ internal void BuildObjectsView()
43034365
deleteButton.AddToClassList("delete-button");
43044366
actionsArea.Add(deleteButton);
43054367

4306-
_objectVisualElementMap[localDataObject] = objectItemRow;
4368+
_objectVisualElementMap[dataObject] = objectItemRow;
43074369
_objectListContainer.Add(objectItemRow);
43084370

4309-
if (_selectedObject == localDataObject)
4371+
if (_selectedObject == dataObject)
43104372
{
43114373
objectItemRow.AddToClassList(StyleConstants.SelectedClass);
43124374
_selectedElement = objectItemRow;
@@ -5031,14 +5093,6 @@ out VisualElement newSelectedElement
50315093
Debug.LogError($"Error saving selection state. {e}");
50325094
}
50335095

5034-
if (_createObjectButton != null)
5035-
{
5036-
_createObjectButton.style.display =
5037-
_namespaceController.SelectedType != null
5038-
? DisplayStyle.Flex
5039-
: DisplayStyle.None;
5040-
}
5041-
50425096
_currentInspectorScriptableObject?.Dispose();
50435097
_currentInspectorScriptableObject =
50445098
dataObject != null ? new SerializedObject(dataObject) : null;
@@ -5060,6 +5114,17 @@ out VisualElement newSelectedElement
50605114
BuildInspectorView();
50615115
}
50625116

5117+
internal void UpdateCreateObjectButtonStyle()
5118+
{
5119+
if (_createObjectButton != null)
5120+
{
5121+
_createObjectButton.style.display =
5122+
_namespaceController.SelectedType != null
5123+
? DisplayStyle.Flex
5124+
: DisplayStyle.None;
5125+
}
5126+
}
5127+
50635128
private void OnObjectPointerDown(PointerDownEvent evt)
50645129
{
50655130
VisualElement targetElement = evt.currentTarget as VisualElement;
@@ -5423,6 +5488,10 @@ private void PerformObjectDrop()
54235488
_draggedElement.style.display = DisplayStyle.Flex;
54245489
_draggedElement.style.opacity = 1.0f;
54255490
_objectListContainer.Insert(targetIndex, _draggedElement);
5491+
foreach (VisualElement child in _objectListContainer.Children())
5492+
{
5493+
NamespaceController.RecalibrateVisualElements(child, offset: 1);
5494+
}
54265495

54275496
int oldDataIndex = _selectedObjects.IndexOf(draggedObject);
54285497
if (0 > oldDataIndex)

Editor/DataVisualizer/NamespaceController.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,10 @@ public void SelectType(DataVisualizer dataVisualizer, Type type)
147147
ScriptableObject objectToSelect = dataVisualizer.DetermineObjectToAutoSelect();
148148
dataVisualizer.BuildObjectsView();
149149
dataVisualizer.SelectObject(objectToSelect);
150+
dataVisualizer.UpdateCreateObjectButtonStyle();
150151
}
151152

152-
public static void RecalibrateVisualElements(VisualElement item)
153+
public static void RecalibrateVisualElements(VisualElement item, int offset = 0)
153154
{
154155
VisualElement parent = item?.parent;
155156
if (parent == null)
@@ -166,9 +167,13 @@ public static void RecalibrateVisualElements(VisualElement item)
166167
Button goUpButton = item.Q<Button>("go-up-button");
167168
if (goUpButton != null)
168169
{
169-
goUpButton.EnableInClassList("go-button-disabled", index == 0);
170-
goUpButton.EnableInClassList(StyleConstants.ActionButtonClass, index != 0);
171-
goUpButton.EnableInClassList("go-button", index != 0);
170+
int compensatedIndex = Mathf.Max(0, index - offset);
171+
goUpButton.EnableInClassList("go-button-disabled", compensatedIndex == 0);
172+
goUpButton.EnableInClassList(
173+
StyleConstants.ActionButtonClass,
174+
compensatedIndex != 0
175+
);
176+
goUpButton.EnableInClassList("go-button", compensatedIndex != 0);
172177
}
173178
Button goDownButton = item.Q<Button>("go-down-button");
174179
if (goDownButton != null)

Editor/DataVisualizer/Styles/DataVisualizerStyles.uss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
overflow: hidden;
3333
text-overflow: ellipsis;
3434
margin-right: 5px;
35+
margin-left: 5px;
3536
height: 20px;
3637
padding-top: 2px;
3738
}
@@ -604,8 +605,7 @@
604605
.empty-object-list-label {
605606
color: grey;
606607
white-space: normal;
607-
margin-top: 20px;
608-
padding: 5px;
608+
margin: 10px;
609609
}
610610

611611
.type-selection-list-item {

0 commit comments

Comments
 (0)