port from perforce
This commit is contained in:
176
intromat/Intromat/ViewModels/CodeGenNetworkViewModel.cs
Normal file
176
intromat/Intromat/ViewModels/CodeGenNetworkViewModel.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user