using System.Collections.Generic; using System.Linq; using System.Reactive; using Intromat.Views.Editors; using NodeNetwork.Toolkit.ValueNode; using NodeNetwork.ViewModels; using ReactiveUI; using Splat; namespace Intromat.ViewModels.Nodes { /// /// A non-generic interface that provides access to the data in GroupEndpointEditorViewModel. /// Mapping a view onto a generic viewmodel is problematic because the generic type often isn't known in the view, /// and generic views are often not allowed. /// public interface IGroupEndpointEditorViewModel { public Endpoint Endpoint { get; } public ReactiveCommand MoveUp { get; } public ReactiveCommand MoveDown { get; } public ReactiveCommand Delete { get; } } public class GroupEndpointEditorViewModel : ValueEditorViewModel, IGroupEndpointEditorViewModel { static GroupEndpointEditorViewModel() { Locator.CurrentMutable.Register(() => new GroupEndpointEditorView(), typeof(IViewFor>)); } public GroupEndpointEditorViewModel(CodeNodeGroupIOBinding nodeGroupBinding) { MoveUp = ReactiveCommand.Create(() => { var isInput = Parent is NodeInputViewModel; IEnumerable endpoints = isInput ? Parent.Parent.Inputs.Items : Parent.Parent.Outputs.Items; // Swap SortIndex of this endpoint with the SortIndex of the previous endpoint in the list, if any. var prevElement = endpoints .Where(e => e.SortIndex < Parent.SortIndex) .MaxBy(e => e.SortIndex); if (prevElement != null) { var idx = prevElement.SortIndex; prevElement.SortIndex = Parent.SortIndex; Parent.SortIndex = idx; } }); MoveDown = ReactiveCommand.Create(() => { var isInput = Parent is NodeInputViewModel; IEnumerable endpoints = isInput ? Parent.Parent.Inputs.Items : Parent.Parent.Outputs.Items; var nextElement = endpoints .Where(e => e.SortIndex > Parent.SortIndex) .MinBy(e => e.SortIndex); if (nextElement != null) { var idx = nextElement.SortIndex; nextElement.SortIndex = Parent.SortIndex; Parent.SortIndex = idx; } }); Delete = ReactiveCommand.Create(() => { nodeGroupBinding.DeleteEndpoint(Parent); }); } public Endpoint Endpoint => Parent; public ReactiveCommand MoveUp { get; } public ReactiveCommand MoveDown { get; } public ReactiveCommand Delete { get; } } }