This commit is contained in:
陈思海 2026-03-19 16:11:04 +08:00
parent 86a110aacc
commit 0a3fd47070
4 changed files with 372 additions and 120 deletions

View File

@ -0,0 +1,16 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 53ed017cef844d11842ba16553c6391d, type: 3}
m_Name: InputGlyphDatabase
m_EditorClassIdentifier:
tables: []
placeholderSprite: {fileID: 0}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e43c1733d8e85a5419c0754bbd597e3b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.InputSystem;
@ -19,15 +18,22 @@ public sealed class InputGlyphDatabaseEditor : Editor
private const float PreviewSize = 52f;
private const float ListPreviewSize = 56f;
private const int MaxValidationIssuesToShow = 10;
private const int DefaultEntriesPerPage = 50;
private static readonly string[] DefaultTableNames = { "Keyboard", "Xbox", "PlayStation", "Other" };
private static readonly int[] EntriesPerPageOptions = { 25, 50, 100, 200 };
private static readonly string[] EntriesPerPageLabels = { "25 / 页", "50 / 页", "100 / 页", "200 / 页" };
private sealed class TableEditorState
{
public Sprite PendingSprite;
public bool ShowValidation = true;
public ReorderableList EntriesList;
public string EntriesPropertyPath;
public string EntrySearch = string.Empty;
public int CurrentPage;
public int EntriesPerPage = DefaultEntriesPerPage;
public readonly List<int> FilteredEntryIndices = new();
public string CachedSearch = string.Empty;
public int CachedEntryCount = -1;
}
private readonly List<TableEditorState> _tableStates = new();
@ -92,6 +98,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
if (serializedObject.ApplyModifiedProperties())
{
InvalidateAllEntryViews();
NotifyDatabaseChanged();
}
}
@ -103,6 +110,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
if (GUILayout.Button("Save Asset", EditorStyles.toolbarButton, GUILayout.Width(90f)))
{
serializedObject.ApplyModifiedProperties();
InvalidateAllEntryViews();
NotifyDatabaseChanged(true);
}
@ -217,13 +225,13 @@ public sealed class InputGlyphDatabaseEditor : Editor
private void DrawDatabaseValidationPanel()
{
List<string> issues = CollectDatabaseValidationIssues();
string title = issues.Count == 0 ? "Database Validation" : $"Database Validation ({issues.Count})";
string title = issues.Count == 0 ? "数据库校验" : $"数据库校验 ({issues.Count})";
_showDatabaseValidation = EditorGUILayout.BeginFoldoutHeaderGroup(_showDatabaseValidation, title);
if (_showDatabaseValidation)
{
if (issues.Count == 0)
{
EditorGUILayout.HelpBox("No database-level issues found.", MessageType.Info);
EditorGUILayout.HelpBox("未发现数据库级别的问题。", MessageType.Info);
}
else
{
@ -314,13 +322,13 @@ public sealed class InputGlyphDatabaseEditor : Editor
private void DrawTableValidationPanel(int tableIndex, TableEditorState state)
{
List<string> issues = CollectTableValidationIssues(tableIndex);
string title = issues.Count == 0 ? "Validation" : $"Validation ({issues.Count})";
string title = issues.Count == 0 ? "校验结果" : $"校验结果 ({issues.Count})";
state.ShowValidation = EditorGUILayout.BeginFoldoutHeaderGroup(state.ShowValidation, title);
if (state.ShowValidation)
{
if (issues.Count == 0)
{
EditorGUILayout.HelpBox("No table-level issues found.", MessageType.Info);
EditorGUILayout.HelpBox("未发现当前表的问题。", MessageType.Info);
}
else
{
@ -341,120 +349,198 @@ public sealed class InputGlyphDatabaseEditor : Editor
if (issues.Count > visibleCount)
{
EditorGUILayout.HelpBox($"{issues.Count - visibleCount} more issues are hidden to keep the inspector readable.", MessageType.None);
EditorGUILayout.HelpBox($"还有 {issues.Count - visibleCount} 条问题未展开显示,以保持检视面板可读。", MessageType.None);
}
}
private void DrawEntriesList(int tableIndex, SerializedProperty entriesProperty)
{
EditorGUILayout.LabelField("Entries", EditorStyles.boldLabel);
ReorderableList list = GetEntriesList(tableIndex, entriesProperty);
list.DoLayoutList();
}
private ReorderableList GetEntriesList(int tableIndex, SerializedProperty entriesProperty)
{
TableEditorState state = _tableStates[tableIndex];
if (state.EntriesList != null && state.EntriesPropertyPath == entriesProperty.propertyPath)
EditorGUILayout.LabelField("Entries", EditorStyles.boldLabel);
DrawEntriesControls(state, entriesProperty.arraySize);
if (entriesProperty.arraySize == 0)
{
return state.EntriesList;
EditorGUILayout.HelpBox("当前表里还没有任何条目。", MessageType.Info);
return;
}
ReorderableList list = new ReorderableList(serializedObject, entriesProperty, true, true, false, true);
state.EntriesList = list;
state.EntriesPropertyPath = entriesProperty.propertyPath;
list.drawHeaderCallback = rect =>
List<int> filteredIndices = GetFilteredEntryIndices(tableIndex, entriesProperty, state);
if (filteredIndices.Count == 0)
{
EditorGUI.LabelField(rect, $"Entries ({entriesProperty.arraySize}) - drag to reorder");
};
EditorGUILayout.HelpBox("没有匹配搜索条件的条目。", MessageType.Info);
return;
}
list.elementHeightCallback = index =>
int entriesPerPage = Mathf.Max(1, state.EntriesPerPage);
int totalPages = Mathf.Max(1, Mathf.CeilToInt(filteredIndices.Count / (float)entriesPerPage));
state.CurrentPage = Mathf.Clamp(state.CurrentPage, 0, totalPages - 1);
DrawEntriesPagination(state, filteredIndices.Count, entriesProperty.arraySize);
EditorGUILayout.Space(4f);
int startIndex = state.CurrentPage * entriesPerPage;
int endIndex = Mathf.Min(startIndex + entriesPerPage, filteredIndices.Count);
for (int i = startIndex; i < endIndex; i++)
{
if (index < 0 || index >= entriesProperty.arraySize)
{
return EditorGUIUtility.singleLineHeight + 8f;
}
int entryIndex = filteredIndices[i];
DrawEntryElement(tableIndex, entryIndex, entriesProperty.GetArrayElementAtIndex(entryIndex));
EditorGUILayout.Space(4f);
}
return GetEntryElementHeight(entriesProperty.GetArrayElementAtIndex(index));
};
list.drawElementCallback = (rect, index, active, focused) =>
if (totalPages > 1)
{
if (index < 0 || index >= entriesProperty.arraySize)
{
return;
}
DrawEntryElement(rect, entriesProperty.GetArrayElementAtIndex(index));
};
list.onReorderCallback = _ =>
{
ApplyPendingInspectorChanges();
};
list.onRemoveCallback = currentList =>
{
if (currentList.index < 0 || currentList.index >= entriesProperty.arraySize)
{
return;
}
if (!EditorUtility.DisplayDialog("Remove Entry", "Remove the selected entry from the table?", "Remove", "Cancel"))
{
return;
}
Undo.RecordObject(_database, "Remove glyph entry");
entriesProperty.DeleteArrayElementAtIndex(currentList.index);
serializedObject.ApplyModifiedProperties();
InvalidateEntriesList(tableIndex);
NotifyDatabaseChanged();
};
return list;
DrawEntriesPagination(state, filteredIndices.Count, entriesProperty.arraySize);
}
}
private float GetEntryElementHeight(SerializedProperty entryProperty)
private void DrawEntriesControls(TableEditorState state, int totalEntries)
{
SerializedProperty spriteProperty = entryProperty.FindPropertyRelative(EntrySpritePropertyName);
SerializedProperty actionProperty = entryProperty.FindPropertyRelative(EntryActionPropertyName);
float spriteHeight = EditorGUI.GetPropertyHeight(spriteProperty, true);
float actionHeight = EditorGUI.GetPropertyHeight(actionProperty, true);
float fieldHeight = spriteHeight + actionHeight + 10f;
return Mathf.Max(ListPreviewSize + 10f, fieldHeight + 8f);
string search = EditorGUILayout.TextField("Search", state.EntrySearch);
if (!string.Equals(search, state.EntrySearch, StringComparison.Ordinal))
{
state.EntrySearch = search;
state.CurrentPage = 0;
InvalidateEntryView(state);
}
using (new EditorGUILayout.HorizontalScope())
{
int entriesPerPage = EditorGUILayout.IntPopup("Page Size", state.EntriesPerPage, EntriesPerPageLabels, EntriesPerPageOptions);
if (entriesPerPage != state.EntriesPerPage)
{
state.EntriesPerPage = entriesPerPage;
state.CurrentPage = 0;
}
GUILayout.FlexibleSpace();
EditorGUILayout.LabelField($"总数: {totalEntries}", EditorStyles.miniLabel, GUILayout.Width(80f));
using (new EditorGUI.DisabledScope(string.IsNullOrEmpty(state.EntrySearch)))
{
if (GUILayout.Button("Clear Search", GUILayout.Width(100f)))
{
state.EntrySearch = string.Empty;
state.CurrentPage = 0;
InvalidateEntryView(state);
GUI.FocusControl(null);
}
}
}
}
private void DrawEntryElement(Rect rect, SerializedProperty entryProperty)
private void DrawEntriesPagination(TableEditorState state, int filteredCount, int totalEntries)
{
int entriesPerPage = Mathf.Max(1, state.EntriesPerPage);
int totalPages = Mathf.Max(1, Mathf.CeilToInt(filteredCount / (float)entriesPerPage));
int startEntry = filteredCount == 0 ? 0 : state.CurrentPage * entriesPerPage + 1;
int endEntry = Mathf.Min(filteredCount, (state.CurrentPage + 1) * entriesPerPage);
using (new EditorGUILayout.HorizontalScope(EditorStyles.helpBox))
{
EditorGUILayout.LabelField(
$"显示 {startEntry}-{endEntry} / {filteredCount} 条",
EditorStyles.miniLabel,
GUILayout.Width(140f));
if (filteredCount != totalEntries)
{
EditorGUILayout.LabelField($"(筛选自 {totalEntries} 条)", EditorStyles.miniLabel, GUILayout.Width(100f));
}
GUILayout.FlexibleSpace();
using (new EditorGUI.DisabledScope(state.CurrentPage <= 0))
{
if (GUILayout.Button("<<", GUILayout.Width(32f)))
{
state.CurrentPage = 0;
}
if (GUILayout.Button("<", GUILayout.Width(28f)))
{
state.CurrentPage--;
}
}
GUILayout.Label($"第 {state.CurrentPage + 1} / {totalPages} 页", EditorStyles.miniLabel, GUILayout.Width(72f));
using (new EditorGUI.DisabledScope(state.CurrentPage >= totalPages - 1))
{
if (GUILayout.Button(">", GUILayout.Width(28f)))
{
state.CurrentPage++;
}
if (GUILayout.Button(">>", GUILayout.Width(32f)))
{
state.CurrentPage = totalPages - 1;
}
}
}
}
private void DrawEntryElement(int tableIndex, int entryIndex, SerializedProperty entryProperty)
{
SerializedProperty spriteProperty = entryProperty.FindPropertyRelative(EntrySpritePropertyName);
SerializedProperty actionProperty = entryProperty.FindPropertyRelative(EntryActionPropertyName);
Sprite sprite = spriteProperty.objectReferenceValue as Sprite;
rect.y += 4f;
rect.height -= 8f;
Rect previewRect = new Rect(rect.x, rect.y, ListPreviewSize, ListPreviewSize);
Rect fieldsRect = new Rect(rect.x + ListPreviewSize + 8f, rect.y, rect.width - ListPreviewSize - 44f, rect.height);
Rect pingRect = new Rect(rect.xMax - 30f, rect.y, 30f, EditorGUIUtility.singleLineHeight);
DrawSpritePreview(previewRect, sprite);
float currentY = fieldsRect.y;
float spriteHeight = EditorGUI.GetPropertyHeight(spriteProperty, true);
Rect spriteRect = new Rect(fieldsRect.x, currentY, fieldsRect.width, spriteHeight);
EditorGUI.PropertyField(spriteRect, spriteProperty, new GUIContent("Sprite"), true);
currentY += spriteHeight + 4f;
float actionHeight = EditorGUI.GetPropertyHeight(actionProperty, true);
Rect actionRect = new Rect(fieldsRect.x, currentY, fieldsRect.width, actionHeight);
EditorGUI.PropertyField(actionRect, actionProperty, new GUIContent("Action"), true);
using (new EditorGUI.DisabledScope(sprite == null))
using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
{
if (GUI.Button(pingRect, "Ping"))
using (new EditorGUILayout.HorizontalScope())
{
EditorGUIUtility.PingObject(sprite);
GUILayout.Label(GetEntryTitle(tableIndex, entryIndex), EditorStyles.boldLabel);
GUILayout.FlexibleSpace();
using (new EditorGUI.DisabledScope(entryIndex <= 0))
{
if (GUILayout.Button("↑", GUILayout.Width(28f)))
{
ApplyPendingInspectorChanges();
MoveEntry(tableIndex, entryIndex, entryIndex - 1);
GUIUtility.ExitGUI();
}
}
using (new EditorGUI.DisabledScope(entryIndex >= _database.tables[tableIndex].entries.Count - 1))
{
if (GUILayout.Button("↓", GUILayout.Width(28f)))
{
ApplyPendingInspectorChanges();
MoveEntry(tableIndex, entryIndex, entryIndex + 1);
GUIUtility.ExitGUI();
}
}
using (new EditorGUI.DisabledScope(sprite == null))
{
if (GUILayout.Button("Ping", GUILayout.Width(48f)))
{
EditorGUIUtility.PingObject(sprite);
}
}
if (GUILayout.Button("Remove", GUILayout.Width(64f)))
{
if (EditorUtility.DisplayDialog("Remove Entry", "Remove the selected entry from the table?", "Remove", "Cancel"))
{
ApplyPendingInspectorChanges();
RemoveEntry(tableIndex, entryIndex);
GUIUtility.ExitGUI();
}
}
}
using (new EditorGUILayout.HorizontalScope())
{
Rect previewRect = GUILayoutUtility.GetRect(ListPreviewSize, ListPreviewSize, GUILayout.Width(ListPreviewSize), GUILayout.Height(ListPreviewSize));
DrawSpritePreview(previewRect, sprite);
using (new EditorGUILayout.VerticalScope())
{
EditorGUILayout.PropertyField(spriteProperty, new GUIContent("Sprite"), true);
EditorGUILayout.PropertyField(actionProperty, new GUIContent("Action"), true);
}
}
}
}
@ -509,14 +595,14 @@ public sealed class InputGlyphDatabaseEditor : Editor
List<string> issues = new();
if (_database.tables == null || _database.tables.Count == 0)
{
issues.Add("The database has no tables. Runtime glyph lookup will always fall back to the placeholder sprite.");
issues.Add("数据库中没有任何表,运行时查询将始终回退到占位图标。");
return issues;
}
List<string> missingTables = GetMissingDefaultTables();
if (missingTables.Count > 0)
{
issues.Add($"Recommended tables are missing: {string.Join(", ", missingTables)}.");
issues.Add($"缺少推荐表: {string.Join(", ", missingTables)}。");
}
HashSet<string> seenNames = new(StringComparer.OrdinalIgnoreCase);
@ -526,7 +612,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
string tableName = _database.tables[i] != null ? _database.tables[i].deviceName : string.Empty;
if (string.IsNullOrWhiteSpace(tableName))
{
issues.Add($"Table {i + 1} has an empty device name.");
issues.Add($"表 {i + 1} 的设备名称为空。");
continue;
}
@ -538,7 +624,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
foreach (string duplicateName in duplicateNames)
{
issues.Add($"Duplicate table name '{duplicateName}' detected.");
issues.Add($"检测到重复的表名 '{duplicateName}'。");
}
return issues;
@ -549,14 +635,14 @@ public sealed class InputGlyphDatabaseEditor : Editor
List<string> issues = new();
if (!IsValidTableIndex(tableIndex))
{
issues.Add("The selected table is invalid.");
issues.Add("当前选中的表无效。");
return issues;
}
DeviceGlyphTable table = _database.tables[tableIndex];
if (table.entries == null || table.entries.Count == 0)
{
issues.Add("This table has no entries.");
issues.Add("当前表没有任何条目。");
return issues;
}
@ -571,7 +657,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
GlyphEntry entry = table.entries[i];
if (entry == null)
{
issues.Add($"Entry {i + 1} is null.");
issues.Add($"条目 {i + 1} 为空。");
continue;
}
@ -601,16 +687,17 @@ public sealed class InputGlyphDatabaseEditor : Editor
if (missingSpriteCount > 0)
{
issues.Add($"{missingSpriteCount} entr{(missingSpriteCount == 1 ? "y has" : "ies have")} no sprite assigned.");
issues.Add($"{missingSpriteCount} 个条目未绑定 Sprite。");
}
if (missingActionCount > 0)
{
issues.Add($"{missingActionCount} entr{(missingActionCount == 1 ? "y has" : "ies have")} no action assigned. Those entries will not participate in runtime path lookup.");
issues.Add($"{missingActionCount} 个条目未绑定 Action这些条目不会参与运行时路径查找。");
}
foreach (string spriteName in duplicateSprites)
{
issues.Add($"Duplicate sprite name '{spriteName}' found in this table.");
issues.Add($"当前表中存在重复的 Sprite 名称 '{spriteName}'。");
}
foreach (KeyValuePair<string, List<string>> pair in bindingOwners)
@ -620,7 +707,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
continue;
}
issues.Add($"Binding '{pair.Key}' is mapped by multiple entries: {string.Join(", ", pair.Value)}. Runtime lookup keeps the first match.");
issues.Add($"绑定 '{pair.Key}' 被多个条目共用: {string.Join(", ", pair.Value)}。运行时只会保留第一个匹配项。");
}
return issues;
@ -658,7 +745,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
table.entries ??= new List<GlyphEntry>();
table.entries.Add(new GlyphEntry { Sprite = sprite, action = null });
serializedObject.Update();
InvalidateEntriesList(tableIndex);
InvalidateEntryView(tableIndex);
NotifyDatabaseChanged();
}
@ -674,7 +761,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
table.entries ??= new List<GlyphEntry>();
table.entries.Clear();
serializedObject.Update();
InvalidateEntriesList(tableIndex);
InvalidateEntryView(tableIndex);
NotifyDatabaseChanged();
}
@ -691,7 +778,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
});
SyncTableStates();
serializedObject.Update();
InvalidateAllEntriesLists();
InvalidateAllEntryViews();
NotifyDatabaseChanged();
}
@ -707,7 +794,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
SyncTableStates();
ClampSelectedTab();
serializedObject.Update();
InvalidateAllEntriesLists();
InvalidateAllEntryViews();
NotifyDatabaseChanged();
}
@ -734,7 +821,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
SyncTableStates();
serializedObject.Update();
InvalidateAllEntriesLists();
InvalidateAllEntryViews();
NotifyDatabaseChanged();
}
@ -822,7 +909,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
}
serializedObject.Update();
InvalidateEntriesList(tableIndex);
InvalidateEntryView(tableIndex);
NotifyDatabaseChanged();
Debug.Log($"[InputGlyphDatabase] Merged sprite sheet '{table.spriteSheetTexture.name}' into '{table.deviceName}'. sprites={sprites.Count}, replaced={replaced}, added={added}, total={table.entries.Count}");
}
@ -831,6 +918,7 @@ public sealed class InputGlyphDatabaseEditor : Editor
{
if (serializedObject.ApplyModifiedProperties())
{
InvalidateAllEntryViews();
NotifyDatabaseChanged();
}
}
@ -865,23 +953,163 @@ public sealed class InputGlyphDatabaseEditor : Editor
_selectedTab = Mathf.Clamp(_selectedTab, 0, maxIndex);
}
private void InvalidateEntriesList(int tableIndex)
private void MoveEntry(int tableIndex, int fromIndex, int toIndex)
{
if (!IsValidTableIndex(tableIndex))
{
return;
}
List<GlyphEntry> entries = _database.tables[tableIndex].entries;
if (entries == null || fromIndex < 0 || fromIndex >= entries.Count || toIndex < 0 || toIndex >= entries.Count || fromIndex == toIndex)
{
return;
}
Undo.RecordObject(_database, "Move glyph entry");
GlyphEntry entry = entries[fromIndex];
entries.RemoveAt(fromIndex);
entries.Insert(toIndex, entry);
serializedObject.Update();
InvalidateEntryView(tableIndex);
NotifyDatabaseChanged();
}
private void RemoveEntry(int tableIndex, int entryIndex)
{
if (!IsValidTableIndex(tableIndex))
{
return;
}
List<GlyphEntry> entries = _database.tables[tableIndex].entries;
if (entries == null || entryIndex < 0 || entryIndex >= entries.Count)
{
return;
}
Undo.RecordObject(_database, "Remove glyph entry");
entries.RemoveAt(entryIndex);
serializedObject.Update();
InvalidateEntryView(tableIndex);
NotifyDatabaseChanged();
}
private List<int> GetFilteredEntryIndices(int tableIndex, SerializedProperty entriesProperty, TableEditorState state)
{
string search = state.EntrySearch != null ? state.EntrySearch.Trim() : string.Empty;
if (state.CachedEntryCount == entriesProperty.arraySize && string.Equals(state.CachedSearch, search, StringComparison.Ordinal))
{
return state.FilteredEntryIndices;
}
state.FilteredEntryIndices.Clear();
for (int i = 0; i < entriesProperty.arraySize; i++)
{
if (DoesEntryMatchSearch(tableIndex, i, search))
{
state.FilteredEntryIndices.Add(i);
}
}
state.CachedEntryCount = entriesProperty.arraySize;
state.CachedSearch = search;
return state.FilteredEntryIndices;
}
private bool DoesEntryMatchSearch(int tableIndex, int entryIndex, string search)
{
if (string.IsNullOrWhiteSpace(search))
{
return true;
}
if (!IsValidTableIndex(tableIndex))
{
return false;
}
List<GlyphEntry> entries = _database.tables[tableIndex].entries;
if (entries == null || entryIndex < 0 || entryIndex >= entries.Count)
{
return false;
}
GlyphEntry entry = entries[entryIndex];
if (entry == null)
{
return ContainsIgnoreCase("null", search);
}
if (ContainsIgnoreCase(entry.Sprite != null ? entry.Sprite.name : string.Empty, search)
|| ContainsIgnoreCase(entry.action != null ? entry.action.name : string.Empty, search))
{
return true;
}
if (entry.action == null)
{
return false;
}
for (int i = 0; i < entry.action.bindings.Count; i++)
{
InputBinding binding = entry.action.bindings[i];
if (ContainsIgnoreCase(binding.path, search) || ContainsIgnoreCase(binding.effectivePath, search))
{
return true;
}
}
return false;
}
private static bool ContainsIgnoreCase(string value, string search)
{
return !string.IsNullOrEmpty(value) && value.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0;
}
private string GetEntryTitle(int tableIndex, int entryIndex)
{
if (!IsValidTableIndex(tableIndex))
{
return $"Entry #{entryIndex + 1}";
}
List<GlyphEntry> entries = _database.tables[tableIndex].entries;
if (entries == null || entryIndex < 0 || entryIndex >= entries.Count)
{
return $"Entry #{entryIndex + 1}";
}
GlyphEntry entry = entries[entryIndex];
string spriteName = entry?.Sprite != null ? entry.Sprite.name : "No Sprite";
string actionName = entry?.action != null ? entry.action.name : "No Action";
return $"#{entryIndex + 1} {spriteName} / {actionName}";
}
private void InvalidateEntryView(int tableIndex)
{
if (tableIndex < 0 || tableIndex >= _tableStates.Count)
{
return;
}
_tableStates[tableIndex].EntriesList = null;
_tableStates[tableIndex].EntriesPropertyPath = null;
InvalidateEntryView(_tableStates[tableIndex]);
}
private void InvalidateAllEntriesLists()
private static void InvalidateEntryView(TableEditorState state)
{
state.FilteredEntryIndices.Clear();
state.CachedSearch = string.Empty;
state.CachedEntryCount = -1;
}
private void InvalidateAllEntryViews()
{
for (int i = 0; i < _tableStates.Count; i++)
{
_tableStates[i].EntriesList = null;
_tableStates[i].EntriesPropertyPath = null;
InvalidateEntryView(_tableStates[i]);
}
}

@ -1 +1 @@
Subproject commit a978c68586cf761c577842532dfa6af5847851a4
Subproject commit e7c6b174fe953381196760a54432048990f74c99