Skip to content

Commit

Permalink
Implement insert above/below in data tree
Browse files Browse the repository at this point in the history
  • Loading branch information
ReMinoer committed Jul 26, 2022
1 parent 3cadee4 commit 675500b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 17 deletions.
2 changes: 2 additions & 0 deletions Calame.Icons/Providers/CalameIconProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ protected override PackIconMaterialKind GetTargetKey(CalameIconKey key)
case CalameIconKey.Folder: return PackIconMaterialKind.FolderOpen;
case CalameIconKey.Add: return PackIconMaterialKind.PlusCircle;
case CalameIconKey.AddFromList: return PackIconMaterialKind.PlaylistPlus;
case CalameIconKey.InsertAbove: return PackIconMaterialKind.ArrowUpRightBold;
case CalameIconKey.InsertBelow: return PackIconMaterialKind.ArrowDownRightBold;
case CalameIconKey.Delete: return PackIconMaterialKind.CloseCircle;
case CalameIconKey.Select: return PackIconMaterialKind.ArrowTopRightThick;
case CalameIconKey.OpenWith: return PackIconMaterialKind.ApplicationImport;
Expand Down
2 changes: 2 additions & 0 deletions Calame/Icons/CalameIconKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public enum CalameIconKey
Folder,
Add,
AddFromList,
InsertAbove,
InsertBelow,
Delete,
Select,
OpenWith,
Expand Down
57 changes: 47 additions & 10 deletions Calame/Utils/AddCollectionItemCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class AddCollectionItemCommand : ICommand
private readonly IList<Type> _newTypeRegistry;
private readonly IIconProvider _iconProvider;
private readonly IIconDescriptor _iconDescriptor;
private readonly object _targetItem;
private readonly bool _afterTarget;

private IList<Type> _newItemTypes;
private readonly ICommand _addItemCommand;
Expand All @@ -25,29 +27,54 @@ public class AddCollectionItemCommand : ICommand

public event EventHandler CanExecuteChanged;

public AddCollectionItemCommand(IList list, Action<int, object> insertItemAction, IList<Type> newTypeRegistry, IIconProvider iconProvider, IIconDescriptor iconDescriptor)
public AddCollectionItemCommand(IList list,
Action<int, object> insertItemAction,
IList<Type> newTypeRegistry,
IIconProvider iconProvider,
IIconDescriptor iconDescriptor,
object targetItem = null,
bool afterTarget = false)
{
_list = list;
_insertItemAction = insertItemAction;
_newTypeRegistry = newTypeRegistry;
_iconProvider = iconProvider;
_iconDescriptor = iconDescriptor;
_addItemCommand = new RelayCommand(x => InsertItemOfType(_list.Count, (Type)x));
_targetItem = targetItem;
_afterTarget = afterTarget;
_addItemCommand = new RelayCommand(x => InsertItemOfType((Type)x));

RefreshNewItemTypes();
}

public bool CanExecute(object _) => _newItemTypes != null && _newItemTypes.Count > 0;
public void Execute(object _)
public bool CanExecute(object obj) => _newItemTypes != null && _newItemTypes.Count > 0;
public void Execute(object obj)
{
if (_newItemTypes.Count == 1)
{
InsertItemOfType(_list.Count, _newItemTypes[0]);
InsertItemOfType(_newItemTypes[0]);
return;
}

var contextMenu = new ContextMenu();
BuildMenuItems(contextMenu.Items);
contextMenu.IsOpen = true;
}

public void SetupMenuItem(MenuItem menuItem)
{
if (_newItemTypes.Count == 1)
{
menuItem.Command = _addItemCommand;
menuItem.CommandParameter = _newItemTypes[0];
return;
}

BuildMenuItems(menuItem.Items);
}

public void BuildMenuItems(IList menuItems)
{
string[] typeNames = _newItemTypes.Select(x => x.Name).ToArray();
ReduceTypeNamePatterns(typeNames);

Expand All @@ -61,14 +88,24 @@ public void Execute(object _)
Icon = _iconProvider.GetControl(_iconDescriptor.GetTypeIcon(_newItemTypes[i]), 16)
};

contextMenu.Items.Add(menuItem);
menuItems.Add(menuItem);
}

contextMenu.IsOpen = true;
}

private void InsertItemOfType(int index, Type itemType) => InsertItem(index, CreateItem(itemType));
private void InsertItem(int index, object item) => _insertItemAction?.Invoke(index, item);
private void InsertItemOfType(Type itemType) => InsertItem(CreateItem(itemType));
private void InsertItem(object item) => _insertItemAction?.Invoke(GetTargetIndex(), item);

private int GetTargetIndex()
{
if (_targetItem is null)
return _list.Count;

int index = _list.IndexOf(_targetItem);
if (_afterTarget)
index++;

return index;
}

private object CreateItem(Type type)
{
Expand Down
34 changes: 27 additions & 7 deletions Modules/Calame.DataModelTree/ViewModels/DataModelTreeViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,19 @@ public DataModelTreeViewModel(IShell shell, IEventAggregator eventAggregator, II
.ChildrenSource(x => new EnumerableReadOnlyObservableList<object>(x.Children), nameof(IGlyphDataChildrenSource.Children))
.IconDescription(x => IconDescriptor.GetIcon(x.Children), nameof(IGlyphDataChildrenSource.Children))
.IsHeader(_ => true)
.QuickCommand(CreateAddCommand, nameof(IGlyphDataChildrenSource.Children))
.QuickCommand(x => CreateAddCommand(x), nameof(IGlyphDataChildrenSource.Children))
.QuickCommandIconDescription(_ => new IconDescription(CalameIconKey.Add, Brushes.DarkGreen, margin: 0.5))
.QuickCommandLabel(_ => "Add")
.QuickCommandToolTip(_ => "Add");
}

private ICommand CreateAddCommand(IGlyphDataChildrenSource childrenSource)
private AddCollectionItemCommand CreateAddCommand(IGlyphDataChildrenSource childrenSource, IGlyphData insertTarget = null, bool afterTarget = false)
{
if (!(childrenSource.Children is IList list))
return null;

return new AddCollectionItemCommand(list, (i, x) => AddDataChild(childrenSource, i, (IGlyphData)x), _newTypeRegistry, IconProvider, IconDescriptor);
return new AddCollectionItemCommand(list,
(i, x) => AddDataChild(childrenSource, i, (IGlyphData)x), _newTypeRegistry, IconProvider, IconDescriptor, insertTarget, afterTarget);
}

private void AddDataChild(IGlyphDataChildrenSource childrenSource, int index, IGlyphData child)
Expand All @@ -130,9 +131,31 @@ private IEnumerable GetContextMenuItems(IGlyphData data)
{
if (data.ParentSource != null)
{
if (data.ParentSource is IGlyphDataChildrenSource childrenSource)
{
var insertAboveItem = new MenuItem
{
Header = "Insert _Above",
Icon = IconProvider.GetControl(IconDescriptor.GetIcon(CalameIconKey.InsertAbove), 16)
};

var insertBelowItem = new MenuItem
{
Header = "_Insert Below",
Icon = IconProvider.GetControl(IconDescriptor.GetIcon(CalameIconKey.InsertBelow), 16)
};

CreateAddCommand(childrenSource, insertTarget: data).SetupMenuItem(insertAboveItem);
CreateAddCommand(childrenSource, insertTarget: data, afterTarget: true).SetupMenuItem(insertBelowItem);

yield return insertAboveItem;
yield return insertBelowItem;
yield return new Separator();
}

yield return new MenuItem
{
Header = "Remove",
Header = "_Remove",
Command = _removeCommand,
CommandParameter = data,
Icon = IconProvider.GetControl(IconDescriptor.GetIcon(CalameIconKey.Delete), 16)
Expand All @@ -148,9 +171,6 @@ private void OnRemove(object obj)

var child = (IGlyphData)obj;

if (Selection == child)
Selection = null;

IGlyphDataSource childrenSource = child.ParentSource;
int index = childrenSource.IndexOf(child);

Expand Down

0 comments on commit 675500b

Please sign in to comment.