Skip to content

Commit

Permalink
Merge pull request #23 from Haruma-K/feature/fix_undo
Browse files Browse the repository at this point in the history
Fixed a bug where grouping is not applied when using undo
  • Loading branch information
Haruma-K authored Jan 9, 2024
2 parents feaa3cc + 2a50de3 commit 9462292
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 27 deletions.
86 changes: 65 additions & 21 deletions Assets/uPalette/Editor/Core/PaletteEditor/PaletteEditorTreeView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ namespace uPalette.Editor.Core.PaletteEditor
internal abstract class PaletteEditorTreeView<T> : TreeViewBase
{
private const string DragType = "PaletteEditorTreeView";
public char FolderDelimiter => UPaletteProjectSettings.instance.FolderDelimiter;

private readonly Dictionary<int, string> _columnIndexToThemeIdMap = new Dictionary<int, string>();
private readonly Dictionary<string, int> _entryIdToItemIdMap = new Dictionary<string, int>();
Expand Down Expand Up @@ -42,6 +41,8 @@ protected PaletteEditorTreeView(TreeViewState state) : base(state)
SetupColumnStates();
}

public char FolderDelimiter => UPaletteProjectSettings.instance.FolderDelimiter;

public IObservable<(PaletteEditorTreeViewEntryItem<T> item, int newIndex)> ItemIndexChangedAsObservable =>
_itemIndexChangedSubject;

Expand Down Expand Up @@ -75,16 +76,19 @@ public PaletteEditorTreeViewEntryItem<T> AddItem(string entryId, string name, Di
{
var entryItem = new PaletteEditorTreeViewEntryItem<T>(entryId, name, values)
{
id = _currentItemId++,
displayName = name
id = _currentItemId++
};
_entryIdToItemIdMap.Add(entryId, entryItem.id);
AddItemAndSetParent(entryItem, -1);
SetHierarchy(entryItem.id);
return entryItem;
}

private void SetHierarchy(int entryItemId)
/// <summary>
/// Set the item as a child item of the appropriate parent item. If there is no parent item, create it.
/// </summary>
/// <param name="entryItemId"></param>
public void SetHierarchy(int entryItemId)
{
var entryItem = (PaletteEditorTreeViewEntryItem<T>)GetItem(entryItemId);

Expand Down Expand Up @@ -126,17 +130,11 @@ private void SetHierarchy(int entryItemId)
}

// Parenting
var oldFolderPath = entryItem.Name.Value; // cache for removing empty folder
var oldParent = entryItem.parent; // cache for removing empty folder
var folderItemId = string.IsNullOrEmpty(folderPath) ? -1 : _folderPathToItemIdMap[folderPath];
SetParent(entryItemId, folderItemId);

// Remove empty folder
if (oldParent.id != -1 && !oldParent.hasChildren)
{
_folderPathToItemIdMap.Remove(oldFolderPath);
RemoveItem(oldParent.id, false);
}
// Remove empty folders
RemoveEmptyFolders();

// Set display name
var nonFolderName = hasFolder
Expand All @@ -154,6 +152,41 @@ private void SetHierarchy(int entryItemId)
}
}

private void RemoveEmptyFolders()
{
// Process in order of long folder path (from the end folder)
var orderedFolderPaths = _folderPathToItemIdMap.Keys
.OrderByDescending(x => x.Length)
.ToArray();

var removeTargetFolders = new List<(string path, int itemId)>();
foreach (var folderPath in orderedFolderPaths)
{
var folderItemId = _folderPathToItemIdMap[folderPath];
var folderItem = GetItem(folderItemId);

// if folder has no children, remove it.
if (!folderItem.hasChildren)
{
removeTargetFolders.Add((folderPath, folderItemId));
continue;
}

// if all children are remove target, remove it.
var allChildrenAreRemoveTarget = folderItem.children
.All(x => removeTargetFolders.Any(y => y.itemId == x.id));
if (allChildrenAreRemoveTarget)
removeTargetFolders.Add((folderPath, folderItemId));
}

foreach (var removeTargetFolder in removeTargetFolders)
{
var removeTargetFolderItemId = removeTargetFolder.itemId;
_folderPathToItemIdMap.Remove(removeTargetFolder.path);
RemoveItem(removeTargetFolderItemId, false);
}
}

public void SetFolderMode(bool folderMode, bool reload = true)
{
if (FolderMode == folderMode)
Expand Down Expand Up @@ -197,7 +230,7 @@ private void RemoveParentItemsIfEmpty(TreeViewItem item)
RemoveParentItemsIfEmpty(parent);
}
}

protected override bool CanRename(TreeViewItem item)
{
// Rename is not supported for folder.
Expand All @@ -207,7 +240,7 @@ protected override bool CanRename(TreeViewItem item)
// Set displayName to full name during rename.
if (FolderMode)
item.displayName = ((PaletteEditorTreeViewEntryItem<T>)item).Name.Value;

return true;
}

Expand All @@ -217,6 +250,7 @@ protected override void RenameEnded(RenameEndedArgs args)
if (args.acceptedRename)
item.SetName(args.newName, true);

// Set displayName to non-folder name after rename.
if (FolderMode)
{
var name = item.Name.Value;
Expand All @@ -226,11 +260,6 @@ protected override void RenameEnded(RenameEndedArgs args)
: name;
item.displayName = nonFolderName;
}

SetHierarchy(item.id);
if (FolderMode)
OrderItemsByName(item.parent, true);
Reload();
}

protected override void CellGUI(int columnIndex, Rect cellRect, RowGUIArgs args)
Expand Down Expand Up @@ -312,7 +341,7 @@ protected override bool CanStartDrag(CanStartDragArgs args)
// Index is not supported in folder mode because items are sorted by name.
if (FolderMode)
return false;

return string.IsNullOrEmpty(searchString);
}

Expand Down Expand Up @@ -342,7 +371,7 @@ protected override DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args)
// Index is not supported in folder mode because items are sorted by name.
if (FolderMode)
return DragAndDropVisualMode.None;

if (args.performDrop)
{
var data = DragAndDrop.GetGenericData(DragType);
Expand Down Expand Up @@ -378,6 +407,12 @@ protected override DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args)
return DragAndDropVisualMode.Move;
}

/// <summary>
/// Sort items by specifying index
/// </summary>
/// <param name="entryItem"></param>
/// <param name="index"></param>
/// <param name="notify"></param>
public void SetItemIndex(PaletteEditorTreeViewEntryItem<T> entryItem, int index, bool notify)
{
var children = RootItem.children;
Expand All @@ -388,6 +423,10 @@ public void SetItemIndex(PaletteEditorTreeViewEntryItem<T> entryItem, int index,
_itemIndexChangedSubject.OnNext((entryItem, index));
}

/// <summary>
/// Sort items according to name
/// </summary>
/// <param name="item"></param>
public void SetItemIndexByName(TreeViewItem item)
{
var children = item.parent.children;
Expand All @@ -401,6 +440,11 @@ public void SetItemIndexByName(TreeViewItem item)
children.Insert(index, item);
}

/// <summary>
/// Sort all items under <see cref="parent" /> according to name
/// </summary>
/// <param name="parent"></param>
/// <param name="recursive"></param>
public void OrderItemsByName(TreeViewItem parent, bool recursive)
{
if (parent.children == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ public PaletteEditorWindowContentsViewPresenter(Palette<T> palette, PaletteEdito
foreach (var entry in sortedEntries)
{
var index = _palette.GetEntryOrder(entry.Id);
AddTreeViewItem(entry, index);
AddTreeViewItem(entry, index, false);
}

_view.TreeView.OrderItemsByName(_view.TreeView.RootItem, true);

view.TreeView.Reload();
}

Expand Down Expand Up @@ -98,7 +100,7 @@ private void OnThemeOrderChanged()
RefreshTreeViewColumns();
}

private void AddTreeViewItem(Entry<T> entry, int index)
private void AddTreeViewItem(Entry<T> entry, int index, bool doSort = true)
{
var treeView = _view.TreeView;

Expand All @@ -112,10 +114,13 @@ private void AddTreeViewItem(Entry<T> entry, int index)
}

var item = treeView.AddItem(entry.Id, entry.Name.Value, values);
if (treeView.FolderMode)
treeView.SetItemIndexByName(item);
else
treeView.SetItemIndex(item, index, false);
if (doSort)
{
if (treeView.FolderMode)
treeView.SetItemIndexByName(item);
else
treeView.SetItemIndex(item, index, false);
}

// Observe entry.
var disposable = new CompositeDisposable();
Expand Down Expand Up @@ -152,6 +157,17 @@ private void AddTreeViewItem(Entry<T> entry, int index)
.Subscribe(x => item.ClearValues())
.DisposeWith(disposable);

entry.Name.Subscribe(x =>
{
treeView.SetHierarchy(item.id);
if (treeView.FolderMode)
treeView.SetItemIndexByName(item);
else
treeView.SetItemIndex(item, index, false);
treeView.Reload();
})
.DisposeWith(disposable);

_perItemDisposables.Add(entry.Id, disposable);
treeView.Reload();
}
Expand Down

0 comments on commit 9462292

Please sign in to comment.