Skip to content

Commit 4277ce1

Browse files
committed
Add pagination
1 parent d7f2883 commit 4277ce1

7 files changed

Lines changed: 241 additions & 29 deletions

File tree

Editor/DataVisualizer/Data/LastObjectSelectionEntry.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public LastObjectSelectionEntry Clone()
1212
{
1313
return new LastObjectSelectionEntry
1414
{
15-
typeFullName = typeFullName,
16-
objectGuid = objectGuid,
15+
typeFullName = typeFullName ?? string.Empty,
16+
objectGuid = objectGuid ?? string.Empty,
1717
};
1818
}
1919
}

Editor/DataVisualizer/Data/NamespaceCollapseState.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public NamespaceCollapseState Clone()
1212
{
1313
return new NamespaceCollapseState
1414
{
15-
namespaceKey = namespaceKey,
15+
namespaceKey = namespaceKey ?? string.Empty,
1616
isCollapsed = isCollapsed,
1717
};
1818
}

Editor/DataVisualizer/Data/NamespaceTypeOrder.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.Linq;
56

67
[Serializable]
78
public sealed class NamespaceTypeOrder
@@ -13,8 +14,8 @@ public NamespaceTypeOrder Clone()
1314
{
1415
return new NamespaceTypeOrder
1516
{
16-
namespaceKey = namespaceKey,
17-
typeNames = new List<string>(typeNames),
17+
namespaceKey = namespaceKey ?? string.Empty,
18+
typeNames = typeNames?.ToList() ?? new List<string>(),
1819
};
1920
}
2021
}

Editor/DataVisualizer/Data/TypeObjectOrder.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.Linq;
56

67
[Serializable]
78
public sealed class TypeObjectOrder
89
{
10+
public int page;
911
public string TypeFullName = string.Empty;
1012
public List<string> ObjectGuids = new();
1113

1214
public TypeObjectOrder Clone()
1315
{
1416
return new TypeObjectOrder
1517
{
16-
TypeFullName = TypeFullName,
17-
ObjectGuids = new List<string>(ObjectGuids),
18+
page = page,
19+
TypeFullName = TypeFullName ?? string.Empty,
20+
ObjectGuids = ObjectGuids?.ToList() ?? new List<string>(),
1821
};
1922
}
2023
}

Editor/DataVisualizer/DataVisualizer.cs

Lines changed: 188 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace WallstopStudios.DataVisualizer.Editor
2727
using UnityEngine.UIElements;
2828
using Utilities;
2929
using Helper;
30+
using NUnit.Framework;
3031
using Debug = UnityEngine.Debug;
3132
using Object = UnityEngine.Object;
3233

@@ -66,6 +67,7 @@ public sealed class DataVisualizer : EditorWindow
6667
private const int MaxSearchResults = 25;
6768
private const float DefaultOuterSplitWidth = 200f;
6869
private const float DefaultInnerSplitWidth = 250f;
70+
private const int MaxObjectsPerPage = 100;
6971

7072
private enum DragType
7173
{
@@ -186,6 +188,11 @@ private int HiddenNamespaces
186188
private VisualElement _selectedNamespaceElement;
187189

188190
private VisualElement _namespaceListContainer;
191+
private VisualElement _objectPageController;
192+
private Button _previousPageButton;
193+
private Button _nextPageButton;
194+
private IntegerField _currentPageField;
195+
private IntegerField _maxPageField;
189196
private VisualElement _objectListContainer;
190197
private VisualElement _inspectorContainer;
191198
private ScrollView _objectScrollView;
@@ -4610,6 +4617,60 @@ private VisualElement CreateObjectColumn()
46104617
SetupDropTarget(_andLabelsContainer, LabelFilterSection.AND);
46114618
SetupDropTarget(_orLabelsContainer, LabelFilterSection.OR);
46124619

4620+
_objectPageController = new VisualElement
4621+
{
4622+
name = "object-page-controller",
4623+
style = { display = DisplayStyle.None },
4624+
};
4625+
_objectPageController.AddToClassList("object-page-controller");
4626+
_previousPageButton = new Button(() =>
4627+
{
4628+
int currentPage = GetCurrentPage(_namespaceController.SelectedType);
4629+
if (currentPage <= 0)
4630+
{
4631+
return;
4632+
}
4633+
4634+
SetCurrentPage(_namespaceController.SelectedType, currentPage - 1);
4635+
BuildObjectsView();
4636+
}) { text = "←" };
4637+
_previousPageButton.AddToClassList("go-button-disabled");
4638+
4639+
_currentPageField = new IntegerField();
4640+
_currentPageField.AddToClassList("current-page-field");
4641+
_currentPageField.RegisterValueChangedCallback(evt =>
4642+
{
4643+
int newValue = evt.newValue;
4644+
newValue = Mathf.Clamp(newValue, 0, _filteredObjects.Count / MaxObjectsPerPage);
4645+
if (newValue != evt.newValue)
4646+
{
4647+
_currentPageField.SetValueWithoutNotify(newValue);
4648+
}
4649+
4650+
SetCurrentPage(_namespaceController.SelectedType, newValue);
4651+
BuildObjectsView();
4652+
});
4653+
_maxPageField = new IntegerField() { isReadOnly = true };
4654+
_maxPageField.AddToClassList("max-page-field");
4655+
_nextPageButton = new Button(() =>
4656+
{
4657+
int currentPage = GetCurrentPage(_namespaceController.SelectedType);
4658+
if (_filteredObjects.Count /MaxObjectsPerPage <= currentPage)
4659+
{
4660+
return;
4661+
}
4662+
4663+
SetCurrentPage(_namespaceController.SelectedType, currentPage + 1);
4664+
BuildObjectsView();
4665+
}) { text = "→" };
4666+
_nextPageButton.AddToClassList("go-button-disabled");
4667+
_objectPageController.Add(_previousPageButton);
4668+
_objectPageController.Add(_currentPageField);
4669+
_objectPageController.Add(_maxPageField);
4670+
_objectPageController.Add(_nextPageButton);
4671+
4672+
objectColumn.Add(_objectPageController);
4673+
46134674
_objectScrollView = new ScrollView(ScrollViewMode.Vertical)
46144675
{
46154676
name = "object-scrollview",
@@ -5743,9 +5804,42 @@ internal void BuildObjectsView()
57435804
return;
57445805
}
57455806

5746-
for (int i = 0; i < _filteredObjects.Count; i++)
5807+
if (_filteredObjects.Count <= MaxObjectsPerPage)
5808+
{
5809+
if (_objectPageController != null)
5810+
{
5811+
_objectPageController.style.display = DisplayStyle.None;
5812+
}
5813+
for (int i = 0; i < _filteredObjects.Count; i++)
5814+
{
5815+
BuildObjectRow(_filteredObjects[i], i);
5816+
}
5817+
}
5818+
else
57475819
{
5748-
BuildObjectRow(_filteredObjects[i], i);
5820+
if (_objectPageController != null)
5821+
{
5822+
_objectPageController.style.display = DisplayStyle.Flex;
5823+
}
5824+
5825+
_maxPageField.value = _filteredObjects.Count / MaxObjectsPerPage;
5826+
int currentPage = GetCurrentPage(_namespaceController.SelectedType);
5827+
currentPage = Mathf.Clamp(currentPage, 0, _filteredObjects.Count / MaxObjectsPerPage);
5828+
_currentPageField.SetValueWithoutNotify(currentPage);
5829+
5830+
_previousPageButton.EnableInClassList("go-button-disabled", currentPage <= 0);
5831+
_previousPageButton.EnableInClassList(StyleConstants.ActionButtonClass, 0 < currentPage);
5832+
_previousPageButton.EnableInClassList("go-button", 0 < currentPage);
5833+
5834+
_nextPageButton.EnableInClassList("go-button-disabled", _maxPageField.value <= currentPage);
5835+
_nextPageButton.EnableInClassList(StyleConstants.ActionButtonClass, currentPage < _maxPageField.value);
5836+
_nextPageButton.EnableInClassList("go-button", currentPage < _maxPageField.value);
5837+
5838+
int max = Mathf.Min((currentPage + 1) * MaxObjectsPerPage, _filteredObjects.Count);
5839+
for (int i = currentPage * MaxObjectsPerPage; i < max; i++)
5840+
{
5841+
BuildObjectRow(_filteredObjects[i], i);
5842+
}
57495843
}
57505844
}
57515845

@@ -5779,12 +5873,12 @@ private void BuildObjectRow(ScriptableObject dataObject, int index)
57795873

57805874
Button goUpButton = new(() =>
57815875
{
5782-
_objectListContainer.Remove(objectItemRow);
5783-
_objectListContainer.Insert(1, objectItemRow);
5784-
foreach (VisualElement child in _objectListContainer.Children())
5785-
{
5786-
NamespaceController.RecalibrateVisualElements(child, offset: 1);
5787-
}
5876+
_filteredObjects.Remove(dataObject);
5877+
_filteredObjects.Insert(0, dataObject);
5878+
_filteredObjects.Remove(dataObject);
5879+
_filteredObjects.Insert(0, dataObject);
5880+
UpdateAndSaveObjectOrderList(dataObject.GetType(), _selectedObjects);
5881+
BuildObjectsView();
57885882
})
57895883
{
57905884
name = "go-up-button",
@@ -5805,12 +5899,12 @@ private void BuildObjectRow(ScriptableObject dataObject, int index)
58055899

58065900
Button goDownButton = new(() =>
58075901
{
5808-
_objectListContainer.Remove(objectItemRow);
5809-
_objectListContainer.Insert(_objectListContainer.childCount, objectItemRow);
5810-
foreach (VisualElement child in _objectListContainer.Children())
5811-
{
5812-
NamespaceController.RecalibrateVisualElements(child, offset: 1);
5813-
}
5902+
_selectedObjects.Remove(dataObject);
5903+
_selectedObjects.Add(dataObject);
5904+
_filteredObjects.Remove(dataObject);
5905+
_filteredObjects.Add(dataObject);
5906+
UpdateAndSaveObjectOrderList(dataObject.GetType(), _selectedObjects);
5907+
BuildObjectsView();
58145908
})
58155909
{
58165910
name = "go-down-button",
@@ -6910,7 +7004,7 @@ internal void LoadObjectTypes(Type type)
69107004
_selectedObjects.Clear();
69117005
_objectVisualElementMap.Clear();
69127006

6913-
List<string> customGuidOrder = GetObjectOrderForType(type.FullName);
7007+
List<string> customGuidOrder = GetObjectOrderForType(type);
69147008
Dictionary<string, ScriptableObject> objectsByGuid = new();
69157009
string[] assetGuids = AssetDatabase.FindAssets($"t:{type.Name}");
69167010
foreach (string assetGuid in assetGuids)
@@ -6956,8 +7050,15 @@ internal void LoadObjectTypes(Type type)
69567050

69577051
List<ScriptableObject> remainingObjects = objectsByGuid.Values.ToList();
69587052
remainingObjects.Sort(
6959-
(a, b) => string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase)
6960-
);
7053+
(a, b) =>
7054+
{
7055+
int comparison = string.Compare(a.name, b.name, StringComparison.OrdinalIgnoreCase);
7056+
if (comparison != 0)
7057+
{
7058+
return comparison;
7059+
}
7060+
return string.Compare(AssetDatabase.GetAssetPath(a), AssetDatabase.GetAssetPath(b), StringComparison.OrdinalIgnoreCase);
7061+
});
69617062
sortedObjects.AddRange(remainingObjects);
69627063

69637064
_selectedObjects.Clear();
@@ -8011,9 +8112,9 @@ private string GetLastSelectedNamespaceKey()
80118112
: UserState.lastSelectedNamespaceKey;
80128113
}
80138114

8014-
private List<string> GetObjectOrderForType(string typeFullName)
8115+
private List<string> GetObjectOrderForType(Type type)
80158116
{
8016-
if (string.IsNullOrWhiteSpace(typeFullName))
8117+
if (type == null)
80178118
{
80188119
return new List<string>();
80198120
}
@@ -8023,19 +8124,85 @@ private List<string> GetObjectOrderForType(string typeFullName)
80238124
if (settings.persistStateInSettingsAsset)
80248125
{
80258126
TypeObjectOrder entry = settings.objectOrders?.Find(o =>
8026-
string.Equals(o.TypeFullName, typeFullName, StringComparison.Ordinal)
8127+
string.Equals(o.TypeFullName, type.FullName, StringComparison.Ordinal)
80278128
);
80288129
return entry?.ObjectGuids?.ToList() ?? new List<string>();
80298130
}
80308131
else
80318132
{
80328133
TypeObjectOrder entry = UserState.objectOrders?.Find(o =>
8033-
string.Equals(o.TypeFullName, typeFullName, StringComparison.Ordinal)
8134+
string.Equals(o.TypeFullName, type.FullName, StringComparison.Ordinal)
80348135
);
80358136
return entry?.ObjectGuids?.ToList() ?? new List<string>();
80368137
}
80378138
}
80388139

8140+
private int GetCurrentPage(Type type)
8141+
{
8142+
DataVisualizerSettings settings = Settings;
8143+
if (settings.persistStateInSettingsAsset)
8144+
{
8145+
TypeObjectOrder entry = settings.objectOrders?.Find(o =>
8146+
string.Equals(o.TypeFullName, type.FullName, StringComparison.Ordinal)
8147+
);
8148+
return entry?.page ?? 0;
8149+
}
8150+
else
8151+
{
8152+
TypeObjectOrder entry = UserState.objectOrders?.Find(o =>
8153+
string.Equals(o.TypeFullName, type.FullName, StringComparison.Ordinal)
8154+
);
8155+
return entry?.page ?? 0;
8156+
}
8157+
}
8158+
8159+
private void SetCurrentPage(Type type, int page)
8160+
{
8161+
PersistSettings(settings =>
8162+
{
8163+
bool dirty = false;
8164+
TypeObjectOrder entry = settings.objectOrders?.Find(o =>
8165+
string.Equals(o.TypeFullName, type.FullName, StringComparison.Ordinal)
8166+
);
8167+
if (entry == null)
8168+
{
8169+
entry = new TypeObjectOrder();
8170+
settings.objectOrders ??= new List<TypeObjectOrder>();
8171+
settings.objectOrders.Add(entry);
8172+
dirty = true;
8173+
}
8174+
8175+
if (page != entry.page)
8176+
{
8177+
dirty = true;
8178+
entry.page = page;
8179+
}
8180+
8181+
return dirty;
8182+
}, userState =>
8183+
{
8184+
bool dirty = false;
8185+
TypeObjectOrder entry = userState.objectOrders?.Find(o =>
8186+
string.Equals(o.TypeFullName, type.FullName, StringComparison.Ordinal)
8187+
);
8188+
if (entry == null)
8189+
{
8190+
entry = new TypeObjectOrder();
8191+
userState.objectOrders ??= new List<TypeObjectOrder>();
8192+
userState.objectOrders.Add(entry);
8193+
dirty = true;
8194+
}
8195+
8196+
if (page != entry.page)
8197+
{
8198+
dirty = true;
8199+
entry.page = page;
8200+
}
8201+
8202+
return dirty;
8203+
});
8204+
}
8205+
80398206
private void SetObjectOrderForType(string typeFullName, List<string> objectGuids)
80408207
{
80418208
if (string.IsNullOrWhiteSpace(typeFullName) || objectGuids == null)

0 commit comments

Comments
 (0)