176 lines
6.9 KiB
C#
176 lines
6.9 KiB
C#
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Reactive;
|
|
using System.Reactive.Linq;
|
|
using DynamicData;
|
|
using DynamicData.Alias;
|
|
using Intromat.Actions.Network;
|
|
using Intromat.Interfaces;
|
|
using Intromat.Nodes;
|
|
using Intromat.ViewModels.Nodes;
|
|
using Intromat.Views;
|
|
using NodeNetwork;
|
|
using NodeNetwork.ViewModels;
|
|
using NodeNetwork.Views;
|
|
using ReactiveUI;
|
|
|
|
namespace Intromat.ViewModels
|
|
{
|
|
public class CodeGenNetworkViewModel : NetworkViewModel, IRefreshProperties
|
|
{
|
|
private readonly ObservableAsPropertyHelper<MainEntryPointNode?> _entryPoint;
|
|
private readonly ObservableAsPropertyHelper<IRefreshProperties?> _selectedObject;
|
|
private string? _name;
|
|
private CodeGenNetworkViewModel? _parentNetwork;
|
|
private int _defaultWidth = 10;
|
|
private int _defaultHeight = 10;
|
|
|
|
static CodeGenNetworkViewModel()
|
|
{
|
|
NNViewRegistrar.AddRegistration(() => new CodeGenNetworkView(), typeof(IViewFor<CodeGenNetworkViewModel>));
|
|
}
|
|
|
|
public CodeGenNetworkViewModel(DocumentViewModel document, string name)
|
|
{
|
|
_name = name;
|
|
Document = document;
|
|
ConnectionFactory = (input, output) => new CodeGenConnectionViewModel(this, input, output);
|
|
Observable.Select(SelectedNodes.Connect(), _ => SelectedNodes.Count == 1 ? SelectedNodes.Items.First() : (ReactiveObject)this)
|
|
.StartWith(this)
|
|
.Cast<IRefreshProperties>()
|
|
.ToProperty(this, vm => vm.SelectedObject, out _selectedObject);
|
|
|
|
var nodes = Nodes.Connect();
|
|
Observable.Select(nodes, _ => (MainEntryPointNode?)Nodes.Items.FirstOrDefault(vm => vm is MainEntryPointNode))
|
|
.ToProperty(this, vm => vm.EntryPoint, out _entryPoint);
|
|
nodes.ActOnEveryObject(OnNodeAdded, OnNodeDeleted);
|
|
|
|
var a = Nodes.Connect()
|
|
.AutoRefreshOnObservable(node => node.Inputs.Connect())
|
|
.SelectMany(node => node.Inputs.Items)
|
|
.AutoRefreshOnObservable(input => input.Connections.Connect())
|
|
.SelectMany(input => input.Connections.Items);
|
|
|
|
var b = Nodes.Connect()
|
|
.AutoRefreshOnObservable(node => node.Outputs.Connect())
|
|
.SelectMany(node => node.Outputs.Items)
|
|
.AutoRefreshOnObservable(output => output.Connections.Connect())
|
|
.SelectMany(output => output.Connections.Items);
|
|
|
|
a.Zip(b, (x, _) => x).ActOnEveryObject(OnConnectionAdded, OnConnectionDeleted);
|
|
|
|
GroupNodes = ReactiveCommand.CreateFromTask(async () =>
|
|
{
|
|
var mainVm = document.MainViewModel;
|
|
var groupName = await mainVm.SelectName.Handle("Group name:");
|
|
if (groupName == null)
|
|
return;
|
|
|
|
var groupBinding = (CodeNodeGroupIOBinding?)mainVm.Grouper.MergeIntoGroup(this, SelectedNodes.Items);
|
|
if (groupBinding == null)
|
|
return;
|
|
|
|
var groupNode = (GroupNodeViewModel)groupBinding.GroupNode;
|
|
var subNet = (CodeGenNetworkViewModel)groupNode.Subnet!;
|
|
groupNode.Name = subNet.Name = groupName;
|
|
groupNode.IOBinding = groupBinding;
|
|
((GroupSubnetIONodeViewModel)groupBinding.EntranceNode).IOBinding = groupBinding;
|
|
((GroupSubnetIONodeViewModel)groupBinding.ExitNode).IOBinding = groupBinding;
|
|
}, this.WhenAnyObservable(vm => vm.SelectedNodes.CountChanged).Select(c => c > 1));
|
|
|
|
var isGroupNodeSelected = this.WhenAnyValue(vm => vm.SelectedNodes.CountChanged).Select(_ => SelectedNodes.Count == 1 && SelectedNodes.Items.First() is GroupNodeViewModel);
|
|
|
|
UngroupNodes = ReactiveCommand.Create(() =>
|
|
{
|
|
var selectedGroupNode = (GroupNodeViewModel)SelectedNodes.Items.First();
|
|
var mainVm = document.MainViewModel;
|
|
mainVm.Grouper.Ungroup(selectedGroupNode.IOBinding);
|
|
}, isGroupNodeSelected);
|
|
|
|
OpenGroup = ReactiveCommand.Create(() =>
|
|
{
|
|
var selectedGroupNode = (GroupNodeViewModel)SelectedNodes.Items.First();
|
|
Debug.Assert(selectedGroupNode.Subnet != null, "selectedGroupNode.Subnet != null");
|
|
|
|
document.NetworkBreadcrumbBar.ActivePath.Add(new NetworkBreadcrumbViewModel
|
|
{
|
|
ViewModel = selectedGroupNode.Subnet,
|
|
Name = selectedGroupNode.Name
|
|
});
|
|
}, isGroupNodeSelected);
|
|
}
|
|
|
|
public IObservableList<PropertyDescriptor>? PropertyDescriptors => null;
|
|
|
|
public CodeGenNetworkViewModel? ParentNetwork
|
|
{
|
|
get => _parentNetwork;
|
|
set => this.RaiseAndSetIfChanged(ref _parentNetwork, value);
|
|
}
|
|
|
|
public IRefreshProperties? SelectedObject => _selectedObject.Value;
|
|
|
|
public MainEntryPointNode? EntryPoint => _entryPoint.Value;
|
|
|
|
public DocumentViewModel Document { get; }
|
|
|
|
public string? Name
|
|
{
|
|
get => _name;
|
|
set => this.RaiseAndSetIfChanged(ref _name, value);
|
|
}
|
|
|
|
public int DefaultWidth
|
|
{
|
|
get => _defaultWidth;
|
|
set => this.RaiseAndSetIfChanged(ref _defaultWidth, value);
|
|
}
|
|
|
|
public int DefaultHeight
|
|
{
|
|
get => _defaultHeight;
|
|
set => this.RaiseAndSetIfChanged(ref _defaultHeight, value);
|
|
}
|
|
|
|
protected override void OnDeleteSelectedNodes()
|
|
{
|
|
var undoRedo = Document.MainViewModel.UndoRedo;
|
|
undoRedo.PushGroup(Document);
|
|
base.OnDeleteSelectedNodes();
|
|
undoRedo.PopGroup();
|
|
}
|
|
|
|
public override void FinishCut()
|
|
{
|
|
var undoRedo = Document.MainViewModel.UndoRedo;
|
|
undoRedo.PushGroup(Document);
|
|
base.FinishCut();
|
|
undoRedo.PopGroup();
|
|
}
|
|
|
|
private void OnNodeDeleted(NodeViewModel node)
|
|
{
|
|
Document.MainViewModel.UndoRedo.Record(new DeleteNodeAction(Document, this, node));
|
|
}
|
|
|
|
private void OnNodeAdded(NodeViewModel node)
|
|
{
|
|
Document.MainViewModel.UndoRedo.Record(new AddNodeAction(Document, this, node));
|
|
}
|
|
|
|
private void OnConnectionDeleted(ConnectionViewModel connection)
|
|
{
|
|
Document.MainViewModel.UndoRedo.Record(new DeleteConnectionAction(Document, this, connection));
|
|
}
|
|
|
|
private void OnConnectionAdded(ConnectionViewModel connection)
|
|
{
|
|
Document.MainViewModel.UndoRedo.Record(new AddConnectionAction(Document, this, connection));
|
|
}
|
|
|
|
public ReactiveCommand<Unit, Unit> GroupNodes { get; }
|
|
public ReactiveCommand<Unit, Unit> UngroupNodes { get; }
|
|
public ReactiveCommand<Unit, Unit> OpenGroup { get; }
|
|
}
|
|
} |