port from perforce
This commit is contained in:
9
intromat/NodeNetworkToolkit/.editorconfig
Normal file
9
intromat/NodeNetworkToolkit/.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
[*.cs]
|
||||
|
||||
dotnet_diagnostic.IDE0019.severity = none
|
||||
dotnet_diagnostic.IDE0038.severity = none
|
||||
dotnet_diagnostic.IDE0044.severity = none
|
||||
dotnet_diagnostic.IDE0052.severity = none
|
||||
dotnet_diagnostic.IDE0058.severity = none
|
||||
dotnet_diagnostic.IDE0062.severity = none
|
||||
dotnet_diagnostic.IDE0090.severity = none
|
||||
@@ -0,0 +1,23 @@
|
||||
<UserControl x:Class="NodeNetwork.Toolkit.BreadcrumbBar.BreadcrumbBarView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<ListView x:Name="list" SelectionMode="Single">
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Data="M 0,0 L 2.5,2.5 L 0,5" Margin="0,2,6,0" StrokeThickness="2" Stroke="#555555" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Name}" TextAlignment="Center" VerticalAlignment="Stretch"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using NodeNetwork.Utilities;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Legacy;
|
||||
|
||||
namespace NodeNetwork.Toolkit.BreadcrumbBar
|
||||
{
|
||||
public partial class BreadcrumbBarView : UserControl, IViewFor<BreadcrumbBarViewModel>
|
||||
{
|
||||
#region ViewModel
|
||||
public static readonly DependencyProperty ViewModelProperty =
|
||||
DependencyProperty.Register(nameof(ViewModel), typeof(BreadcrumbBarViewModel), typeof(BreadcrumbBarView), new PropertyMetadata(null));
|
||||
|
||||
public BreadcrumbBarViewModel ViewModel
|
||||
{
|
||||
get => (BreadcrumbBarViewModel)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (BreadcrumbBarViewModel)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public BreadcrumbBarView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.BindList(ViewModel, vm => vm.ActivePath, v => v.list.ItemsSource).DisposeWith(d);
|
||||
this.WhenAnyValue(v => v.list.SelectedItem)
|
||||
.Where(i => i != null)
|
||||
.Cast<BreadcrumbViewModel>()
|
||||
.Do(_ => list.UnselectAll())
|
||||
.InvokeCommand(this, v => v.ViewModel.SelectCrumb).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using DynamicData;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.BreadcrumbBar
|
||||
{
|
||||
/// <summary>
|
||||
/// Viewmodel for a single element of the BreadcrumbBar.
|
||||
/// </summary>
|
||||
public class BreadcrumbViewModel : ReactiveObject
|
||||
{
|
||||
#region Name
|
||||
/// <summary>
|
||||
/// Displayed name of the crumb.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => this.RaiseAndSetIfChanged(ref _name, value);
|
||||
}
|
||||
private string _name = "";
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ViewModel for the BreadcrumbBar.
|
||||
/// This UI element displays a path as a list of path elements (crumbs), allowing navigation by selection of path elements.
|
||||
/// </summary>
|
||||
public class BreadcrumbBarViewModel : ReactiveObject
|
||||
{
|
||||
static BreadcrumbBarViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new BreadcrumbBarView(), typeof(IViewFor<BreadcrumbBarViewModel>));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The path that is currently displayed in the bar.
|
||||
/// Add or remove elements to modify the path.
|
||||
/// </summary>
|
||||
public ISourceList<BreadcrumbViewModel> ActivePath { get; } = new SourceList<BreadcrumbViewModel>();
|
||||
|
||||
#region ActiveElement
|
||||
/// <summary>
|
||||
/// The deepest element of the currect path. (Last element of ActivePath)
|
||||
/// </summary>
|
||||
public BreadcrumbViewModel ActiveItem => _activeItem.Value;
|
||||
private readonly ObservableAsPropertyHelper<BreadcrumbViewModel> _activeItem;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Navigate to the subpath represented by the selected crumb which is passed as a parameter.
|
||||
/// Only this crumb and its ancestors are kept, the rest of the path is removed.
|
||||
/// </summary>
|
||||
public ReactiveCommand<BreadcrumbViewModel, Unit> SelectCrumb { get; }
|
||||
|
||||
public BreadcrumbBarViewModel()
|
||||
{
|
||||
SelectCrumb = ReactiveCommand.Create((BreadcrumbViewModel crumb) =>
|
||||
{
|
||||
ActivePath.Edit(l =>
|
||||
{
|
||||
int index = l.IndexOf(crumb);
|
||||
for (int i = l.Count - 1; i > index; i--)
|
||||
{
|
||||
l.RemoveAt(i);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ActivePath.Connect().Select(_ => ActivePath.Count > 0 ? ActivePath.Items.ElementAt(ActivePath.Count - 1) : null)
|
||||
.ToProperty(this, vm => vm.ActiveItem, out _activeItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using DynamicData;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ContextMenu
|
||||
{
|
||||
/// <summary>
|
||||
/// A viewmodel for a context menu that allows users to add nodes to a network.
|
||||
/// </summary>
|
||||
public class AddNodeContextMenuViewModel : SearchableContextMenuViewModel
|
||||
{
|
||||
static AddNodeContextMenuViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new SearchableContextMenuView(), typeof(IViewFor<AddNodeContextMenuViewModel>));
|
||||
}
|
||||
|
||||
#region Network
|
||||
/// <summary>
|
||||
/// The network to which the nodes are to be added.
|
||||
/// </summary>
|
||||
public NetworkViewModel Network
|
||||
{
|
||||
get => _network;
|
||||
set => this.RaiseAndSetIfChanged(ref _network, value);
|
||||
}
|
||||
private NetworkViewModel _network;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The format that is used to create labels for the menu entries based on the node name.
|
||||
/// E.g. "Add {0}"
|
||||
/// </summary>
|
||||
public string LabelFormat { get; }
|
||||
|
||||
/// <summary>
|
||||
/// When adding a node to the network,
|
||||
/// this function is used to determine the position at which it is placed.
|
||||
/// </summary>
|
||||
public Func<NodeViewModel, Point> NodePositionFunc { get; set; } = (node) => new Point();
|
||||
|
||||
/// <summary>
|
||||
/// A callback that is called after a node is added to the network through this menu.
|
||||
/// </summary>
|
||||
public Action<NodeViewModel> OnNodeAdded { get; set; } = node => { };
|
||||
|
||||
/// <summary>
|
||||
/// An interaction that is used to open contextmenu views given a SearchableContextMenuViewModel.
|
||||
/// Used in ShowAddNodeForPendingConnectionMenu to display this menu, and a menu for choosing an endpoint.
|
||||
/// </summary>
|
||||
public Interaction<SearchableContextMenuViewModel, Unit> OpenContextMenu { get; } = new Interaction<SearchableContextMenuViewModel, Unit>();
|
||||
|
||||
private ReactiveCommand<NodeTemplate, Unit> CreateNode { get; }
|
||||
|
||||
public AddNodeContextMenuViewModel(string labelFormat = "{0}")
|
||||
{
|
||||
LabelFormat = labelFormat;
|
||||
|
||||
CreateNode = ReactiveCommand.Create<NodeTemplate, Unit>((template) =>
|
||||
{
|
||||
var nodeInstance = template.Factory();
|
||||
Network.Nodes.Add(nodeInstance);
|
||||
nodeInstance.Position = NodePositionFunc(nodeInstance);
|
||||
OnNodeAdded(nodeInstance);
|
||||
return Unit.Default;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new node type to the list.
|
||||
/// Every time a node is added to a network from this list, the factory function in the template
|
||||
/// will be called to create a new instance of the viewmodel type.
|
||||
/// </summary>
|
||||
/// <param name="template">The template with the node type to add.</param>
|
||||
public void AddNodeType(NodeTemplate template)
|
||||
{
|
||||
Commands.Add(new LabeledCommand
|
||||
{
|
||||
Label = string.Format(LabelFormat, template.Instance.Name),
|
||||
Command = CreateNode,
|
||||
CommandParameter = template
|
||||
});
|
||||
}
|
||||
|
||||
public void AddNodeTypes(IEnumerable<NodeTemplate> templates)
|
||||
{
|
||||
foreach (var nodeTemplate in templates)
|
||||
{
|
||||
AddNodeType(nodeTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowOnlyConnectableNodes(PendingConnectionViewModel testCon)
|
||||
{
|
||||
foreach (var cmd in Commands.Items)
|
||||
{
|
||||
var curNodeTemplate = (NodeTemplate)cmd.CommandParameter;
|
||||
|
||||
bool hasValidEndpoint =
|
||||
testCon.InputIsLocked ?
|
||||
GetConnectableOutputs(curNodeTemplate.Instance, testCon).Any() :
|
||||
GetConnectableInputs(curNodeTemplate.Instance, testCon).Any();
|
||||
|
||||
cmd.Visible = hasValidEndpoint;
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowAddNodeForPendingConnectionMenu(PendingConnectionViewModel pendingCon)
|
||||
{
|
||||
var testCon = new PendingConnectionViewModel(pendingCon.Parent) // Copy used to test which inputs/outputs will work with the pending connection
|
||||
{
|
||||
Input = pendingCon.Input,
|
||||
InputIsLocked = pendingCon.InputIsLocked,
|
||||
Output = pendingCon.Output,
|
||||
OutputIsLocked = pendingCon.OutputIsLocked
|
||||
};
|
||||
|
||||
ShowOnlyConnectableNodes(testCon);
|
||||
|
||||
// After a node type is chosen, pick an endpoint
|
||||
OnNodeAdded = node =>
|
||||
{
|
||||
if (testCon.InputIsLocked)
|
||||
{
|
||||
var outputs = GetConnectableOutputs(node, testCon).ToList();
|
||||
if (outputs.Count == 1)
|
||||
{
|
||||
// If only 1 output matches, select this one
|
||||
Network.Connections.Add(Network.ConnectionFactory(pendingCon.Input, outputs[0]));
|
||||
Network.RemovePendingConnection();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Open a menu to let the user choose the desired output to connect to
|
||||
var chooseEndpointVM = new SearchableContextMenuViewModel();
|
||||
var cmd = ReactiveCommand.Create<NodeOutputViewModel, Unit>((o) =>
|
||||
{
|
||||
Network.Connections.Add(Network.ConnectionFactory(pendingCon.Input, o));
|
||||
Network.RemovePendingConnection();
|
||||
return Unit.Default;
|
||||
});
|
||||
foreach (var output in outputs)
|
||||
{
|
||||
chooseEndpointVM.Commands.Add(new LabeledCommand
|
||||
{
|
||||
Command = cmd,
|
||||
CommandParameter = output,
|
||||
Label = output.Name
|
||||
});
|
||||
}
|
||||
|
||||
OpenContextMenu.Handle(chooseEndpointVM).Subscribe();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var inputs = GetConnectableInputs(node, testCon).ToList();
|
||||
if (inputs.Count == 1)
|
||||
{
|
||||
Network.Connections.Add(Network.ConnectionFactory(inputs[0], pendingCon.Output));
|
||||
Network.RemovePendingConnection();
|
||||
}
|
||||
else
|
||||
{
|
||||
var chooseEndpointVM = new SearchableContextMenuViewModel();
|
||||
var cmd = ReactiveCommand.Create<NodeInputViewModel, Unit>((i) =>
|
||||
{
|
||||
Network.Connections.Add(Network.ConnectionFactory(i, pendingCon.Output));
|
||||
Network.RemovePendingConnection();
|
||||
return Unit.Default;
|
||||
});
|
||||
foreach (var input in inputs)
|
||||
{
|
||||
chooseEndpointVM.Commands.Add(new LabeledCommand
|
||||
{
|
||||
Command = cmd,
|
||||
CommandParameter = input,
|
||||
Label = input.Name
|
||||
});
|
||||
}
|
||||
|
||||
OpenContextMenu.Handle(chooseEndpointVM).Subscribe();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
OpenContextMenu.Handle(this).Subscribe();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a set of node templates, return those which have an endpoint
|
||||
/// that could be connected to the specified pending connection.
|
||||
/// </summary>
|
||||
public static IEnumerable<NodeTemplate> GetConnectableNodes(IEnumerable<NodeTemplate> candidateNodeTemplates, PendingConnectionViewModel testCon)
|
||||
{
|
||||
foreach (var curNode in candidateNodeTemplates)
|
||||
{
|
||||
bool hasValidEndpoint =
|
||||
testCon.InputIsLocked ?
|
||||
GetConnectableOutputs(curNode.Instance, testCon).Any() :
|
||||
GetConnectableInputs(curNode.Instance, testCon).Any();
|
||||
|
||||
if (hasValidEndpoint)
|
||||
{
|
||||
yield return curNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a node viewmodel, return the outputs which could be connected to the pending connection.
|
||||
/// Assumes testCon.Input is set.
|
||||
/// </summary>
|
||||
public static IEnumerable<NodeOutputViewModel> GetConnectableOutputs(NodeViewModel node, PendingConnectionViewModel testCon)
|
||||
{
|
||||
var validator = testCon.Input.ConnectionValidator;
|
||||
foreach (var curOutput in node.Outputs.Items)
|
||||
{
|
||||
testCon.Output = curOutput;
|
||||
if (curOutput.MaxConnections > 0 && validator(testCon).IsValid)
|
||||
{
|
||||
yield return curOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a node viewmodel, return the inputs which could be connected to the pending connection.
|
||||
/// Assumes testCon.Output is set.
|
||||
/// </summary>
|
||||
public static IEnumerable<NodeInputViewModel> GetConnectableInputs(NodeViewModel node, PendingConnectionViewModel testCon)
|
||||
{
|
||||
foreach (var curInput in node.Inputs.Items)
|
||||
{
|
||||
var validator = curInput.ConnectionValidator;
|
||||
testCon.Input = curInput;
|
||||
if (curInput.MaxConnections > 0 && validator(testCon).IsValid)
|
||||
{
|
||||
yield return curInput;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<ContextMenu x:Class="NodeNetwork.Toolkit.ContextMenu.SearchableContextMenuView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:NodeNetwork.Toolkit.ContextMenu"
|
||||
xmlns:viewModels="clr-namespace:NodeNetwork.ViewModels;assembly=NodeNetwork"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800" x:Name="self">
|
||||
<ContextMenu.Resources>
|
||||
<Style TargetType="{x:Type MenuItem}">
|
||||
<Style.Setters>
|
||||
<Setter Property="Command" Value="{Binding Command}"/>
|
||||
<Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
<DataTemplate DataType="{x:Type local:LabeledCommand}">
|
||||
<TextBlock><Run Text="{Binding Label}"/></TextBlock>
|
||||
</DataTemplate>
|
||||
</ContextMenu.Resources>
|
||||
<ContextMenu.ItemsSource>
|
||||
<CompositeCollection>
|
||||
<MenuItem x:Name="SearchMenuItem" StaysOpenOnClick="True">
|
||||
<MenuItem.Header>
|
||||
<TextBox x:Name="SearchTextBox" MinWidth="150"></TextBox>
|
||||
</MenuItem.Header>
|
||||
</MenuItem>
|
||||
<CollectionContainer x:Name="CollectionContainer"/>
|
||||
<Separator/>
|
||||
<CollectionContainer x:Name="ContainerBelowSearch"/>
|
||||
</CompositeCollection>
|
||||
</ContextMenu.ItemsSource>
|
||||
</ContextMenu>
|
||||
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using DynamicData;
|
||||
using NodeNetwork.Utilities;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ContextMenu
|
||||
{
|
||||
public partial class SearchableContextMenuView : IViewFor<SearchableContextMenuViewModel>
|
||||
{
|
||||
#region ViewModel
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(SearchableContextMenuViewModel), typeof(SearchableContextMenuView), new PropertyMetadata(null));
|
||||
|
||||
public SearchableContextMenuViewModel ViewModel
|
||||
{
|
||||
get => (SearchableContextMenuViewModel)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (SearchableContextMenuViewModel)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ChildrenBelowSearch
|
||||
public static readonly DependencyProperty ChildrenBelowSearchProperty =
|
||||
DependencyProperty.Register(nameof(ChildrenBelowSearch), typeof(IEnumerable), typeof(SearchableContextMenuView), new PropertyMetadata(new object[0]));
|
||||
|
||||
public IEnumerable ChildrenBelowSearch
|
||||
{
|
||||
get => (IEnumerable)GetValue(ChildrenBelowSearchProperty);
|
||||
set => SetValue(ChildrenBelowSearchProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReferencePointElement
|
||||
public static readonly DependencyProperty ReferencePointElementProperty =
|
||||
DependencyProperty.Register(nameof(ReferencePointElement), typeof(IInputElement), typeof(SearchableContextMenuView), new PropertyMetadata(null));
|
||||
|
||||
public IInputElement ReferencePointElement
|
||||
{
|
||||
get => (IInputElement)GetValue(ReferencePointElementProperty);
|
||||
set => SetValue(ReferencePointElementProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OpenPoint
|
||||
public static readonly DependencyProperty OpenPointProperty =
|
||||
DependencyProperty.Register(nameof(OpenPoint), typeof(Point), typeof(SearchableContextMenuView), new PropertyMetadata(new Point()));
|
||||
|
||||
public Point OpenPoint
|
||||
{
|
||||
get => (Point)GetValue(OpenPointProperty);
|
||||
private set => SetValue(OpenPointProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public SearchableContextMenuView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SearchQuery, v => v.SearchTextBox.Text);
|
||||
this.BindList(ViewModel, vm => vm.VisibleCommands, v => v.CollectionContainer.Collection);
|
||||
|
||||
Binding myBinding = new Binding(nameof(ChildrenBelowSearch)) { Source = this };
|
||||
BindingOperations.SetBinding(ContainerBelowSearch, CollectionContainer.CollectionProperty, myBinding);
|
||||
|
||||
this.Opened += (sender, args) =>
|
||||
{
|
||||
SearchTextBox.Focus();
|
||||
if (ReferencePointElement != null)
|
||||
{
|
||||
OpenPoint = Mouse.GetPosition(ReferencePointElement);
|
||||
}
|
||||
};
|
||||
|
||||
// This var is needed to ensure both key down and key up of arrow keys happened in the textbox,
|
||||
// otherwise moving into the textbox will immediately move out again.
|
||||
bool arrowWasPressedInTextBox = false;
|
||||
|
||||
this.SearchTextBox.PreviewKeyDown += (sender, args) =>
|
||||
{
|
||||
if (args.Key == Key.Enter || args.Key == Key.Return)
|
||||
{
|
||||
if (ViewModel.VisibleCommands.Count > 0)
|
||||
{
|
||||
var firstEntry = ViewModel.VisibleCommands.Items.First();
|
||||
firstEntry.Command.Execute(firstEntry.CommandParameter);
|
||||
this.IsOpen = false;
|
||||
}
|
||||
}
|
||||
else if (args.Key == Key.Escape && SearchTextBox.Text.Length > 0)
|
||||
{
|
||||
SearchTextBox.Text = "";
|
||||
args.Handled = true;
|
||||
}
|
||||
else if (args.Key == Key.Up || args.Key == Key.Down)
|
||||
{
|
||||
arrowWasPressedInTextBox = true;
|
||||
}
|
||||
};
|
||||
this.SearchTextBox.PreviewKeyUp += (sender, args) =>
|
||||
{
|
||||
if (arrowWasPressedInTextBox && (args.Key == Key.Up || args.Key == Key.Down))
|
||||
{
|
||||
arrowWasPressedInTextBox = false;
|
||||
|
||||
var dir = args.Key == Key.Up ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next;
|
||||
var traversalRequest = new TraversalRequest(dir);
|
||||
var focusedElem = Keyboard.FocusedElement as FrameworkElement;
|
||||
focusedElem?.MoveFocus(traversalRequest);
|
||||
}
|
||||
};
|
||||
this.SearchMenuItem.GotKeyboardFocus += (sender, args) => { SearchTextBox.Focus(); };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using DynamicData;
|
||||
using ReactiveUI;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ContextMenu
|
||||
{
|
||||
/// <summary>
|
||||
/// A data type containing a command, parameter and display properties.
|
||||
/// </summary>
|
||||
public class LabeledCommand : ReactiveObject
|
||||
{
|
||||
#region Label
|
||||
/// <summary>
|
||||
/// The label that is displayed in the menu
|
||||
/// </summary>
|
||||
public string Label
|
||||
{
|
||||
get => _label;
|
||||
set => this.RaiseAndSetIfChanged(ref _label, value);
|
||||
}
|
||||
private string _label = "";
|
||||
#endregion
|
||||
|
||||
#region Visible
|
||||
/// <summary>
|
||||
/// Should the command be displayed in the menu?
|
||||
/// </summary>
|
||||
public bool Visible
|
||||
{
|
||||
get => _visible;
|
||||
set => this.RaiseAndSetIfChanged(ref _visible, value);
|
||||
}
|
||||
private bool _visible = true;
|
||||
#endregion
|
||||
|
||||
#region Command
|
||||
/// <summary>
|
||||
/// The command to be executed.
|
||||
/// </summary>
|
||||
public ICommand Command
|
||||
{
|
||||
get => _command;
|
||||
set => this.RaiseAndSetIfChanged(ref _command, value);
|
||||
}
|
||||
private ICommand _command = null;
|
||||
#endregion
|
||||
|
||||
#region CommandParameter
|
||||
/// <summary>
|
||||
/// The parameter to be passed to the command on execution.
|
||||
/// </summary>
|
||||
public object CommandParameter
|
||||
{
|
||||
get => _commandParameter;
|
||||
set => this.RaiseAndSetIfChanged(ref _commandParameter, value);
|
||||
}
|
||||
private object _commandParameter = null;
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A viewmodel for a context menu in which the entries can be filtered by the user based on a searchquery.
|
||||
/// </summary>
|
||||
public class SearchableContextMenuViewModel : ReactiveObject
|
||||
{
|
||||
static SearchableContextMenuViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new SearchableContextMenuView(), typeof(IViewFor<SearchableContextMenuViewModel>));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of all the available commands in the menu.
|
||||
/// </summary>
|
||||
public ISourceList<LabeledCommand> Commands { get; } = new SourceList<LabeledCommand>();
|
||||
|
||||
/// <summary>
|
||||
/// List of commands that are actually visible in the menu.
|
||||
/// This list is based on Commands and SearchQuery.
|
||||
/// </summary>
|
||||
public IObservableList<LabeledCommand> VisibleCommands { get; }
|
||||
|
||||
#region SearchQuery
|
||||
/// <summary>
|
||||
/// The current search string that is used to filter Nodes into VisibleNodes.
|
||||
/// </summary>
|
||||
public string SearchQuery
|
||||
{
|
||||
get => _searchQuery;
|
||||
set => this.RaiseAndSetIfChanged(ref _searchQuery, value);
|
||||
}
|
||||
private string _searchQuery = "";
|
||||
#endregion
|
||||
|
||||
#region MaxItemsDisplayed
|
||||
/// <summary>
|
||||
/// Only the first MaxItemsDisplayed items from Commands that match the query are displayed.
|
||||
/// </summary>
|
||||
public int MaxItemsDisplayed
|
||||
{
|
||||
get => _maxItemsDisplayed;
|
||||
set => this.RaiseAndSetIfChanged(ref _maxItemsDisplayed, value);
|
||||
}
|
||||
private int _maxItemsDisplayed = int.MaxValue;
|
||||
#endregion
|
||||
|
||||
public SearchableContextMenuViewModel()
|
||||
{
|
||||
var onQueryChanged =
|
||||
this.WhenAnyValue(vm => vm.SearchQuery, vm => vm.MaxItemsDisplayed)
|
||||
.Throttle(TimeSpan.FromMilliseconds(70), RxApp.MainThreadScheduler)
|
||||
.Publish();
|
||||
onQueryChanged.Connect();
|
||||
|
||||
VisibleCommands = Commands.Connect()
|
||||
.AutoRefreshOnObservable(_ => onQueryChanged)
|
||||
.AutoRefresh(cmd => cmd.Label)
|
||||
.AutoRefresh(cmd => cmd.Visible)
|
||||
.Filter(cmd => cmd.Visible && (cmd.Label ?? "").ToUpper().Contains(SearchQuery?.ToUpper() ?? ""))
|
||||
.Top(MaxItemsDisplayed)
|
||||
.AsObservableList();
|
||||
}
|
||||
}
|
||||
}
|
||||
8
intromat/NodeNetworkToolkit/GlobalSuppressions.cs
Normal file
8
intromat/NodeNetworkToolkit/GlobalSuppressions.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
|
||||
356
intromat/NodeNetworkToolkit/GraphAlgorithms.cs
Normal file
356
intromat/NodeNetworkToolkit/GraphAlgorithms.cs
Normal file
@@ -0,0 +1,356 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is a collection of various graph algoritms.
|
||||
/// </summary>
|
||||
public class GraphAlgorithms
|
||||
{
|
||||
/*
|
||||
* Algorithm:
|
||||
* 1. Pick next ready node from the nodes-to-check list, set as current
|
||||
*
|
||||
* a. Mark current node as busy
|
||||
* b. For each input of the current node, find the connected node
|
||||
* c. Check connected node state
|
||||
* -> if ready
|
||||
* => set connected node as current and goto a
|
||||
* -> if busy
|
||||
* => recursion found!
|
||||
* => mark all busy nodes as broken!
|
||||
* => mark all nodes connected to outputs of broken nodes as broken
|
||||
* => goto 1
|
||||
* d. Mark current node as ready
|
||||
*
|
||||
* 2. Goto 1
|
||||
*/
|
||||
|
||||
private enum NodeState
|
||||
{
|
||||
Ready,
|
||||
Busy,
|
||||
Error
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for loops in a network.
|
||||
/// A loop is a connection sequence that starts and ends at the same node.
|
||||
/// </summary>
|
||||
/// <param name="network">the network to search for loops.</param>
|
||||
/// <returns>an enumeration of connections involved in loops</returns>
|
||||
public static IEnumerable<ConnectionViewModel> FindLoops(NetworkViewModel network)
|
||||
{
|
||||
Stack<NodeViewModel> nodesToCheck = new Stack<NodeViewModel>(network.Nodes.Items);
|
||||
Dictionary<NodeViewModel, NodeState> nodeStates = new Dictionary<NodeViewModel, NodeState>(nodesToCheck.Count);
|
||||
|
||||
while (nodesToCheck.Count > 0)
|
||||
{
|
||||
NodeViewModel currentNode = nodesToCheck.Peek();
|
||||
|
||||
NodeState state;
|
||||
if (!nodeStates.TryGetValue(currentNode, out state))
|
||||
{
|
||||
state = NodeState.Ready;
|
||||
}
|
||||
|
||||
if (state == NodeState.Error)
|
||||
{
|
||||
nodesToCheck.Pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
ConnectionViewModel recursiveConnection = FindLoops(nodeStates, currentNode);
|
||||
if (recursiveConnection != null)
|
||||
{
|
||||
yield return recursiveConnection;
|
||||
}
|
||||
|
||||
nodesToCheck.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
private static ConnectionViewModel FindLoops(Dictionary<NodeViewModel, NodeState> nodeStates, NodeViewModel node)
|
||||
{
|
||||
nodeStates[node] = NodeState.Busy;
|
||||
|
||||
//Get the nodes connected to the inputs of node and check their state
|
||||
//If they are Ready, check them recursively.
|
||||
//If they are Busy, we found recursion.
|
||||
//If they are Error, the node was already found to be part of a loop and so we ignore it.
|
||||
List<ConnectionViewModel> nodesToCheck = new List<ConnectionViewModel>();
|
||||
foreach (NodeInputViewModel input in node.Inputs.Items)
|
||||
{
|
||||
foreach (ConnectionViewModel con in input.Connections.Items)
|
||||
{
|
||||
NodeViewModel connectedNode = con.Output.Parent;
|
||||
if (!nodeStates.TryGetValue(connectedNode, out var connectedNodeState))
|
||||
{
|
||||
connectedNodeState = NodeState.Ready;
|
||||
}
|
||||
|
||||
if (connectedNodeState == NodeState.Ready)
|
||||
{
|
||||
nodesToCheck.Add(con);
|
||||
}
|
||||
else if (connectedNodeState == NodeState.Busy)
|
||||
{
|
||||
//Found recursion!
|
||||
List<NodeViewModel> keys = new List<NodeViewModel>(nodeStates.Keys);
|
||||
foreach (NodeViewModel cur in keys)
|
||||
{
|
||||
if (nodeStates[cur] == NodeState.Busy)
|
||||
{
|
||||
nodeStates[cur] = NodeState.Error;
|
||||
}
|
||||
}
|
||||
return con;
|
||||
}
|
||||
else if (connectedNodeState == NodeState.Error)
|
||||
{
|
||||
//connected node is already marked with error state, no further action required
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ConnectionViewModel con in nodesToCheck)
|
||||
{
|
||||
NodeViewModel currentNode = con.Output.Parent;
|
||||
ConnectionViewModel result = FindLoops(nodeStates, currentNode);
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
nodeStates[node] = NodeState.Ready;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the nodes connected to the starting node, then the nodes connected to those nodes, ... and so on.
|
||||
/// If the subgraph that contains the starting nodes has a loop, then this function will keep producing the values in the loop.
|
||||
/// A call to FindLoops is recommended before using this function
|
||||
/// </summary>
|
||||
/// <param name="startingNode">The node from which to branch out</param>
|
||||
/// <param name="includeInputs">Include nodes connected through node inputs?</param>
|
||||
/// <param name="includeOutputs">Include nodes connected through node outputs?</param>
|
||||
/// <param name="includeSelf">Include the starting node? (will be first)</param>
|
||||
/// <returns>An enumeration of the nodes connected to the starting node.</returns>
|
||||
public static IEnumerable<NodeViewModel> GetConnectedNodesTunneling(NodeViewModel startingNode, bool includeInputs = true, bool includeOutputs = false, bool includeSelf = false)
|
||||
{
|
||||
if (includeSelf)
|
||||
{
|
||||
yield return startingNode;
|
||||
}
|
||||
|
||||
if (includeInputs)
|
||||
{
|
||||
IEnumerable<NodeViewModel> inputNodes = startingNode.Inputs.Items.SelectMany(i => i.Connections.Items).Select(c => c.Output.Parent);
|
||||
foreach (NodeViewModel nodeVM in inputNodes)
|
||||
{
|
||||
foreach (NodeViewModel subNodeVM in GetConnectedNodesTunneling(nodeVM, includeInputs, includeOutputs, true))
|
||||
{
|
||||
if (subNodeVM != startingNode)
|
||||
{
|
||||
yield return subNodeVM;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (includeOutputs)
|
||||
{
|
||||
IEnumerable<NodeViewModel> outputNodes = startingNode.Outputs.Items.SelectMany(i => i.Connections.Items).Select(c => c.Input.Parent);
|
||||
foreach (NodeViewModel nodeVM in outputNodes)
|
||||
{
|
||||
foreach (NodeViewModel subNodeVM in GetConnectedNodesTunneling(nodeVM, includeInputs, includeOutputs, true))
|
||||
{
|
||||
if (subNodeVM != startingNode)
|
||||
{
|
||||
yield return subNodeVM;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Similar to GetConnectedNodesTunneling, but returns the outermost nodes first.
|
||||
/// If the subgraph that contains the starting nodes has a loop, then this function will never return.
|
||||
/// A call to FindLoops is recommended before using this function
|
||||
/// </summary>
|
||||
public static IEnumerable<NodeViewModel> GetConnectedNodesBubbling(NodeViewModel startingNode, bool includeInputs = true, bool includeOutputs = false, bool includeSelf = false)
|
||||
{
|
||||
return GetConnectedNodesTunneling(startingNode, includeInputs, includeOutputs, includeSelf).Reverse();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the starting nodes in the network.
|
||||
/// Starting nodes are nodes that do not have inputs connected to an output.
|
||||
/// </summary>
|
||||
/// <param name="network">The network to find starting nodes in</param>
|
||||
/// <returns>An enumerable of starting nodes</returns>
|
||||
public static IEnumerable<NodeViewModel> FindStartingNodes(NetworkViewModel network)
|
||||
{
|
||||
return FindStartingNodes(network.Nodes.Items);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the starting nodes in the node group.
|
||||
/// Starting nodes are nodes that do not have inputs connected to an output of a node in the group.
|
||||
/// </summary>
|
||||
public static IEnumerable<NodeViewModel> FindStartingNodes(IEnumerable<NodeViewModel> nodeGroup)
|
||||
{
|
||||
Queue<NodeViewModel> todo = new Queue<NodeViewModel>(nodeGroup);
|
||||
HashSet<NodeViewModel> nodes = new HashSet<NodeViewModel>(todo);
|
||||
|
||||
while (todo.Count > 0)
|
||||
{
|
||||
NodeViewModel cur = todo.Dequeue();
|
||||
|
||||
bool hasInputConnection = false;
|
||||
foreach (NodeInputViewModel input in cur.Inputs.Items)
|
||||
{
|
||||
if (input.Connections.Items.Any(c => nodes.Contains(c.Output.Parent)))
|
||||
{
|
||||
hasInputConnection = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasInputConnection)
|
||||
{
|
||||
yield return cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes the provided set of nodes and returns the nodes are connected to the source node, directly or indirectly.
|
||||
/// This method uses breadth-first search and keeps track of visited nodes, so it can handle networks with loops.
|
||||
/// </summary>
|
||||
/// <param name="sourceNode">The node from which the search for connected nodes starts</param>
|
||||
/// <param name="nodes">
|
||||
/// The nodes to look for when searching.
|
||||
/// If this set contains the sourcenode, the first item returned will be the source node.
|
||||
/// </param>
|
||||
/// <returns>An enumeration of connected nodes</returns>
|
||||
public static IEnumerable<NodeViewModel> FindConnectedNodes(NodeViewModel sourceNode, IEnumerable<NodeViewModel> nodes)
|
||||
{
|
||||
HashSet<NodeViewModel> nodesSet = new HashSet<NodeViewModel>(nodes);
|
||||
|
||||
HashSet<NodeViewModel> visitedNodes = new HashSet<NodeViewModel>();
|
||||
|
||||
Queue<NodeViewModel> nodeQueue = new Queue<NodeViewModel>();
|
||||
nodeQueue.Enqueue(sourceNode);
|
||||
|
||||
while (nodeQueue.Count > 0)
|
||||
{
|
||||
NodeViewModel node = nodeQueue.Dequeue();
|
||||
|
||||
if (nodesSet.Remove(node))
|
||||
{
|
||||
yield return node;
|
||||
if (nodesSet.Count == 0)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (NodeInputViewModel input in node.Inputs.Items)
|
||||
{
|
||||
foreach (NodeViewModel connectedNode in input.Connections.Items.Select(c => c.Output.Parent))
|
||||
{
|
||||
if (visitedNodes.Add(connectedNode))
|
||||
{
|
||||
nodeQueue.Enqueue(connectedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (NodeOutputViewModel output in node.Outputs.Items)
|
||||
{
|
||||
foreach (NodeViewModel connectedNode in output.Connections.Items.Select(c => c.Input.Parent))
|
||||
{
|
||||
if (visitedNodes.Add(connectedNode))
|
||||
{
|
||||
nodeQueue.Enqueue(connectedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes the provided set of nodes and groups these nodes in sets that are connected, directly or indirectly.
|
||||
/// Because this method uses FindConnectedNodes, it is capable of handling networks with loops.
|
||||
/// </summary>
|
||||
/// <param name="nodes">the nodes to group into sets</param>
|
||||
public static IEnumerable<IEnumerable<NodeViewModel>> FindSubGraphs(IEnumerable<NodeViewModel> nodes)
|
||||
{
|
||||
HashSet<NodeViewModel> nodesSet = new HashSet<NodeViewModel>(nodes);
|
||||
while (nodesSet.Count > 0)
|
||||
{
|
||||
NodeViewModel curNode = nodesSet.First();
|
||||
|
||||
List<NodeViewModel> subGraphMembers = new List<NodeViewModel>(FindConnectedNodes(curNode, nodesSet));
|
||||
foreach (NodeViewModel subGraphMember in subGraphMembers)
|
||||
{
|
||||
nodesSet.Remove(subGraphMember);
|
||||
}
|
||||
yield return subGraphMembers;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the given set of nodes form continuous subgraphs.
|
||||
/// The given set of nodes is split into subgraphs based on the connections between the nodes.
|
||||
/// If for each subgraph it is true that all nodes of the subgraph are in the provided set, then true is returned.
|
||||
/// Otherwise false is returned.
|
||||
/// Because this method uses FindSubGraphs, it is capable of handling networks with loops.
|
||||
/// </summary>
|
||||
public static bool IsContinuousSubGraphSet(HashSet<NodeViewModel> nodesInSubGraphSet)
|
||||
{
|
||||
return FindSubGraphs(FindStartingNodes(nodesInSubGraphSet))
|
||||
.All(subGraph => IsContinuousSubGroup(nodesInSubGraphSet, subGraph));
|
||||
}
|
||||
public static bool IsContinuousSubGraphSet(IEnumerable<NodeViewModel> nodesInSubGraphSet)
|
||||
=> IsContinuousSubGraphSet(new HashSet<NodeViewModel>(nodesInSubGraphSet));
|
||||
|
||||
private static bool IsContinuousSubGroup(HashSet<NodeViewModel> groupNodesSet, IEnumerable<NodeViewModel> subGraphStartingNodes)
|
||||
{
|
||||
Queue<NodeViewModel> queue = new Queue<NodeViewModel>(subGraphStartingNodes);
|
||||
HashSet<NodeViewModel> visitedNodes = new HashSet<NodeViewModel>(queue);
|
||||
|
||||
//Transitions from inside to outside to inside the group are not allowed in a continuous group.
|
||||
//Since we start from the starting nodes of the current subgroup, which are inside,
|
||||
//we only need to check for a transitions from outside to inside.
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
NodeViewModel cur = queue.Dequeue();
|
||||
|
||||
foreach (NodeOutputViewModel output in cur.Outputs.Items)
|
||||
{
|
||||
foreach (ConnectionViewModel con in output.Connections.Items)
|
||||
{
|
||||
NodeViewModel connectedNode = con.Input.Parent;
|
||||
|
||||
if (groupNodesSet.Contains(connectedNode) && !groupNodesSet.Contains(cur))
|
||||
{
|
||||
//Found transision from outside to inside
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!visitedNodes.Add(connectedNode))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
queue.Enqueue(connectedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<UserControl x:Class="NodeNetwork.Toolkit.Group.AddEndpointDropPanel.AddEndpointDropPanelView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800" x:Name="Self">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid Width="Auto" Height="40"
|
||||
Visibility="{Binding IsDropZoneVisible, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<Grid.Style>
|
||||
<Style TargetType="Grid">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" To="#44FFFFFF" Duration="0:0:0.1"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" To="Transparent" Duration="0:0:0.1"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<Rectangle Stroke="#fff" StrokeThickness="2" StrokeDashArray="4 4" SnapsToDevicePixels="True"/>
|
||||
<TextBlock Text="{Binding DropHintText, ElementName=Self}" VerticalAlignment="Center" TextAlignment="Center" FontSize="14" Margin="15,5,15,5"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Group.AddEndpointDropPanel
|
||||
{
|
||||
public partial class AddEndpointDropPanelView : IViewFor<AddEndpointDropPanelViewModel>
|
||||
{
|
||||
#region ViewModel
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(AddEndpointDropPanelViewModel), typeof(AddEndpointDropPanelView), new PropertyMetadata(null));
|
||||
|
||||
public AddEndpointDropPanelViewModel ViewModel
|
||||
{
|
||||
get => (AddEndpointDropPanelViewModel)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (AddEndpointDropPanelViewModel)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DropHintText
|
||||
public static readonly DependencyProperty DropHintTextProperty = DependencyProperty.Register(nameof(DropHintText),
|
||||
typeof(string), typeof(AddEndpointDropPanelView), new PropertyMetadata(null));
|
||||
|
||||
public string DropHintText
|
||||
{
|
||||
get => (string)GetValue(DropHintTextProperty);
|
||||
set => SetValue(DropHintTextProperty, value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public AddEndpointDropPanelView()
|
||||
{
|
||||
InitializeComponent();
|
||||
DropHintText = "Drop here to create new entry";
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Events().MouseLeftButtonUp
|
||||
.Select(_ => Unit.Default)
|
||||
.InvokeCommand(this, v => v.ViewModel.AddEndpointFromPendingConnection)
|
||||
.DisposeWith(d);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Text;
|
||||
using DynamicData;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Group.AddEndpointDropPanel
|
||||
{
|
||||
public class AddEndpointDropPanelViewModel : ReactiveObject
|
||||
{
|
||||
static AddEndpointDropPanelViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new AddEndpointDropPanelView(), typeof(IViewFor<AddEndpointDropPanelViewModel>));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Take the pending connection from the super- or subnetwork, whichever is non-null,
|
||||
/// and add endpoints to NodeGroupIOBinding that match this connection.
|
||||
/// </summary>
|
||||
public ReactiveCommand<Unit, Unit> AddEndpointFromPendingConnection { get; }
|
||||
|
||||
#region IsDropZoneVisible
|
||||
public bool IsDropZoneVisible => _isDropZoneVisible.Value;
|
||||
private readonly ObservableAsPropertyHelper<bool> _isDropZoneVisible;
|
||||
#endregion
|
||||
|
||||
#region NodeGroupIOBinding
|
||||
public NodeGroupIOBinding NodeGroupIOBinding
|
||||
{
|
||||
get => _nodeGroupIoBinding;
|
||||
set => this.RaiseAndSetIfChanged(ref _nodeGroupIoBinding, value);
|
||||
}
|
||||
private NodeGroupIOBinding _nodeGroupIoBinding;
|
||||
#endregion
|
||||
|
||||
private readonly bool isOnSubnetEntrance;
|
||||
private readonly bool isOnSubnetExit;
|
||||
|
||||
public AddEndpointDropPanelViewModel(bool isOnSubnetEntrance = false, bool isOnSubnetExit = false)
|
||||
{
|
||||
this.isOnSubnetEntrance = isOnSubnetEntrance;
|
||||
this.isOnSubnetExit = isOnSubnetExit;
|
||||
|
||||
bool isOnSubnet = isOnSubnetEntrance || isOnSubnetExit;
|
||||
|
||||
AddEndpointFromPendingConnection = ReactiveCommand.Create(() =>
|
||||
{
|
||||
var network = isOnSubnet ? NodeGroupIOBinding.SubNetwork : NodeGroupIOBinding.SuperNetwork;
|
||||
var pendingConn = network.PendingConnection;
|
||||
|
||||
NodeInputViewModel input = null;
|
||||
NodeOutputViewModel output = null;
|
||||
|
||||
if (!CanCreateEndpointFromPendingConnection(pendingConn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pendingConn.Input != null)
|
||||
{
|
||||
input = pendingConn.Input;
|
||||
if (isOnSubnet)
|
||||
{
|
||||
output = NodeGroupIOBinding.AddNewSubnetInlet(pendingConn.Input);
|
||||
}
|
||||
else
|
||||
{
|
||||
output = NodeGroupIOBinding.AddNewGroupNodeOutput(pendingConn.Input);
|
||||
}
|
||||
}
|
||||
else if (pendingConn.Output != null)
|
||||
{
|
||||
if (isOnSubnet)
|
||||
{
|
||||
input = NodeGroupIOBinding.AddNewSubnetOutlet(pendingConn.Output);
|
||||
}
|
||||
else
|
||||
{
|
||||
input = NodeGroupIOBinding.AddNewGroupNodeInput(pendingConn.Output);
|
||||
}
|
||||
output = pendingConn.Output;
|
||||
}
|
||||
|
||||
network.Connections.Add(network.ConnectionFactory(input, output));
|
||||
});
|
||||
|
||||
if (isOnSubnet)
|
||||
{
|
||||
this.WhenAnyValue(vm => vm.NodeGroupIOBinding.SubNetwork.PendingConnection)
|
||||
.Select(CanCreateEndpointFromPendingConnection)
|
||||
.ToProperty(this, vm => vm.IsDropZoneVisible, out _isDropZoneVisible);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.WhenAnyValue(vm => vm.NodeGroupIOBinding.SuperNetwork.PendingConnection)
|
||||
.Select(CanCreateEndpointFromPendingConnection)
|
||||
.ToProperty(this, vm => vm.IsDropZoneVisible, out _isDropZoneVisible);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool CanCreateEndpointFromPendingConnection(PendingConnectionViewModel conn)
|
||||
{
|
||||
if (conn == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var sourceNode = conn.Input != null ? conn.Input.Parent : conn.Output.Parent;
|
||||
|
||||
return sourceNode != NodeGroupIOBinding.GroupNode
|
||||
&& !(isOnSubnetEntrance && sourceNode == NodeGroupIOBinding.EntranceNode)
|
||||
&& !(isOnSubnetExit && sourceNode == NodeGroupIOBinding.ExitNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
91
intromat/NodeNetworkToolkit/Group/NodeGroupIOBinding.cs
Normal file
91
intromat/NodeNetworkToolkit/Group/NodeGroupIOBinding.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Group
|
||||
{
|
||||
/// <summary>
|
||||
/// Facilitates connections between nodes outside and inside a group.
|
||||
/// This is performed by having inputs on the group node (in the supernet) that map to outputs on (mostly) the EntranceNode in the subnet.
|
||||
/// Likewise, outputs of the group node map to inputs on (mostly) the ExitNode in the subnet.
|
||||
/// </summary>
|
||||
public abstract class NodeGroupIOBinding
|
||||
{
|
||||
/// <summary>
|
||||
/// Node in the parent network that represents the group.
|
||||
/// </summary>
|
||||
public NodeViewModel GroupNode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Inlet node in the subnet.
|
||||
/// Although this generally contains only outputs, this may contain inputs if their orientation is flipped.
|
||||
/// </summary>
|
||||
public NodeViewModel EntranceNode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Outlet node in the subnet.
|
||||
/// Although this generally contains only outputs, this may contain inputs if their orientation is flipped.
|
||||
/// </summary>
|
||||
public NodeViewModel ExitNode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Parent network that contains the GroupNode.
|
||||
/// </summary>
|
||||
public NetworkViewModel SuperNetwork => GroupNode.Parent;
|
||||
|
||||
/// <summary>
|
||||
/// Child network, contained in SuperNetwork, that contains the group member nodes (like the EntranceNode and ExitNode).
|
||||
/// </summary>
|
||||
public NetworkViewModel SubNetwork => ExitNode.Parent;
|
||||
|
||||
public NodeGroupIOBinding(NodeViewModel groupNode, NodeViewModel entranceNode, NodeViewModel exitNode)
|
||||
{
|
||||
GroupNode = groupNode;
|
||||
EntranceNode = entranceNode;
|
||||
ExitNode = exitNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given the output in the subnet, return the corresponding input on the groupnode in the supernet.
|
||||
/// </summary>
|
||||
public abstract NodeInputViewModel GetGroupNodeInput(NodeOutputViewModel subnetInlet);
|
||||
|
||||
/// <summary>
|
||||
/// Given the input on the group node in the supernet, return the corresponding output in the subnet.
|
||||
/// </summary>
|
||||
public abstract NodeOutputViewModel GetSubnetInlet(NodeInputViewModel entranceInput);
|
||||
|
||||
/// <summary>
|
||||
/// Given the output on the group node in the supernet, return the corresponding input in the subnet.
|
||||
/// </summary>
|
||||
public abstract NodeInputViewModel GetSubnetOutlet(NodeOutputViewModel groupNodeOutput);
|
||||
|
||||
/// <summary>
|
||||
/// Given the input in the subnet, return the corresponding output on the groupnode in the supernet.
|
||||
/// </summary>
|
||||
public abstract NodeOutputViewModel GetGroupNodeOutput(NodeInputViewModel subnetOutlet);
|
||||
|
||||
/// <summary>
|
||||
/// Create and add a new input to the group node, along with a corresponding output in the subnet (e.g. on the entrance node).
|
||||
/// </summary>
|
||||
/// <param name="candidateOutput">Output viewmodel that should match the new input on the group node.</param>
|
||||
/// <returns></returns>
|
||||
public abstract NodeInputViewModel AddNewGroupNodeInput(NodeOutputViewModel candidateOutput);
|
||||
|
||||
/// <summary>
|
||||
/// Create and add a new input to the group node, along with a corresponding output in the subnet (e.g. on the entrance node).
|
||||
/// </summary>
|
||||
/// <param name="candidateInput">Input viewmodel that should match the new output that is added to the subnet.</param>
|
||||
public abstract NodeOutputViewModel AddNewSubnetInlet(NodeInputViewModel candidateInput);
|
||||
|
||||
/// <summary>
|
||||
/// Create and add a new output to the group node, along with a corresponding input in the subnet (e.g. on the exit node).
|
||||
/// </summary>
|
||||
/// <param name="candidateInput">Input viewmodel that should match the new output on the group node.</param>
|
||||
public abstract NodeOutputViewModel AddNewGroupNodeOutput(NodeInputViewModel candidateInput);
|
||||
|
||||
/// <summary>
|
||||
/// Create and add a new output to the group node, along with a corresponding input in the subnet (e.g. on the exit node).
|
||||
/// </summary>
|
||||
/// <param name="candidateOutput">Output viewmodel that should match the new input that is added to the subnet.</param>
|
||||
public abstract NodeInputViewModel AddNewSubnetOutlet(NodeOutputViewModel candidateOutput);
|
||||
}
|
||||
}
|
||||
269
intromat/NodeNetworkToolkit/Group/NodeGrouper.cs
Normal file
269
intromat/NodeNetworkToolkit/Group/NodeGrouper.cs
Normal file
@@ -0,0 +1,269 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using DynamicData;
|
||||
using DynamicData.Alias;
|
||||
using NodeNetwork.Utilities;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Group
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to provide nesting of networks by grouping nodes.
|
||||
/// </summary>
|
||||
public class NodeGrouper
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new node that represents a group of nodes.
|
||||
/// The parameter is the subnetwork (constructed with SubNetworkFactory) that contains the group member nodes.
|
||||
/// </summary>
|
||||
public Func<NetworkViewModel, NodeViewModel> GroupNodeFactory { get; set; } = subnet => new NodeViewModel();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a viewmodel for the subnetwork that will contain the group member nodes.
|
||||
/// </summary>
|
||||
public Func<NetworkViewModel, NetworkViewModel> SubNetworkFactory { get; set; } = parentNet => new NetworkViewModel();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the node in the subnet that provides access to (mostly) inputs to the group
|
||||
/// </summary>
|
||||
public Func<NodeViewModel> EntranceNodeFactory { get; set; } = () => new NodeViewModel();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the node in the subnet that provides access to (mostly) outputs of the group
|
||||
/// </summary>
|
||||
public Func<NodeViewModel> ExitNodeFactory { get; set; } = () => new NodeViewModel();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a NodeGroupIOBinding from a group, entrance and exit node.
|
||||
/// </summary>
|
||||
public Func<NodeViewModel, NodeViewModel, NodeViewModel, NodeGroupIOBinding> IOBindingFactory { get; set; }
|
||||
|
||||
private bool CheckPropertiesValid() =>
|
||||
GroupNodeFactory != null && SubNetworkFactory != null && EntranceNodeFactory != null && ExitNodeFactory != null && IOBindingFactory != null;
|
||||
|
||||
/// <summary>
|
||||
/// Move the specified set of nodes to a new subnetwork, create a new group node that contains this subnet,
|
||||
/// restore inter- and intra-network connections.
|
||||
/// </summary>
|
||||
/// <param name="network">The parent network</param>
|
||||
/// <param name="nodesToGroup">The nodes to group</param>
|
||||
/// <returns>Returns the NodeGroupIOBinding that was constructed for this group using the IOBindingFactory.</returns>
|
||||
public NodeGroupIOBinding MergeIntoGroup(NetworkViewModel network, IEnumerable<NodeViewModel> nodesToGroup)
|
||||
{
|
||||
if (!CheckPropertiesValid())
|
||||
{
|
||||
throw new InvalidOperationException("All properties must be set before usage");
|
||||
}
|
||||
else if (network == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(network));
|
||||
}
|
||||
else if (nodesToGroup == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(nodesToGroup));
|
||||
}
|
||||
|
||||
var groupNodesSet = nodesToGroup is HashSet<NodeViewModel> set
|
||||
? set
|
||||
: new HashSet<NodeViewModel>(nodesToGroup);
|
||||
|
||||
// Check if nodesToGroup can be combined into a single group
|
||||
if (groupNodesSet.Count == 0)//[FT] allowed for now || !GraphAlgorithms.IsContinuousSubGraphSet(groupNodesSet))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create new empty group
|
||||
var subnet = SubNetworkFactory(network);
|
||||
|
||||
var groupNode = GroupNodeFactory(subnet);
|
||||
network.Nodes.Add(groupNode);
|
||||
|
||||
var groupEntranceNode = EntranceNodeFactory();
|
||||
var groupExitNode = ExitNodeFactory();
|
||||
|
||||
subnet.Nodes.AddRange(new []{groupEntranceNode, groupExitNode});
|
||||
|
||||
// Map from input on a group member node to group node input
|
||||
var groupNodeInputs = new Dictionary<NodeInputViewModel, NodeInputViewModel>();
|
||||
// Map from output on a group member node to group node output
|
||||
var groupNodeOutputs = new Dictionary<NodeOutputViewModel, NodeOutputViewModel>();
|
||||
|
||||
// Move the new nodes to appropriate positions
|
||||
groupNode.Position = new Point(
|
||||
groupNodesSet.Average(n => n.Position.X),
|
||||
groupNodesSet.Average(n => n.Position.Y)
|
||||
);
|
||||
|
||||
double yCoord = groupNodesSet.Average(n => n.Position.Y);
|
||||
groupEntranceNode.Position = new Point(
|
||||
groupNodesSet.Min(n => n.Position.X) - 100,
|
||||
yCoord
|
||||
);
|
||||
groupExitNode.Position = new Point(
|
||||
groupNodesSet.Max(n => n.Position.X) + 100,
|
||||
yCoord
|
||||
);
|
||||
|
||||
// Setup binding between entrance/exit inputs and outputs
|
||||
var ioBinding = IOBindingFactory(groupNode, groupEntranceNode, groupExitNode);
|
||||
|
||||
// Calculate set of connections to replace
|
||||
var subnetConnections = new List<ConnectionViewModel>();
|
||||
var borderInputConnections = new List<ConnectionViewModel>();
|
||||
var borderOutputConnections = new List<ConnectionViewModel>();
|
||||
foreach (var con in network.Connections.Items)
|
||||
{
|
||||
bool inputIsInSubnet = groupNodesSet.Contains(con.Input.Parent);
|
||||
bool outputIsInSubnet = groupNodesSet.Contains(con.Output.Parent);
|
||||
|
||||
if (inputIsInSubnet && outputIsInSubnet)
|
||||
{
|
||||
subnetConnections.Add(con);
|
||||
}
|
||||
else if (inputIsInSubnet)
|
||||
{
|
||||
borderInputConnections.Add(con);
|
||||
}
|
||||
else if (outputIsInSubnet)
|
||||
{
|
||||
borderOutputConnections.Add(con);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct inputs/outputs into/out of the group
|
||||
foreach (var borderInCon in borderInputConnections)
|
||||
{
|
||||
if (!groupNodeInputs.ContainsKey(borderInCon.Input))
|
||||
{
|
||||
groupNodeInputs[borderInCon.Input] = ioBinding.AddNewGroupNodeInput(borderInCon.Output);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var borderOutCon in borderOutputConnections)
|
||||
{
|
||||
if (!groupNodeOutputs.ContainsKey(borderOutCon.Output))
|
||||
{
|
||||
groupNodeOutputs[borderOutCon.Output] = ioBinding.AddNewGroupNodeOutput(borderOutCon.Input);
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer nodes and inner connections to subnet
|
||||
network.Connections.Edit(l =>
|
||||
{
|
||||
l.RemoveMany(subnetConnections);
|
||||
l.RemoveMany(borderInputConnections);
|
||||
l.RemoveMany(borderOutputConnections);
|
||||
});
|
||||
network.Nodes.RemoveMany(groupNodesSet);
|
||||
subnet.Nodes.AddRange(groupNodesSet);
|
||||
subnet.Connections.AddRange(subnetConnections.Select(con => subnet.ConnectionFactory(con.Input, con.Output)));
|
||||
|
||||
// Restore connections in/out of group
|
||||
network.Connections.AddRange(Enumerable.Concat(
|
||||
borderInputConnections.Select(con => network.ConnectionFactory(groupNodeInputs[con.Input], con.Output)),
|
||||
borderOutputConnections.Select(con => network.ConnectionFactory(con.Input, groupNodeOutputs[con.Output]))
|
||||
));
|
||||
subnet.Connections.AddRange(Enumerable.Concat(
|
||||
borderInputConnections.Select(con => subnet.ConnectionFactory(con.Input, ioBinding.GetSubnetInlet(groupNodeInputs[con.Input]))),
|
||||
borderOutputConnections.Select(con => subnet.ConnectionFactory(ioBinding.GetSubnetOutlet(groupNodeOutputs[con.Output]), con.Output))
|
||||
));
|
||||
|
||||
return ioBinding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the grouping performed by MergeIntoGroup.
|
||||
/// Group members get moved back into the parent network and the group node is removed.
|
||||
/// </summary>
|
||||
/// <param name="nodeGroupInfo">The NodeGroupIOBinding of the group to dissolve.</param>
|
||||
public void Ungroup(NodeGroupIOBinding nodeGroupInfo)
|
||||
{
|
||||
if (!CheckPropertiesValid())
|
||||
{
|
||||
throw new InvalidOperationException("All properties must be set before usage");
|
||||
}
|
||||
else if (nodeGroupInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(nodeGroupInfo));
|
||||
}
|
||||
|
||||
var supernet = nodeGroupInfo.SuperNetwork;
|
||||
var subnet = nodeGroupInfo.SubNetwork;
|
||||
|
||||
// Calculate set of subnet connections to replace
|
||||
var borderInputConnections = new List<Tuple<NodeOutputViewModel, NodeInputViewModel[]>>();
|
||||
var borderOutputConnections = new List<Tuple<NodeInputViewModel, NodeOutputViewModel[]>>();
|
||||
var subnetConnections = new List<ConnectionViewModel>();
|
||||
foreach (var conn in subnet.Connections.Items)
|
||||
{
|
||||
if (conn.Input.Parent == nodeGroupInfo.EntranceNode || conn.Input.Parent == nodeGroupInfo.ExitNode)
|
||||
{
|
||||
var inputs = nodeGroupInfo.GetGroupNodeOutput(conn.Input).Connections.Items.Select(c => c.Input).ToArray();
|
||||
if (inputs.Length > 0)
|
||||
{
|
||||
borderInputConnections.Add(Tuple.Create(conn.Output, inputs));
|
||||
}
|
||||
}
|
||||
else if (conn.Output.Parent == nodeGroupInfo.EntranceNode || conn.Output.Parent == nodeGroupInfo.ExitNode)
|
||||
{
|
||||
var outputs = nodeGroupInfo.GetGroupNodeInput(conn.Output).Connections.Items.Select(c => c.Output).ToArray();
|
||||
if (outputs.Length > 0)
|
||||
{
|
||||
borderOutputConnections.Add(Tuple.Create(conn.Input, outputs));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subnetConnections.Add(conn);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate set of nodes to move
|
||||
var groupMemberNodes = subnet.Nodes.Items.Where(node => node != nodeGroupInfo.EntranceNode && node != nodeGroupInfo.ExitNode).ToArray();
|
||||
|
||||
// Calculate center of nodes
|
||||
var minX = groupMemberNodes.Min(n => n.Position.X);
|
||||
var minY = groupMemberNodes.Min(n => n.Position.Y);
|
||||
var maxX = groupMemberNodes.Max(n => n.Position.X);
|
||||
var maxY = groupMemberNodes.Max(n => n.Position.Y);
|
||||
var center = new Vector(minX + (maxX - minX)/2, minY + (maxY - minY)/2);
|
||||
|
||||
// Remove connections and nodes from subnet
|
||||
subnet.Connections.Clear();
|
||||
subnet.Nodes.Clear();
|
||||
|
||||
// Remove groupnode and connections from supernet
|
||||
var groupNodePos = new Vector(nodeGroupInfo.GroupNode.Position.X, nodeGroupInfo.GroupNode.Position.Y);
|
||||
supernet.Nodes.Remove(nodeGroupInfo.GroupNode);
|
||||
|
||||
// Add nodes to supernet and move them to correct position
|
||||
supernet.Nodes.AddRange(groupMemberNodes);
|
||||
foreach (var node in groupMemberNodes)
|
||||
{
|
||||
node.Position = node.Position - center + groupNodePos;
|
||||
}
|
||||
|
||||
// Add connections to supernet
|
||||
supernet.Connections.AddRange(subnetConnections);
|
||||
foreach (var connTuple in borderInputConnections)
|
||||
{
|
||||
var output = connTuple.Item1;
|
||||
var inputs = connTuple.Item2;
|
||||
var connections = inputs.Select(input => supernet.ConnectionFactory(input, output));
|
||||
supernet.Connections.AddRange(connections);
|
||||
}
|
||||
foreach (var connTuple in borderOutputConnections)
|
||||
{
|
||||
var outputs = connTuple.Item2;
|
||||
var input = connTuple.Item1;
|
||||
var connections = outputs.Select(output => supernet.ConnectionFactory(input, output));
|
||||
supernet.Connections.AddRange(connections);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
219
intromat/NodeNetworkToolkit/Group/ValueNodeGroupIOBinding.cs
Normal file
219
intromat/NodeNetworkToolkit/Group/ValueNodeGroupIOBinding.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using DynamicData;
|
||||
using NodeNetwork.Toolkit.ValueNode;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Group
|
||||
{
|
||||
/// <summary>
|
||||
/// Basic reference implementation of NodeGroupIOBinding for ValueInputViewModels and ValueOutputViewModels.
|
||||
/// </summary>
|
||||
public class ValueNodeGroupIOBinding : NodeGroupIOBinding
|
||||
{
|
||||
private readonly IDictionary<NodeOutputViewModel, NodeInputViewModel> _outputInputMapping = new Dictionary<NodeOutputViewModel, NodeInputViewModel>();
|
||||
|
||||
public ValueNodeGroupIOBinding(NodeViewModel groupNode, NodeViewModel entranceNode, NodeViewModel exitNode)
|
||||
: base(groupNode, entranceNode, exitNode)
|
||||
{
|
||||
// For each input on the group node, create an output in the subnet
|
||||
groupNode.Inputs.Connect()
|
||||
.Filter(input => input.PortPosition == PortPosition.Left)
|
||||
.Transform(i =>
|
||||
{
|
||||
// Dynamic is applied here so that late binding is used to find the most specific
|
||||
// CreateCompatibleOutput variant for this specific input.
|
||||
NodeOutputViewModel result = CreateCompatibleOutput((dynamic)i);
|
||||
BindOutputToInput((dynamic)result, (dynamic)i);
|
||||
return result;
|
||||
}).PopulateInto(entranceNode.Outputs);
|
||||
groupNode.Inputs.Connect()
|
||||
.Filter(input => input.PortPosition == PortPosition.Right)
|
||||
.Transform(i =>
|
||||
{
|
||||
NodeOutputViewModel result = CreateCompatibleOutput((dynamic) i);
|
||||
BindOutputToInput((dynamic) result, (dynamic) i);
|
||||
return result;
|
||||
}).PopulateInto(exitNode.Outputs);
|
||||
groupNode.Inputs.Connect().OnItemRemoved(input =>
|
||||
_outputInputMapping.Remove(
|
||||
_outputInputMapping.First(kvp => kvp.Value == input)
|
||||
)
|
||||
);
|
||||
|
||||
// For each output on the group node, create an input in the subnet
|
||||
groupNode.Outputs.Connect()
|
||||
.Filter(input => input.PortPosition == PortPosition.Right)
|
||||
.Transform(o =>
|
||||
{
|
||||
NodeInputViewModel result = CreateCompatibleInput((dynamic)o);
|
||||
BindOutputToInput((dynamic)o, (dynamic)result);
|
||||
return result;
|
||||
}).PopulateInto(exitNode.Inputs);
|
||||
groupNode.Outputs.Connect()
|
||||
.Filter(input => input.PortPosition == PortPosition.Left)
|
||||
.Transform(o =>
|
||||
{
|
||||
NodeInputViewModel result = CreateCompatibleInput((dynamic)o);
|
||||
BindOutputToInput((dynamic)o, (dynamic)result);
|
||||
return result;
|
||||
}).PopulateInto(entranceNode.Inputs);
|
||||
groupNode.Outputs.Connect().OnItemRemoved(output => _outputInputMapping.Remove(output));
|
||||
}
|
||||
|
||||
protected virtual void BindEndpointProperties(NodeOutputViewModel output, NodeInputViewModel input)
|
||||
{
|
||||
input.WhenAnyValue(vm => vm.Name).BindTo(output, vm => vm.Name);
|
||||
output.WhenAnyValue(vm => vm.Name).BindTo(input, vm => vm.Name);
|
||||
input.WhenAnyValue(vm => vm.SortIndex).BindTo(output, vm => vm.SortIndex);
|
||||
output.WhenAnyValue(vm => vm.SortIndex).BindTo(input, vm => vm.SortIndex);
|
||||
input.WhenAnyValue(vm => vm.Icon).BindTo(output, vm => vm.Icon);
|
||||
output.WhenAnyValue(vm => vm.Icon).BindTo(input, vm => vm.Icon);
|
||||
}
|
||||
|
||||
protected virtual void BindOutputToInput<T>(ValueNodeOutputViewModel<T> output, ValueNodeInputViewModel<T> input)
|
||||
{
|
||||
BindEndpointProperties(output, input);
|
||||
output.Value = input.ValueChanged;
|
||||
_outputInputMapping.Add(output, input);
|
||||
}
|
||||
|
||||
protected virtual void BindOutputToInput<T>(ValueNodeOutputViewModel<IObservableList<T>> output, ValueListNodeInputViewModel<T> input)
|
||||
{
|
||||
BindEndpointProperties(output, input);
|
||||
output.Value = Observable.Return(input.Values);
|
||||
_outputInputMapping.Add(output, input);
|
||||
}
|
||||
|
||||
#region Endpoint Create
|
||||
public virtual ValueNodeOutputViewModel<T> CreateCompatibleOutput<T>(ValueNodeInputViewModel<T> input)
|
||||
{
|
||||
return new ValueNodeOutputViewModel<T>()
|
||||
{
|
||||
Name = input.Name,
|
||||
Icon = input.Icon
|
||||
};
|
||||
}
|
||||
|
||||
public virtual ValueNodeOutputViewModel<IObservableList<T>> CreateCompatibleOutput<T>(ValueListNodeInputViewModel<T> input)
|
||||
{
|
||||
return new ValueNodeOutputViewModel<IObservableList<T>>();
|
||||
}
|
||||
|
||||
public virtual ValueNodeInputViewModel<T> CreateCompatibleInput<T>(ValueNodeOutputViewModel<T> output)
|
||||
{
|
||||
return new ValueNodeInputViewModel<T>()
|
||||
{
|
||||
Name = output.Name,
|
||||
Icon = output.Icon
|
||||
};
|
||||
}
|
||||
|
||||
public virtual ValueListNodeInputViewModel<T> CreateCompatibleInput<T>(ValueNodeOutputViewModel<IObservableList<T>> output)
|
||||
{
|
||||
return new ValueListNodeInputViewModel<T>()
|
||||
{
|
||||
Name = output.Name,
|
||||
Icon = output.Icon
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Endpoint Add
|
||||
public override NodeInputViewModel AddNewGroupNodeInput(NodeOutputViewModel candidateOutput)
|
||||
{
|
||||
NodeInputViewModel input = CreateCompatibleInput((dynamic)candidateOutput);
|
||||
input.Name = candidateOutput.Name;
|
||||
GroupNode.Inputs.Add(input);
|
||||
// Append to bottom of list
|
||||
input.SortIndex = GroupNode.Inputs.Items.Select(i => i.SortIndex).DefaultIfEmpty(-1).Max() + 1;
|
||||
return input;
|
||||
}
|
||||
|
||||
public override NodeOutputViewModel AddNewSubnetInlet(NodeInputViewModel candidateInput)
|
||||
{
|
||||
NodeInputViewModel input = AddNewGroupNodeInput(CreateCompatibleOutput((dynamic)candidateInput));
|
||||
return GetSubnetInlet(input);
|
||||
}
|
||||
|
||||
public override NodeInputViewModel AddNewSubnetOutlet(NodeOutputViewModel candidateOutput)
|
||||
{
|
||||
NodeOutputViewModel output = AddNewGroupNodeOutput(CreateCompatibleInput((dynamic)candidateOutput));
|
||||
return GetSubnetOutlet(output);
|
||||
}
|
||||
|
||||
public override NodeOutputViewModel AddNewGroupNodeOutput(NodeInputViewModel candidateInput)
|
||||
{
|
||||
NodeOutputViewModel output = CreateCompatibleOutput((dynamic)candidateInput);
|
||||
output.Name = candidateInput.Name;
|
||||
GroupNode.Outputs.Add(output);
|
||||
// Append to bottom of list
|
||||
output.SortIndex = GroupNode.Outputs.Items.Select(o => o.SortIndex).DefaultIfEmpty(-1).Max() + 1;
|
||||
return output;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Endpoint Getters
|
||||
public override NodeInputViewModel GetGroupNodeInput(NodeOutputViewModel entranceOutput)
|
||||
{
|
||||
return _outputInputMapping[entranceOutput];
|
||||
}
|
||||
|
||||
public override NodeOutputViewModel GetSubnetInlet(NodeInputViewModel entranceInput)
|
||||
{
|
||||
return _outputInputMapping.Single(p => p.Value == entranceInput).Key;
|
||||
}
|
||||
|
||||
public override NodeInputViewModel GetSubnetOutlet(NodeOutputViewModel exitOutput)
|
||||
{
|
||||
return _outputInputMapping[exitOutput];
|
||||
}
|
||||
|
||||
public override NodeOutputViewModel GetGroupNodeOutput(NodeInputViewModel exitInput)
|
||||
{
|
||||
return _outputInputMapping.Single(p => p.Value == exitInput).Key;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Remove an endpoint, which can be from group node, entrance node or exit node.
|
||||
/// Also removes the corresponding endpoint in the other network.
|
||||
/// </summary>
|
||||
/// <param name="endpoint">Input or output to be removed.</param>
|
||||
public virtual void DeleteEndpoint(Endpoint endpoint)
|
||||
{
|
||||
// Because the subnet entrance and exit are derived from the groupnode,
|
||||
// endpoints should be deleted from the groupnode only.
|
||||
|
||||
bool isOnGroupNode = GroupNode == endpoint.Parent;
|
||||
|
||||
if (endpoint is NodeInputViewModel input)
|
||||
{
|
||||
if (isOnGroupNode)
|
||||
{
|
||||
GroupNode.Inputs.Remove(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
var groupOutput = GetGroupNodeOutput(input);
|
||||
GroupNode.Outputs.Remove(groupOutput);
|
||||
}
|
||||
}
|
||||
else if(endpoint is NodeOutputViewModel output)
|
||||
{
|
||||
if (isOnGroupNode)
|
||||
{
|
||||
GroupNode.Outputs.Remove(output);
|
||||
}
|
||||
else
|
||||
{
|
||||
var groupInput = GetGroupNodeInput(output);
|
||||
GroupNode.Inputs.Remove(groupInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Layout.ForceDirected
|
||||
{
|
||||
public class Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// The network whose nodes are to be repositioned.
|
||||
/// </summary>
|
||||
public NetworkViewModel Network { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A time modifier that is used to speed up, or slow down, time during the simulation.
|
||||
/// A greater time modifier speeds up the physics simulation, at the cost of accuracy and stability.
|
||||
/// </summary>
|
||||
public float TimeModifier { get; set; } = 3.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Number of updates per iteration.
|
||||
/// Increasing this number increases the accuracy of the physics simulation at the cost of performance.
|
||||
/// </summary>
|
||||
public int UpdatesPerIteration { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// How strongly should nodes push eachother away?
|
||||
/// A greater NodeRepulsionForce increases the distance between nodes.
|
||||
/// </summary>
|
||||
public float NodeRepulsionForce { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// A function that maps each connection onto the equilibrium distance of its corresponding spring.
|
||||
/// A greater equilibrium distance increases the distance between the two connected endpoints.
|
||||
/// </summary>
|
||||
public Func<ConnectionViewModel, double> EquilibriumDistance { get; set; } = conn => 100;
|
||||
|
||||
/// <summary>
|
||||
/// A function that maps each connection onto the springiness/stiffness constant of its corresponding spring.
|
||||
/// (c.f. Hooke's law)
|
||||
/// </summary>
|
||||
public Func<ConnectionViewModel, double> SpringConstant { get; set; } = conn => 1;
|
||||
|
||||
/// <summary>
|
||||
/// A function that maps each connection onto the strength of its row force.
|
||||
/// Since inputs/outputs are on the left/right of a node, networks tend to be layed out horizontally.
|
||||
/// The row force is added onto the endpoints of the connection to make the nodes end up in a more horizontal layout.
|
||||
/// </summary>
|
||||
public Func<ConnectionViewModel, double> RowForce { get; set; } = conn => 100;
|
||||
|
||||
/// <summary>
|
||||
/// A function that maps each node onto its mass in the physics simulation.
|
||||
/// Greater mass makes the node harder to move.
|
||||
/// </summary>
|
||||
public Func<NodeViewModel, float> NodeMass { get; set; } = node => 10;
|
||||
|
||||
/// <summary>
|
||||
/// The friction coefficient is used to control friction forces in the simulation.
|
||||
/// Greater friction makes the simulation converge faster, as it slows nodes down when
|
||||
/// they are swinging around. If the friction is too high, the nodes will stop moving before
|
||||
/// they reach their optimal position or might not even move at all.
|
||||
/// </summary>
|
||||
public Func<NodeViewModel, float> FrictionCoefficient { get; set; } = node => 2.5f;
|
||||
|
||||
/// <summary>
|
||||
/// A predicate function that specifies whether or not a node is fixed.
|
||||
/// Fixed nodes do not get moved in the simulation.
|
||||
/// </summary>
|
||||
public Func<NodeViewModel, bool> IsFixedNode { get; set; } = node => false;
|
||||
}
|
||||
}
|
||||
125
intromat/NodeNetworkToolkit/Layout/ForceDirected/Engine.cs
Normal file
125
intromat/NodeNetworkToolkit/Layout/ForceDirected/Engine.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Layout.ForceDirected
|
||||
{
|
||||
internal class Engine
|
||||
{
|
||||
internal void ApplyRandomShift(NetworkViewModel network)
|
||||
{
|
||||
Random random = new Random();
|
||||
foreach (var node in network.Nodes.Items)
|
||||
{
|
||||
node.Position = node.Position + new Vector(random.NextDouble(), random.NextDouble());
|
||||
}
|
||||
}
|
||||
|
||||
internal void Update(int deltaTMillis, IState state, Configuration config)
|
||||
{
|
||||
// Calculate forces
|
||||
int nodeCount = config.Network.Nodes.Count;
|
||||
IList<(NodeViewModel, Vector)> nodeForces = new List<(NodeViewModel, Vector)>(nodeCount);
|
||||
|
||||
foreach (var node in config.Network.Nodes.Items)
|
||||
{
|
||||
if (!config.IsFixedNode(node))
|
||||
{
|
||||
nodeForces.Add((node, CalculateNodeForce(node, state, config)));
|
||||
}
|
||||
}
|
||||
|
||||
// Apply forces
|
||||
foreach (var (node, force) in nodeForces)
|
||||
{
|
||||
Vector speed = state.GetNodeSpeed(node);
|
||||
Vector pos = state.GetNodePosition(node);
|
||||
double deltaT = deltaTMillis / 1000.0;
|
||||
state.SetNodePosition(node, pos + ((speed * deltaT) + (force * deltaT * deltaT / 2)));
|
||||
state.SetNodeSpeed(node, speed + ((force / config.NodeMass(node)) * deltaT));
|
||||
}
|
||||
}
|
||||
|
||||
private Vector CalculateNodeForce(NodeViewModel node, IState state, Configuration config)
|
||||
{
|
||||
Vector force = new Vector();
|
||||
|
||||
// Calculate total force on node from endpoints
|
||||
if (node.Inputs.Count > 0 || node.Outputs.Count > 0)
|
||||
{
|
||||
force += node.Inputs.Items.Cast<Endpoint>().Concat(node.Outputs.Items)
|
||||
.Select(e => CalculateEndpointForce(e, state, config))
|
||||
.Aggregate((v1, v2) => v1 + v2);
|
||||
}
|
||||
|
||||
// Apply node repulsion force so nodes don't overlap
|
||||
var nodeCenter = state.GetNodePosition(node) + (new Vector(node.Size.Width, node.Size.Height) / 2.0);
|
||||
foreach (var otherNode in config.Network.Nodes.Items)
|
||||
{
|
||||
if (node == otherNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var otherNodeCenter = state.GetNodePosition(otherNode) + (new Vector(otherNode.Size.Width, otherNode.Size.Height) / 2.0);
|
||||
var thisToOther = otherNodeCenter - nodeCenter;
|
||||
var dist = thisToOther.Length;
|
||||
thisToOther.Normalize();
|
||||
|
||||
var repulsionX = thisToOther.X * (-1 * ((node.Size.Width + otherNode.Size.Width) / 2) / dist);
|
||||
var repulsionY = thisToOther.Y * (-1 * ((node.Size.Height + otherNode.Size.Height) / 2) / dist);
|
||||
force += new Vector(repulsionX, repulsionY) * config.NodeRepulsionForce;
|
||||
}
|
||||
|
||||
// Apply friction to make the movement converge to a stable state.
|
||||
float gravity = 9.8f;
|
||||
float normalForce = gravity * config.NodeMass(node);
|
||||
float kineticFriction = normalForce * config.FrictionCoefficient(node);
|
||||
Vector frictionVector = new Vector();
|
||||
var nodeSpeed = state.GetNodeSpeed(node);
|
||||
if (nodeSpeed.Length > 0)
|
||||
{
|
||||
frictionVector = new Vector(nodeSpeed.X, nodeSpeed.Y);
|
||||
frictionVector.Normalize();
|
||||
frictionVector *= -1.0 * kineticFriction;
|
||||
}
|
||||
force += frictionVector;
|
||||
|
||||
return force;
|
||||
}
|
||||
|
||||
private Vector CalculateEndpointForce(Endpoint endpoint, IState state, Configuration config)
|
||||
{
|
||||
var pos = state.GetEndpointPosition(endpoint);
|
||||
|
||||
Vector force = new Vector();
|
||||
|
||||
foreach (var conn in endpoint.Connections.Items)
|
||||
{
|
||||
var otherSide = conn.Input == endpoint ? (Endpoint)conn.Output : conn.Input;
|
||||
var otherSidePos = state.GetEndpointPosition(otherSide);
|
||||
var dist = (otherSidePos - pos).Length;
|
||||
var angle = Math.Acos((otherSidePos.X - pos.X) / dist);
|
||||
if (otherSidePos.Y < pos.Y)
|
||||
{
|
||||
angle *= -1.0;
|
||||
}
|
||||
|
||||
// Put a spring between connected endpoints.
|
||||
var hookForce = (dist - config.EquilibriumDistance(conn)) * config.SpringConstant(conn);
|
||||
force += new Vector(Math.Cos(angle), Math.Sin(angle)) * hookForce;
|
||||
|
||||
// Try to 'straighten' out the graph horizontally.
|
||||
var isLeftSide = endpoint.PortPosition == PortPosition.Left;
|
||||
var rowForce = (isLeftSide ? 1 : -1) * config.RowForce(conn);
|
||||
force.X += rowForce;
|
||||
}
|
||||
|
||||
return force;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Layout.ForceDirected
|
||||
{
|
||||
/// <summary>
|
||||
/// Reposition the nodes in a network using a physics-based approach.
|
||||
/// The nodes are interpreted as point masses, and the connections are represented
|
||||
/// by springs. This system, along with a few additional forces such as friction and a
|
||||
/// horizontal force, is then simulated to calculate the new position of the nodes.
|
||||
/// </summary>
|
||||
public class ForceDirectedLayouter
|
||||
{
|
||||
/// <summary>
|
||||
/// Layout the nodes in the network.
|
||||
/// </summary>
|
||||
/// <param name="config">The configuration to use.</param>
|
||||
/// <param name="maxIterations">The maximum amount of iterations after which the physics simulation ends.</param>
|
||||
public void Layout(Configuration config, int maxIterations)
|
||||
{
|
||||
var engine = new Engine();
|
||||
var state = new BufferedState();
|
||||
|
||||
// Move each node so no two nodes have the exact same position.
|
||||
engine.ApplyRandomShift(config.Network);
|
||||
|
||||
int deltaT = (int)Math.Ceiling(10.0 / (double)config.UpdatesPerIteration);
|
||||
for (int i = 0; i < maxIterations * config.UpdatesPerIteration; i++)
|
||||
{
|
||||
engine.Update(deltaT, state, config);
|
||||
}
|
||||
|
||||
foreach (var newNodePosition in state.NodePositions)
|
||||
{
|
||||
newNodePosition.Key.Position = new Point(newNodePosition.Value.X, newNodePosition.Value.Y);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Layout the nodes in the network, updating the user interface at each iteration.
|
||||
/// This method, contrary to Layout(), lets users see the simulation as it happens.
|
||||
/// The cancellation token should be used to end the simulation.
|
||||
/// </summary>
|
||||
/// <param name="config">The configuration to use.</param>
|
||||
/// <param name="token">A cancellation token to end the layout process.</param>
|
||||
/// <returns>The async task</returns>
|
||||
public async Task LayoutAsync(Configuration config, CancellationToken token)
|
||||
{
|
||||
var engine = new Engine();
|
||||
var state = new LiveState();
|
||||
|
||||
// Move each node so no two nodes have the exact same position.
|
||||
engine.ApplyRandomShift(config.Network);
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
TimeSpan t = TimeSpan.Zero;
|
||||
do
|
||||
{
|
||||
// Current real time
|
||||
var newT = DateTime.Now - start;
|
||||
var deltaT = newT - t;
|
||||
|
||||
// Current modified time
|
||||
//int virtT = (int)(t.Milliseconds * Settings.TimeModifier);
|
||||
int virtDeltaT = (int)(deltaT.Milliseconds * config.TimeModifier);
|
||||
int virtDeltaTPerUpdate = virtDeltaT / config.UpdatesPerIteration;
|
||||
for (int i = 0; i < config.UpdatesPerIteration; i++)
|
||||
{
|
||||
// Modified time in this update step
|
||||
engine.Update(virtDeltaTPerUpdate, state, config);
|
||||
}
|
||||
|
||||
t = newT;
|
||||
|
||||
await Task.Delay(14, token);
|
||||
} while (!token.IsCancellationRequested);
|
||||
}
|
||||
}
|
||||
}
|
||||
104
intromat/NodeNetworkToolkit/Layout/ForceDirected/State.cs
Normal file
104
intromat/NodeNetworkToolkit/Layout/ForceDirected/State.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit.Layout.ForceDirected
|
||||
{
|
||||
internal interface IState
|
||||
{
|
||||
Vector GetNodePosition(NodeViewModel node);
|
||||
void SetNodePosition(NodeViewModel node, Vector pos);
|
||||
Vector GetEndpointPosition(Endpoint endpoint);
|
||||
Vector GetNodeSpeed(NodeViewModel node);
|
||||
void SetNodeSpeed(NodeViewModel node, Vector speed);
|
||||
}
|
||||
|
||||
internal class BufferedState : IState
|
||||
{
|
||||
private readonly Dictionary<NodeViewModel, Vector> _nodePositions = new Dictionary<NodeViewModel, Vector>();
|
||||
private readonly Dictionary<Endpoint, Vector> _endpointRelativePositions = new Dictionary<Endpoint, Vector>();
|
||||
public IEnumerable<KeyValuePair<NodeViewModel, Vector>> NodePositions => _nodePositions;
|
||||
|
||||
private readonly Dictionary<NodeViewModel, Vector> _nodeSpeeds = new Dictionary<NodeViewModel, Vector>();
|
||||
|
||||
public Vector GetNodePosition(NodeViewModel node)
|
||||
{
|
||||
if (!_nodePositions.TryGetValue(node, out Vector result))
|
||||
{
|
||||
result = new Vector(node.Position.X, node.Position.Y);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetNodePosition(NodeViewModel node, Vector pos)
|
||||
{
|
||||
_nodePositions[node] = pos;
|
||||
}
|
||||
|
||||
public Vector GetEndpointPosition(Endpoint endpoint)
|
||||
{
|
||||
if (!_endpointRelativePositions.TryGetValue(endpoint, out Vector result))
|
||||
{
|
||||
result = new Vector(endpoint.Port.CenterPoint.X, endpoint.Port.CenterPoint.Y) - GetNodePosition(endpoint.Parent);
|
||||
_endpointRelativePositions[endpoint] = result;
|
||||
}
|
||||
|
||||
return result + GetNodePosition(endpoint.Parent);
|
||||
}
|
||||
|
||||
public Vector GetNodeSpeed(NodeViewModel node)
|
||||
{
|
||||
if (!_nodeSpeeds.TryGetValue(node, out Vector result))
|
||||
{
|
||||
result = new Vector(0, 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetNodeSpeed(NodeViewModel node, Vector speed)
|
||||
{
|
||||
_nodeSpeeds[node] = speed;
|
||||
}
|
||||
}
|
||||
|
||||
internal class LiveState : IState
|
||||
{
|
||||
private readonly Dictionary<NodeViewModel, Vector> _nodeSpeeds = new Dictionary<NodeViewModel, Vector>();
|
||||
|
||||
public Vector GetNodePosition(NodeViewModel node)
|
||||
{
|
||||
return new Vector(node.Position.X, node.Position.Y);
|
||||
}
|
||||
|
||||
public void SetNodePosition(NodeViewModel node, Vector pos)
|
||||
{
|
||||
node.Position = new Point(pos.X, pos.Y);
|
||||
}
|
||||
|
||||
public Vector GetEndpointPosition(Endpoint endpoint)
|
||||
{
|
||||
return new Vector(endpoint.Port.CenterPoint.X, endpoint.Port.CenterPoint.Y);
|
||||
}
|
||||
|
||||
public Vector GetNodeSpeed(NodeViewModel node)
|
||||
{
|
||||
if (!_nodeSpeeds.TryGetValue(node, out Vector result))
|
||||
{
|
||||
result = new Vector(0, 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetNodeSpeed(NodeViewModel node, Vector speed)
|
||||
{
|
||||
_nodeSpeeds[node] = speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
107
intromat/NodeNetworkToolkit/NodeList/NodeListView.xaml
Normal file
107
intromat/NodeNetworkToolkit/NodeList/NodeListView.xaml
Normal file
@@ -0,0 +1,107 @@
|
||||
<UserControl x:Class="NodeNetwork.Toolkit.NodeList.NodeListView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:controls="clr-namespace:NodeNetwork.Views.Controls;assembly=NodeNetwork"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="500" d:DesignWidth="320"
|
||||
Background="{DynamicResource BackgroundColor}"
|
||||
x:Name="self">
|
||||
<UserControl.Resources>
|
||||
<DataTemplate x:Key="tilesTemplate">
|
||||
<Grid>
|
||||
<controls:ViewModelViewHostNoAnimations VerticalAlignment="Top" Margin="0, 5, 0, 5" ViewModel="{Binding}" KeyboardNavigation.TabNavigation="None">
|
||||
<controls:ViewModelViewHostNoAnimations.LayoutTransform>
|
||||
<ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
|
||||
</controls:ViewModelViewHostNoAnimations.LayoutTransform>
|
||||
</controls:ViewModelViewHostNoAnimations>
|
||||
<Grid Background="#01000000" MouseMove="OnNodeMouseMove" Cursor="Hand"/>
|
||||
<!-- Overlay absorbs mouse events -->
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<ItemsPanelTemplate x:Key="tilesItemsPanelTemplate">
|
||||
<WrapPanel />
|
||||
</ItemsPanelTemplate>
|
||||
<ControlTemplate x:Key="tilesItemsControlTemplate">
|
||||
<ItemsPresenter HorizontalAlignment="Stretch"/>
|
||||
</ControlTemplate>
|
||||
|
||||
<DataTemplate x:Key="listTemplate">
|
||||
<Grid HorizontalAlignment="Stretch" Margin="0, 0, 0, 0" MouseMove="OnNodeMouseMove">
|
||||
<Grid.Style>
|
||||
<Style TargetType="Grid">
|
||||
<Setter Property="Background" Value="{Binding ListEntryBackgroundBrush, ElementName=self}"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{Binding ListEntryBackgroundMouseOverBrush, ElementName=self}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<TextBlock Margin="10,5,5,5"><Run Text="{Binding Name}"/></TextBlock>
|
||||
<Viewbox Stretch="Uniform" Width="10" Height="20" HorizontalAlignment="Right" Margin="5" Cursor="SizeAll">
|
||||
<Canvas Width="12.5" Height="30" Background="#01ffffff">
|
||||
<Rectangle Canvas.Left="0" Canvas.Top="0" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
<Rectangle Canvas.Left="7.5" Canvas.Top="0" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
<Rectangle Canvas.Left="0" Canvas.Top="7.5" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
<Rectangle Canvas.Left="7.5" Canvas.Top="7.5" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
<Rectangle Canvas.Left="0" Canvas.Top="15" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
<Rectangle Canvas.Left="7.5" Canvas.Top="15" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
<Rectangle Canvas.Left="0" Canvas.Top="22.5" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
<Rectangle Canvas.Left="7.5" Canvas.Top="22.5" Width="4" Height="4" Fill="{Binding ListEntryHandleBrush, ElementName=self}" StrokeThickness="0" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<ItemsPanelTemplate x:Key="listItemsPanelTemplate">
|
||||
<StackPanel HorizontalAlignment="Stretch"/>
|
||||
</ItemsPanelTemplate>
|
||||
<ControlTemplate x:Key="listItemsControlTemplate">
|
||||
<ItemsPresenter HorizontalAlignment="Stretch"/>
|
||||
</ControlTemplate>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"></RowDefinition>
|
||||
<RowDefinition Height="Auto"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Row="0">
|
||||
<TextBlock x:Name="titleLabel" Margin="10, 0, 0, 0" Padding="0, 10, 0, 10" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="18" FontFamily="Segoe UI Semilight" Text="Test"/>
|
||||
<ComboBox x:Name="viewComboBox" Margin="0,0,10,0" VerticalAlignment="Center" HorizontalAlignment="Right" Width="65" Height="20" />
|
||||
</Grid>
|
||||
|
||||
<Grid Row="1" x:Name="searchBoxGrid" Margin="25,7,25,0" MaxWidth="300" VerticalAlignment="Top">
|
||||
<TextBox x:Name="searchBox" TextWrapping="Wrap"/>
|
||||
<TextBlock Margin="5, 0, 0, 0" x:Name="emptySearchBoxMessage" Text="Search..." IsHitTestVisible="False" Foreground="LightGray"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Row="2" Margin="10,10,10,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<ScrollViewer>
|
||||
<ItemsControl x:Name="elementsList" IsTabStop="False">
|
||||
<ItemsControl.GroupStyle>
|
||||
<GroupStyle>
|
||||
<GroupStyle.ContainerStyle>
|
||||
<Style TargetType="{x:Type GroupItem}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate>
|
||||
<Expander Header="{Binding Name}" IsExpanded="True">
|
||||
<ItemsPresenter />
|
||||
</Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</GroupStyle.ContainerStyle>
|
||||
</GroupStyle>
|
||||
</ItemsControl.GroupStyle>
|
||||
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
<TextBlock x:Name="emptyMessage" Text="No matching nodes found" HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
166
intromat/NodeNetworkToolkit/NodeList/NodeListView.xaml.cs
Normal file
166
intromat/NodeNetworkToolkit/NodeList/NodeListView.xaml.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using DynamicData;
|
||||
using NodeNetwork.Utilities;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.NodeList
|
||||
{
|
||||
public partial class NodeListView : IViewFor<NodeListViewModel>
|
||||
{
|
||||
#region ViewModel
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(NodeListViewModel), typeof(NodeListView), new PropertyMetadata(null));
|
||||
|
||||
public NodeListViewModel ViewModel
|
||||
{
|
||||
get => (NodeListViewModel)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (NodeListViewModel)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Show/Hide properties
|
||||
public static readonly DependencyProperty ShowSearchProperty =
|
||||
DependencyProperty.Register(nameof(ShowSearch), typeof(bool), typeof(NodeListView), new PropertyMetadata(true));
|
||||
public static readonly DependencyProperty ShowDisplayModeSelectorProperty =
|
||||
DependencyProperty.Register(nameof(ShowDisplayModeSelector), typeof(bool), typeof(NodeListView), new PropertyMetadata(true));
|
||||
public static readonly DependencyProperty ShowTitleProperty =
|
||||
DependencyProperty.Register(nameof(ShowTitle), typeof(bool), typeof(NodeListView), new PropertyMetadata(true));
|
||||
|
||||
public bool ShowSearch
|
||||
{
|
||||
get { return (bool)GetValue(ShowSearchProperty); }
|
||||
set { SetValue(ShowSearchProperty, value); }
|
||||
}
|
||||
|
||||
public bool ShowDisplayModeSelector
|
||||
{
|
||||
get { return (bool)GetValue(ShowDisplayModeSelectorProperty); }
|
||||
set { SetValue(ShowDisplayModeSelectorProperty, value); }
|
||||
}
|
||||
|
||||
public bool ShowTitle
|
||||
{
|
||||
get { return (bool)GetValue(ShowTitleProperty); }
|
||||
set { SetValue(ShowTitleProperty, value); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Colors
|
||||
public static readonly DependencyProperty ListEntryBackgroundBrushProperty =
|
||||
DependencyProperty.Register(nameof(ListEntryBackgroundBrush), typeof(Brush), typeof(NodeListView), new PropertyMetadata(new SolidColorBrush(Colors.White)));
|
||||
|
||||
public Brush ListEntryBackgroundBrush
|
||||
{
|
||||
get { return (Brush)GetValue(ListEntryBackgroundBrushProperty); }
|
||||
set { SetValue(ListEntryBackgroundBrushProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ListEntryBackgroundMouseOverBrushProperty =
|
||||
DependencyProperty.Register(nameof(ListEntryBackgroundMouseOverBrush), typeof(Brush), typeof(NodeListView), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(0xf7, 0xf7, 0xf7))));
|
||||
|
||||
public Brush ListEntryBackgroundMouseOverBrush
|
||||
{
|
||||
get { return (Brush)GetValue(ListEntryBackgroundMouseOverBrushProperty); }
|
||||
set { SetValue(ListEntryBackgroundMouseOverBrushProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ListEntryHandleBrushProperty =
|
||||
DependencyProperty.Register(nameof(ListEntryHandleBrush), typeof(Brush), typeof(NodeListView), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(0x99, 0x99, 0x99))));
|
||||
|
||||
public Brush ListEntryHandleBrush
|
||||
{
|
||||
get { return (Brush)GetValue(ListEntryHandleBrushProperty); }
|
||||
set { SetValue(ListEntryHandleBrushProperty, value); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
public CollectionViewSource CVS { get; } = new CollectionViewSource();
|
||||
|
||||
public NodeListView()
|
||||
{
|
||||
InitializeComponent();
|
||||
if (DesignerProperties.GetIsInDesignMode(this)) { return; }
|
||||
|
||||
viewComboBox.ItemsSource = Enum.GetValues(typeof(NodeListViewModel.DisplayMode)).Cast<NodeListViewModel.DisplayMode>();
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.Display, v => v.viewComboBox.SelectedItem).DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.Display, v => v.elementsList.ItemTemplate,
|
||||
displayMode => displayMode == NodeListViewModel.DisplayMode.Tiles
|
||||
? Resources["tilesTemplate"]
|
||||
: Resources["listTemplate"])
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.Display, v => v.elementsList.ItemsPanel,
|
||||
displayMode => displayMode == NodeListViewModel.DisplayMode.Tiles
|
||||
? Resources["tilesItemsPanelTemplate"]
|
||||
: Resources["listItemsPanelTemplate"])
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.Display, v => v.elementsList.Template,
|
||||
displayMode => displayMode == NodeListViewModel.DisplayMode.Tiles
|
||||
? Resources["tilesItemsControlTemplate"]
|
||||
: Resources["listItemsControlTemplate"])
|
||||
.DisposeWith(d);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.SearchQuery, v => v.searchBox.Text).DisposeWith(d);
|
||||
|
||||
this.WhenAnyValue(v => v.ViewModel.VisibleNodes).Switch().Bind(out var bindableList).Subscribe().DisposeWith(d);
|
||||
CVS.Source = bindableList;
|
||||
elementsList.ItemsSource = CVS.View;
|
||||
|
||||
this.WhenAnyObservable(v => v.ViewModel.VisibleNodes.CountChanged)
|
||||
.Select(count => count == 0)
|
||||
.BindTo(this, v => v.emptyMessage.Visibility).DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.Title, v => v.titleLabel.Text).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.EmptyLabel, v => v.emptyMessage.Text).DisposeWith(d);
|
||||
|
||||
this.WhenAnyValue(v => v.searchBox.IsFocused, v => v.searchBox.Text)
|
||||
.Select(t => !t.Item1 && string.IsNullOrWhiteSpace(t.Item2))
|
||||
.BindTo(this, v => v.emptySearchBoxMessage.Visibility)
|
||||
.DisposeWith(d);
|
||||
|
||||
this.WhenAnyValue(v => v.ShowSearch)
|
||||
.BindTo(this, v => v.searchBoxGrid.Visibility).DisposeWith(d);
|
||||
this.WhenAnyValue(v => v.ShowDisplayModeSelector)
|
||||
.BindTo(this, v => v.viewComboBox.Visibility).DisposeWith(d);
|
||||
this.WhenAnyValue(v => v.ShowTitle)
|
||||
.BindTo(this, v => v.titleLabel.Visibility).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
private void OnNodeMouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
NodeViewModel nodeVM = ((FrameworkElement)sender).DataContext as NodeViewModel;
|
||||
if (nodeVM == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var nodeFactory = ViewModel.NodeTemplates.Items.First(t => t.Instance == nodeVM).Factory;
|
||||
NodeViewModel newNodeVM = nodeFactory();
|
||||
|
||||
DragDrop.DoDragDrop(this, new DataObject("nodeVM", newNodeVM), DragDropEffects.Copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
intromat/NodeNetworkToolkit/NodeList/NodeListViewModel.cs
Normal file
130
intromat/NodeNetworkToolkit/NodeList/NodeListViewModel.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using DynamicData;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.NodeList
|
||||
{
|
||||
/// <summary>
|
||||
/// A viewmodel for a UI List component that contains NodeViewModels
|
||||
/// and can be used to let the user add new nodes to a network.
|
||||
/// </summary>
|
||||
public class NodeListViewModel : ReactiveObject
|
||||
{
|
||||
static NodeListViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new NodeListView(), typeof(IViewFor<NodeListViewModel>));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The formatting mode of the list.
|
||||
/// </summary>
|
||||
public enum DisplayMode
|
||||
{
|
||||
/// <summary>
|
||||
/// The nodes are displayed graphically in a grid.
|
||||
/// </summary>
|
||||
Tiles,
|
||||
/// <summary>
|
||||
/// The node names are displayed as text in a list.
|
||||
/// </summary>
|
||||
List
|
||||
}
|
||||
|
||||
#region Title
|
||||
/// <summary>
|
||||
/// The string that is displayed at the top of the list
|
||||
/// </summary>
|
||||
public string Title
|
||||
{
|
||||
get => _title;
|
||||
set => this.RaiseAndSetIfChanged(ref _title, value);
|
||||
}
|
||||
private string _title;
|
||||
#endregion
|
||||
|
||||
#region EmptyLabel
|
||||
/// <summary>
|
||||
/// The string that is displayed when VisibleNodes is empty.
|
||||
/// </summary>
|
||||
public string EmptyLabel
|
||||
{
|
||||
get => _emptyLabel;
|
||||
set => this.RaiseAndSetIfChanged(ref _emptyLabel, value);
|
||||
}
|
||||
private string _emptyLabel = "";
|
||||
#endregion
|
||||
|
||||
#region DisplayMode
|
||||
/// <summary>
|
||||
/// The way the list of available nodes is formatted.
|
||||
/// </summary>
|
||||
public DisplayMode Display
|
||||
{
|
||||
get => _display;
|
||||
set => this.RaiseAndSetIfChanged(ref _display, value);
|
||||
}
|
||||
private DisplayMode _display;
|
||||
#endregion
|
||||
|
||||
#region NodeTemplates
|
||||
/// <summary>
|
||||
/// List of all the available nodes in the list.
|
||||
/// </summary>
|
||||
public ISourceList<NodeTemplate> NodeTemplates { get; } = new SourceList<NodeTemplate>();
|
||||
#endregion
|
||||
|
||||
#region VisibleNodes
|
||||
/// <summary>
|
||||
/// List of nodes that are actually visible in the list.
|
||||
/// This list is based on Nodes and SearchQuery.
|
||||
/// </summary>
|
||||
public IObservableList<NodeViewModel> VisibleNodes { get; }
|
||||
#endregion
|
||||
|
||||
#region SearchQuery
|
||||
/// <summary>
|
||||
/// The current search string that is used to filter Nodes into VisibleNodes.
|
||||
/// </summary>
|
||||
public string SearchQuery
|
||||
{
|
||||
get => _searchQuery;
|
||||
set => this.RaiseAndSetIfChanged(ref _searchQuery, value);
|
||||
}
|
||||
private string _searchQuery = "";
|
||||
#endregion
|
||||
|
||||
public NodeListViewModel()
|
||||
{
|
||||
Title = "Add node";
|
||||
EmptyLabel = "No matching nodes found.";
|
||||
Display = DisplayMode.Tiles;
|
||||
|
||||
var onQueryChanged = this.WhenAnyValue(vm => vm.SearchQuery)
|
||||
.Throttle(TimeSpan.FromMilliseconds(200), RxApp.MainThreadScheduler)
|
||||
.Publish();
|
||||
onQueryChanged.Connect();
|
||||
VisibleNodes = NodeTemplates.Connect()
|
||||
.AutoRefreshOnObservable(_ => onQueryChanged)
|
||||
.Transform(t => t.Instance)
|
||||
.AutoRefresh(node => node.Name)
|
||||
.Filter(n => (n.Name ?? "").ToUpper().Contains(SearchQuery?.ToUpper() ?? ""))
|
||||
.AsObservableList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new node type to the list.
|
||||
/// Every time a node is added to a network from this list, the factory function will be called to create a new instance of the viewmodel type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The subtype of NodeViewModel to add to the list.</typeparam>
|
||||
/// <param name="factory">The factory function to create a new instance of T</param>
|
||||
public void AddNodeType<T>(Func<T> factory) where T : NodeViewModel
|
||||
{
|
||||
NodeTemplates.Add(new NodeTemplate(factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
39
intromat/NodeNetworkToolkit/NodeNetworkToolkit.csproj
Normal file
39
intromat/NodeNetworkToolkit/NodeNetworkToolkit.csproj
Normal file
@@ -0,0 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0-windows7.0;net48</TargetFrameworks>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>NodeNetwork.Toolkit</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<UseWPF>true</UseWPF>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Version>6.0.0</Version>
|
||||
<Authors>Wouter De Keersmaecker</Authors>
|
||||
<PackageTags>wpf reactiveui node network editor node-editor graph</PackageTags>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<RepositoryUrl>https://www.github.com/wouterdek/nodenetwork</RepositoryUrl>
|
||||
<RepositoryType>Github</RepositoryType>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DocumentationFile>bin\Release\NodeNetworkToolkit.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include=".editorconfig" Link=".editorconfig" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NodeNetwork\NodeNetwork.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ReactiveUI" Version="13.2.18" />
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
<PackageReference Include="System.Buffers" Version="4.5.1" />
|
||||
<PackageReference Include="System.Collections.Immutable" Version="5.0.0" />
|
||||
<PackageReference Include="System.Drawing.Primitives" Version="4.3.0" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
|
||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
27
intromat/NodeNetworkToolkit/NodeTemplate.cs
Normal file
27
intromat/NodeNetworkToolkit/NodeTemplate.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in systems that need an example of a type of node as well as a way to create more instances of the same type.
|
||||
/// </summary>
|
||||
public class NodeTemplate
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory function to create a new instance of the same type of node as Instance
|
||||
/// </summary>
|
||||
public Func<NodeViewModel> Factory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Example instance of the type of node created by Factory
|
||||
/// </summary>
|
||||
public NodeViewModel Instance { get; }
|
||||
|
||||
public NodeTemplate(Func<NodeViewModel> factory)
|
||||
{
|
||||
Factory = factory;
|
||||
Instance = factory();
|
||||
}
|
||||
}
|
||||
}
|
||||
36
intromat/NodeNetworkToolkit/Properties/AssemblyInfo.cs
Normal file
36
intromat/NodeNetworkToolkit/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("NodeNetworkToolkit")]
|
||||
[assembly: AssemblyDescription("A helper library for NodeNetwork with additional, commonly used helper components")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("NodeNetwork")]
|
||||
[assembly: AssemblyCopyright("Copyright (c) Wouter De Keersmaecker")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("391d0670-646f-4633-9e86-e9a966f61953")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("6.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("6.0.0.0")]
|
||||
26
intromat/NodeNetworkToolkit/ValueNode/ValidationAction.cs
Normal file
26
intromat/NodeNetworkToolkit/ValueNode/ValidationAction.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace NodeNetwork.Toolkit.ValueNode
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Action that should be taken based on the validation result
|
||||
/// </summary>
|
||||
public enum ValidationAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Don't run the validation. (LatestValidation is not updated)
|
||||
/// </summary>
|
||||
DontValidate,
|
||||
/// <summary>
|
||||
/// Run the validation, but ignore the result and assume the network is valid.
|
||||
/// </summary>
|
||||
IgnoreValidation,
|
||||
/// <summary>
|
||||
/// Run the validation and if the network is invalid then wait until it is valid.
|
||||
/// </summary>
|
||||
WaitForValid,
|
||||
/// <summary>
|
||||
/// Run the validation and if the network is invalid then make default(T) the current value.
|
||||
/// </summary>
|
||||
PushDefaultValue
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using NodeNetwork.ViewModels;
|
||||
using NodeNetwork.Views;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ValueNode
|
||||
{
|
||||
/// <summary>
|
||||
/// An editor for ValueNodeInputViewModel or ValueNodeOutputViewModel.
|
||||
/// For inputs, this class can provide values when no connection is present.
|
||||
/// For outputs, this class can provide a way to configure the value produced by the output.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ValueEditorViewModel<T> : NodeEndpointEditorViewModel
|
||||
{
|
||||
static ValueEditorViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new NodeEndpointEditorView(), typeof(IViewFor<ValueEditorViewModel<T>>));
|
||||
}
|
||||
|
||||
#region Value
|
||||
/// <summary>
|
||||
/// The value currently set in the editor.
|
||||
/// </summary>
|
||||
public T Value
|
||||
{
|
||||
get => _value;
|
||||
set => this.RaiseAndSetIfChanged(ref _value, value);
|
||||
}
|
||||
private T _value;
|
||||
#endregion
|
||||
|
||||
#region ValueChanged
|
||||
/// <summary>
|
||||
/// Observable that produces an object when the value changes.
|
||||
/// </summary>
|
||||
public IObservable<T> ValueChanged { get; }
|
||||
#endregion
|
||||
|
||||
public ValueEditorViewModel()
|
||||
{
|
||||
ValueChanged = this.WhenAnyValue(vm => vm.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DynamicData;
|
||||
using DynamicData.Alias;
|
||||
using DynamicData.Kernel;
|
||||
using NodeNetwork.ViewModels;
|
||||
using NodeNetwork.Views;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ValueNode
|
||||
{
|
||||
/// <summary>
|
||||
/// A node input that keeps a list of the latest values produced by all of the connected ValueNodeOutputViewModels.
|
||||
/// This input can take multiple connections, ValueNodeInputViewModel cannot.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object this input can receive</typeparam>
|
||||
public class ValueListNodeInputViewModel<T> : NodeInputViewModel
|
||||
{
|
||||
static ValueListNodeInputViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new NodeInputView(), typeof(IViewFor<ValueListNodeInputViewModel<T>>));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current values of the outputs connected to this input
|
||||
/// </summary>
|
||||
public IObservableList<T> Values { get; }
|
||||
|
||||
public ValueListNodeInputViewModel()
|
||||
{
|
||||
MaxConnections = Int32.MaxValue;
|
||||
ConnectionValidator = pending => new ConnectionValidationResult(
|
||||
pending.Output is ValueNodeOutputViewModel<T> ||
|
||||
pending.Output is ValueNodeOutputViewModel<IObservableList<T>>,
|
||||
null
|
||||
);
|
||||
|
||||
var valuesFromSingles = Connections.Connect(c => c.Output is ValueNodeOutputViewModel<T>)
|
||||
.Transform(c => (ValueNodeOutputViewModel<T>)c.Output)
|
||||
//Note: this line used to be
|
||||
//.AutoRefresh(output => output.CurrentValue)
|
||||
//which ignored changes where CurrentValue didn't change.
|
||||
//This caused problems when the value object isn't replaced, but one of its properties changes.
|
||||
.AutoRefreshOnObservable(output => output.Value)
|
||||
// Null values are not allowed, so filter before transform
|
||||
.Filter(output => output.CurrentValue != null)
|
||||
.Transform(output => output.CurrentValue, true)
|
||||
// Any 'replace' changes that don't change the value should be refresh changes
|
||||
// This prevents issues where a value is updated, but it doesn't propagate through the network
|
||||
// because the connections didn't change.
|
||||
.Select(changes =>
|
||||
{
|
||||
if (changes.TotalChanges == changes.Replaced + changes.Refreshes)
|
||||
{
|
||||
bool allRefresh = true;
|
||||
var newChanges = new ChangeSet<T>();
|
||||
foreach (var change in changes)
|
||||
{
|
||||
if (change.Reason == ListChangeReason.Replace)
|
||||
{
|
||||
if (change.Type == ChangeType.Item)
|
||||
{
|
||||
if (change.Item.Previous != change.Item.Current)
|
||||
{
|
||||
allRefresh = false;
|
||||
break;
|
||||
}
|
||||
newChanges.Add(new Change<T>(ListChangeReason.Refresh, change.Item.Current, change.Item.Previous, change.Item.CurrentIndex, change.Item.PreviousIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Does this ever occur?");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newChanges.Add(change);
|
||||
}
|
||||
}
|
||||
|
||||
if (allRefresh) return newChanges;
|
||||
}
|
||||
return changes;
|
||||
});
|
||||
|
||||
var valuesFromLists = Connections.Connect(c => c.Output is ValueNodeOutputViewModel<IObservableList<T>>)
|
||||
// Grab list of values from output, using switch to handle when the list object is replaced
|
||||
.Transform(c => ((ValueNodeOutputViewModel<IObservableList<T>>) c.Output).Value.Switch())
|
||||
// Materialize this changeset stream into a list (needed to make sure the next step is done dynamically)
|
||||
.AsObservableList()
|
||||
// Take the union of all values from all lists. This is done dynamically, so adding/removing new lists works as expected.
|
||||
.Or();
|
||||
|
||||
Values = valuesFromSingles.Or(valuesFromLists).AsObservableList();
|
||||
}
|
||||
}
|
||||
}
|
||||
224
intromat/NodeNetworkToolkit/ValueNode/ValueNodeInputViewModel.cs
Normal file
224
intromat/NodeNetworkToolkit/ValueNode/ValueNodeInputViewModel.cs
Normal file
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Concurrency;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using NodeNetwork.ViewModels;
|
||||
using NodeNetwork.Views;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ValueNode
|
||||
{
|
||||
/// <summary>
|
||||
/// A node input that keeps track of the latest value produced by either the connected ValueNodeOutputViewModel,
|
||||
/// or the ValueEditorViewModel in the Editor property.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object this input can receive</typeparam>
|
||||
public class ValueNodeInputViewModel<T> : ValueNodeInputViewModelBase
|
||||
{
|
||||
static ValueNodeInputViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new NodeInputView(), typeof(IViewFor<ValueNodeInputViewModel<T>>));
|
||||
}
|
||||
|
||||
#region Value
|
||||
/// <summary>
|
||||
/// The value currently associated with this input.
|
||||
/// If the input is not connected, the value is taken from ValueEditorViewModel.Value in the Editor property.
|
||||
/// If the input is connected, the value is taken from ValueNodeOutputViewModel.LatestValue unless the network is not traversable.
|
||||
/// Note that this value may be equal to default(T) if there is an error somewhere.
|
||||
/// </summary>
|
||||
public T Value => _value.Value;
|
||||
private readonly ObservableAsPropertyHelper<T> _value;
|
||||
#endregion
|
||||
|
||||
#region ValueChanged
|
||||
/// <summary>
|
||||
/// An observable that fires when the input value changes.
|
||||
/// This may be because of a connection change, editor value change, network validation change, ...
|
||||
/// </summary>
|
||||
public IObservable<T> ValueChanged { get; }
|
||||
public override IObservable<Unit> UnitValueChanged { get; }
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new ValueNodeInputViewModel with the specified ValidationActions.
|
||||
/// The default values are carefully chosen and should probably not be changed unless you know what you are doing.
|
||||
/// </summary>
|
||||
/// <param name="connectionChangedValidationAction">The validation behaviour when the connection of this input changes.</param>
|
||||
/// <param name="connectedValueChangedValidationAction">The validation behaviour when the value of this input changes.</param>
|
||||
public ValueNodeInputViewModel(
|
||||
ValidationAction connectionChangedValidationAction = ValidationAction.PushDefaultValue,
|
||||
ValidationAction connectedValueChangedValidationAction = ValidationAction.IgnoreValidation
|
||||
)
|
||||
{
|
||||
MaxConnections = 1;
|
||||
ConnectionValidator = pending => new ConnectionValidationResult(pending.Output is ValueNodeOutputViewModel<T>, null);
|
||||
|
||||
var connectedValues = GenerateConnectedValuesBinding(connectionChangedValidationAction, connectedValueChangedValidationAction);
|
||||
|
||||
var localValues = this.WhenAnyValue(vm => vm.Editor)
|
||||
.Select(e =>
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return Observable.Return(default(T));
|
||||
}
|
||||
else if (!(e is ValueEditorViewModel<T>))
|
||||
{
|
||||
throw new Exception($"The endpoint editor is not a subclass of ValueEditorViewModel<{typeof(T).Name}>");
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((ValueEditorViewModel<T>)e).ValueChanged;
|
||||
}
|
||||
})
|
||||
.Switch();
|
||||
|
||||
var valueChanged = Observable.CombineLatest(connectedValues, localValues,
|
||||
(connectedValue, localValue) => Connections.Count == 0 ? localValue : connectedValue
|
||||
).Publish();
|
||||
valueChanged.Connect();
|
||||
valueChanged.ToProperty(this, vm => vm.Value, out _value);
|
||||
|
||||
ValueChanged = Observable
|
||||
.Defer(() => Observable.Return(Value))
|
||||
.Concat(valueChanged);
|
||||
|
||||
UnitValueChanged = ValueChanged
|
||||
.Select(_ => Unit.Default)
|
||||
.StartWith(Unit.Default);
|
||||
}
|
||||
|
||||
private IObservable<T> GenerateConnectedValuesBinding(ValidationAction connectionChangedValidationAction, ValidationAction connectedValueChangedValidationAction)
|
||||
{
|
||||
var onConnectionChanged = this.Connections.Connect().Select(_ => Unit.Default).StartWith(Unit.Default)
|
||||
.Select(_ => Connections.Count == 0 ? null : Connections.Items.First());
|
||||
|
||||
//On connection change
|
||||
IObservable<IObservable<T>> connectionObservables;
|
||||
if (connectionChangedValidationAction != ValidationAction.DontValidate)
|
||||
{
|
||||
//Either run network validation
|
||||
IObservable<NetworkValidationResult> postValidation = onConnectionChanged
|
||||
.SelectMany(con => Parent?.Parent?.UpdateValidation.Execute() ?? Observable.Return(new NetworkValidationResult(true, true, null)));
|
||||
|
||||
if (connectionChangedValidationAction == ValidationAction.WaitForValid)
|
||||
{
|
||||
//And wait until the validation is successful
|
||||
postValidation = postValidation.SelectMany(validation =>
|
||||
validation.NetworkIsTraversable
|
||||
? Observable.Return(validation)
|
||||
: Parent.Parent.Validation.FirstAsync(val => val.NetworkIsTraversable));
|
||||
}
|
||||
|
||||
if (connectionChangedValidationAction == ValidationAction.PushDefaultValue)
|
||||
{
|
||||
//Or push a single default(T) if the validation fails
|
||||
connectionObservables = postValidation.Select(validation =>
|
||||
{
|
||||
if (Connections.Count == 0)
|
||||
{
|
||||
return Observable.Return(default(T));
|
||||
}
|
||||
else if(validation.NetworkIsTraversable)
|
||||
{
|
||||
IObservable<T> connectedObservable =
|
||||
((ValueNodeOutputViewModel<T>) Connections.Items.First().Output).Value;
|
||||
if (connectedObservable == null)
|
||||
{
|
||||
throw new Exception($"The value observable for output '{Connections.Items.First().Output.Name}' is null.");
|
||||
}
|
||||
return connectedObservable;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Observable.Return(default(T));
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
//Grab the values observable from the connected output
|
||||
connectionObservables = postValidation
|
||||
.Select(_ =>
|
||||
{
|
||||
if (Connections.Count == 0)
|
||||
{
|
||||
return Observable.Return(default(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
IObservable<T> connectedObservable =
|
||||
((ValueNodeOutputViewModel<T>)Connections.Items.First().Output).Value;
|
||||
if (connectedObservable == null)
|
||||
{
|
||||
throw new Exception($"The value observable for output '{Connections.Items.First().Output.Name}' is null.");
|
||||
}
|
||||
return connectedObservable;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Or just grab the values observable from the connected output
|
||||
connectionObservables = onConnectionChanged.Select(con =>
|
||||
{
|
||||
if (con == null)
|
||||
{
|
||||
return Observable.Return(default(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
IObservable<T> connectedObservable =
|
||||
((ValueNodeOutputViewModel<T>)con.Output).Value;
|
||||
if (connectedObservable == null)
|
||||
{
|
||||
throw new Exception($"The value observable for output '{Connections.Items.First().Output.Name}' is null.");
|
||||
}
|
||||
return connectedObservable;
|
||||
}
|
||||
});
|
||||
}
|
||||
IObservable<T> connectedValues = connectionObservables.SelectMany(c => c);
|
||||
|
||||
//On connected output value change, either just push the value as is
|
||||
if (connectedValueChangedValidationAction != ValidationAction.DontValidate)
|
||||
{
|
||||
//Or run a network validation
|
||||
IObservable<NetworkValidationResult> postValidation = connectedValues.SelectMany(v =>
|
||||
Parent?.Parent?.UpdateValidation.Execute() ?? Observable.Return(new NetworkValidationResult(true, true, null)));
|
||||
if (connectedValueChangedValidationAction == ValidationAction.WaitForValid)
|
||||
{
|
||||
//And wait until the validation is successful
|
||||
postValidation = postValidation.SelectMany(validation =>
|
||||
validation.IsValid
|
||||
? Observable.Return(validation)
|
||||
: Parent.Parent.Validation.FirstAsync(val => val.IsValid));
|
||||
}
|
||||
|
||||
connectedValues = postValidation.Select(validation =>
|
||||
{
|
||||
if (Connections.Count == 0
|
||||
|| connectionChangedValidationAction == ValidationAction.PushDefaultValue && !validation.NetworkIsTraversable
|
||||
|| connectedValueChangedValidationAction == ValidationAction.PushDefaultValue && !validation.IsValid)
|
||||
{
|
||||
//Push default(T) if the network isn't valid
|
||||
return default;
|
||||
}
|
||||
|
||||
//Or just ignore the validation and push the value as is
|
||||
return ((ValueNodeOutputViewModel<T>) this.Connections.Items.First().Output).CurrentValue;
|
||||
});
|
||||
}
|
||||
|
||||
return connectedValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using NodeNetwork.ViewModels;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ValueNode
|
||||
{
|
||||
public abstract class ValueNodeInputViewModelBase : NodeInputViewModel
|
||||
{
|
||||
|
||||
#region ValueChanged
|
||||
/// <summary>
|
||||
/// An observable that fires when the input value changes.
|
||||
/// This may be because of a connection change, editor value change, network validation change, ...
|
||||
/// </summary>
|
||||
public abstract IObservable<Unit> UnitValueChanged { get; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Reactive.Concurrency;
|
||||
using NodeNetwork.ViewModels;
|
||||
using NodeNetwork.Views;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace NodeNetwork.Toolkit.ValueNode
|
||||
{
|
||||
/// <summary>
|
||||
/// A viewmodel for a node output that produces a value based on the inputs.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object produced by this output.</typeparam>
|
||||
public class ValueNodeOutputViewModel<T> : NodeOutputViewModel
|
||||
{
|
||||
static ValueNodeOutputViewModel()
|
||||
{
|
||||
NNViewRegistrar.AddRegistration(() => new NodeOutputView(), typeof(IViewFor<ValueNodeOutputViewModel<T>>));
|
||||
}
|
||||
|
||||
#region Value
|
||||
/// <summary>
|
||||
/// Observable that produces the value every time it changes.
|
||||
/// </summary>
|
||||
public IObservable<T> Value
|
||||
{
|
||||
get => _value;
|
||||
set => this.RaiseAndSetIfChanged(ref _value, value);
|
||||
}
|
||||
private IObservable<T> _value;
|
||||
#endregion
|
||||
|
||||
#region CurrentValue
|
||||
/// <summary>
|
||||
/// The latest value produced by this output.
|
||||
/// </summary>
|
||||
public T CurrentValue => _currentValue.Value;
|
||||
private readonly ObservableAsPropertyHelper<T> _currentValue;
|
||||
#endregion
|
||||
|
||||
public ValueNodeOutputViewModel()
|
||||
{
|
||||
this.WhenAnyObservable(vm => vm.Value).ToProperty(this, vm => vm.CurrentValue, out _currentValue, false, Scheduler.Immediate);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/DynamicData.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/DynamicData.dll
Normal file
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/NodeNetwork.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/NodeNetwork.dll
Normal file
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/NodeNetwork.pdb
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/NodeNetwork.pdb
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/ReactiveUI.Wpf.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/ReactiveUI.Wpf.dll
Normal file
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/ReactiveUI.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/ReactiveUI.dll
Normal file
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/Splat.Drawing.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/Splat.Drawing.dll
Normal file
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/Splat.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/Splat.dll
Normal file
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/System.Buffers.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/System.Buffers.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/System.Memory.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/System.Memory.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/System.Reactive.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/System.Reactive.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/log4net.dll
Normal file
BIN
intromat/NodeNetworkToolkit/bin/Debug/net48/log4net.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,543 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v5.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v5.0": {
|
||||
"NodeNetworkToolkit/6.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"NodeNetwork": "6.0.0",
|
||||
"ReactiveUI": "13.2.18",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Collections.Immutable": "5.0.0",
|
||||
"System.Data.DataSetExtensions": "4.5.0",
|
||||
"System.Drawing.Primitives": "4.3.0",
|
||||
"System.Memory": "4.5.4",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "5.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4",
|
||||
"System.ValueTuple": "4.5.0"
|
||||
},
|
||||
"runtime": {
|
||||
"NodeNetworkToolkit.dll": {}
|
||||
}
|
||||
},
|
||||
"DynamicData/7.1.1": {
|
||||
"dependencies": {
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0/DynamicData.dll": {
|
||||
"assemblyVersion": "7.1.0.0",
|
||||
"fileVersion": "7.1.1.11487"
|
||||
}
|
||||
}
|
||||
},
|
||||
"log4net/2.0.12": {
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "4.5.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/log4net.dll": {
|
||||
"assemblyVersion": "2.0.12.0",
|
||||
"fileVersion": "2.0.12.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.CSharp/4.7.0": {},
|
||||
"Microsoft.NETCore.Platforms/2.0.0": {},
|
||||
"Microsoft.NETCore.Targets/1.1.0": {},
|
||||
"Pharmacist.Common/2.0.8": {
|
||||
"dependencies": {
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0/Pharmacist.Common.dll": {
|
||||
"assemblyVersion": "2.0.0.0",
|
||||
"fileVersion": "2.0.8.15338"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReactiveUI/13.2.18": {
|
||||
"dependencies": {
|
||||
"DynamicData": "7.1.1",
|
||||
"Splat": "11.0.1",
|
||||
"System.Reactive": "5.0.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/ReactiveUI.dll": {
|
||||
"assemblyVersion": "13.2.0.0",
|
||||
"fileVersion": "13.2.18.42750"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReactiveUI.Events.WPF/13.2.18": {
|
||||
"dependencies": {
|
||||
"Pharmacist.Common": "2.0.8",
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/ReactiveUI.Events.WPF.dll": {
|
||||
"assemblyVersion": "13.2.0.0",
|
||||
"fileVersion": "13.2.18.42750"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReactiveUI.WPF/13.2.18": {
|
||||
"dependencies": {
|
||||
"ReactiveUI": "13.2.18",
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/ReactiveUI.Wpf.dll": {
|
||||
"assemblyVersion": "13.2.0.0",
|
||||
"fileVersion": "13.2.18.42750"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Splat/11.0.1": {
|
||||
"runtime": {
|
||||
"lib/net5.0/Splat.dll": {
|
||||
"assemblyVersion": "11.0.0.0",
|
||||
"fileVersion": "11.0.1.61461"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Splat.Drawing/11.0.1": {
|
||||
"dependencies": {
|
||||
"Splat": "11.0.1",
|
||||
"System.Diagnostics.Contracts": "4.3.0",
|
||||
"System.Drawing.Primitives": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/Splat.Drawing.dll": {
|
||||
"assemblyVersion": "11.0.0.0",
|
||||
"fileVersion": "11.0.1.61461"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Buffers/4.5.1": {},
|
||||
"System.Collections.Immutable/5.0.0": {},
|
||||
"System.Configuration.ConfigurationManager/4.5.0": {
|
||||
"dependencies": {
|
||||
"System.Security.Cryptography.ProtectedData": "4.5.0",
|
||||
"System.Security.Permissions": "4.5.0"
|
||||
}
|
||||
},
|
||||
"System.Data.DataSetExtensions/4.5.0": {},
|
||||
"System.Diagnostics.Contracts/4.3.0": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Drawing.Primitives/4.3.0": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Globalization/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.IO/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Text.Encoding": "4.3.0",
|
||||
"System.Threading.Tasks": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Memory/4.5.4": {},
|
||||
"System.Numerics.Vectors/4.5.0": {},
|
||||
"System.Reactive/5.0.0": {
|
||||
"runtime": {
|
||||
"lib/net5.0/System.Reactive.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.0.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Reflection/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.IO": "4.3.0",
|
||||
"System.Reflection.Primitives": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Reflection.Primitives/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Resources.ResourceManager/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Globalization": "4.3.0",
|
||||
"System.Reflection": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe/5.0.0": {},
|
||||
"System.Runtime.Extensions/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives/4.3.0": {
|
||||
"dependencies": {
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl/4.5.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"System.Security.Principal.Windows": "4.5.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/4.5.0": {},
|
||||
"System.Security.Permissions/4.5.0": {
|
||||
"dependencies": {
|
||||
"System.Security.AccessControl": "4.5.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Principal.Windows/4.5.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions/4.5.4": {},
|
||||
"System.ValueTuple/4.5.0": {},
|
||||
"NodeNetwork/6.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"ReactiveUI": "13.2.18",
|
||||
"ReactiveUI.Events.WPF": "13.2.18",
|
||||
"ReactiveUI.WPF": "13.2.18",
|
||||
"Splat.Drawing": "11.0.1",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Collections.Immutable": "5.0.0",
|
||||
"System.Data.DataSetExtensions": "4.5.0",
|
||||
"System.Drawing.Primitives": "4.3.0",
|
||||
"System.Memory": "4.5.4",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "5.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4",
|
||||
"System.ValueTuple": "4.5.0",
|
||||
"log4net": "2.0.12"
|
||||
},
|
||||
"runtime": {
|
||||
"NodeNetwork.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"NodeNetworkToolkit/6.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"DynamicData/7.1.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Pc6J5bFnSxEa64PV2V67FMcLlDdpv6m+zTBKSnRN3aLon/WtWWy8kuDpHFbJlgXHtqc6Nxloj9ItuvDlvKC/8w==",
|
||||
"path": "dynamicdata/7.1.1",
|
||||
"hashPath": "dynamicdata.7.1.1.nupkg.sha512"
|
||||
},
|
||||
"log4net/2.0.12": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-9P67BCftJ7KG+B7rNOM1A9KczUwyEDed6zbAddy5Cj/73xVkzi+rEAHeOgUnW5wDqy1JFlY8+oTP0m1PgJ03Tg==",
|
||||
"path": "log4net/2.0.12",
|
||||
"hashPath": "log4net.2.0.12.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.CSharp/4.7.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==",
|
||||
"path": "microsoft.csharp/4.7.0",
|
||||
"hashPath": "microsoft.csharp.4.7.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.NETCore.Platforms/2.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-VdLJOCXhZaEMY7Hm2GKiULmn7IEPFE4XC5LPSfBVCUIA8YLZVh846gtfBJalsPQF2PlzdD7ecX7DZEulJ402ZQ==",
|
||||
"path": "microsoft.netcore.platforms/2.0.0",
|
||||
"hashPath": "microsoft.netcore.platforms.2.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.NETCore.Targets/1.1.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==",
|
||||
"path": "microsoft.netcore.targets/1.1.0",
|
||||
"hashPath": "microsoft.netcore.targets.1.1.0.nupkg.sha512"
|
||||
},
|
||||
"Pharmacist.Common/2.0.8": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-NNiYvv2oTd18ckJMBt8zatCBPj0KwbzbxMuxgu45m20VtqvkvR6AborbOhkhmJC70iaSv3uLvhTnFExIJGDnQA==",
|
||||
"path": "pharmacist.common/2.0.8",
|
||||
"hashPath": "pharmacist.common.2.0.8.nupkg.sha512"
|
||||
},
|
||||
"ReactiveUI/13.2.18": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-w457p8goRjJgbggK2whtgYO8U9SOT1JbMDyZOKceibWoZVuOGME4RfUc60/AsLVmfwlkI+9ve+xc2S696nJZuQ==",
|
||||
"path": "reactiveui/13.2.18",
|
||||
"hashPath": "reactiveui.13.2.18.nupkg.sha512"
|
||||
},
|
||||
"ReactiveUI.Events.WPF/13.2.18": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-m9mFgMdSWFAdlCEFOahD2bfDo+zV8BlLxOhTSVSEFbtiSC0loYHSbJDBZYu/nxTTYzjqHTN86PZ7T9NoRgfVGw==",
|
||||
"path": "reactiveui.events.wpf/13.2.18",
|
||||
"hashPath": "reactiveui.events.wpf.13.2.18.nupkg.sha512"
|
||||
},
|
||||
"ReactiveUI.WPF/13.2.18": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ALpQe9Y970v4d/RfFT/keb93POq1WEYwUq0bfvZchUiYG4j8GOcFe085x+D5bfwh2aCRz/hHNl+9fTFVnCRisw==",
|
||||
"path": "reactiveui.wpf/13.2.18",
|
||||
"hashPath": "reactiveui.wpf.13.2.18.nupkg.sha512"
|
||||
},
|
||||
"Splat/11.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-C1p+fZE+xgwKCqnf9Qsk0lrJYGiUplWpS2wp9/RR/YNHkjx7vBCRebau1Uej7ZXda71eJgZVBYzZq0/qsQOc3Q==",
|
||||
"path": "splat/11.0.1",
|
||||
"hashPath": "splat.11.0.1.nupkg.sha512"
|
||||
},
|
||||
"Splat.Drawing/11.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-hSho9yLfiv2+QhWqZImg01lhZZzz/6qPP3r2AQQRRJdxIoqgcgw1VqBWYC5bT+4QzcX/hAcjtpmQXmYEg2KBZw==",
|
||||
"path": "splat.drawing/11.0.1",
|
||||
"hashPath": "splat.drawing.11.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Buffers/4.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
|
||||
"path": "system.buffers/4.5.1",
|
||||
"hashPath": "system.buffers.4.5.1.nupkg.sha512"
|
||||
},
|
||||
"System.Collections.Immutable/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==",
|
||||
"path": "system.collections.immutable/5.0.0",
|
||||
"hashPath": "system.collections.immutable.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-UIFvaFfuKhLr9u5tWMxmVoDPkFeD+Qv8gUuap4aZgVGYSYMdERck4OhLN/2gulAc0nYTEigWXSJNNWshrmxnng==",
|
||||
"path": "system.configuration.configurationmanager/4.5.0",
|
||||
"hashPath": "system.configuration.configurationmanager.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Data.DataSetExtensions/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-221clPs1445HkTBZPL+K9sDBdJRB8UN8rgjO3ztB0CQ26z//fmJXtlsr6whGatscsKGBrhJl5bwJuKSA8mwFOw==",
|
||||
"path": "system.data.datasetextensions/4.5.0",
|
||||
"hashPath": "system.data.datasetextensions.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Diagnostics.Contracts/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-eelRRbnm+OloiQvp9CXS0ixjNQldjjkHO4iIkR5XH2VIP8sUB/SIpa1TdUW6/+HDcQ+MlhP3pNa1u5SbzYuWGA==",
|
||||
"path": "system.diagnostics.contracts/4.3.0",
|
||||
"hashPath": "system.diagnostics.contracts.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Drawing.Primitives/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-1QU/c35gwdhvj77fkScXQQbjiVAqIL3fEYn/19NE0CV/ic5TN5PyWAft8HsrbRd4SBLEoErNCkWSzMDc0MmbRw==",
|
||||
"path": "system.drawing.primitives/4.3.0",
|
||||
"hashPath": "system.drawing.primitives.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Globalization/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
|
||||
"path": "system.globalization/4.3.0",
|
||||
"hashPath": "system.globalization.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.IO/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
|
||||
"path": "system.io/4.3.0",
|
||||
"hashPath": "system.io.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Memory/4.5.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==",
|
||||
"path": "system.memory/4.5.4",
|
||||
"hashPath": "system.memory.4.5.4.nupkg.sha512"
|
||||
},
|
||||
"System.Numerics.Vectors/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==",
|
||||
"path": "system.numerics.vectors/4.5.0",
|
||||
"hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Reactive/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"path": "system.reactive/5.0.0",
|
||||
"hashPath": "system.reactive.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Reflection/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
|
||||
"path": "system.reflection/4.3.0",
|
||||
"hashPath": "system.reflection.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Reflection.Primitives/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
|
||||
"path": "system.reflection.primitives/4.3.0",
|
||||
"hashPath": "system.reflection.primitives.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Resources.ResourceManager/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
|
||||
"path": "system.resources.resourcemanager/4.3.0",
|
||||
"hashPath": "system.resources.resourcemanager.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
||||
"path": "system.runtime/4.3.0",
|
||||
"hashPath": "system.runtime.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==",
|
||||
"path": "system.runtime.compilerservices.unsafe/5.0.0",
|
||||
"hashPath": "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.Extensions/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
|
||||
"path": "system.runtime.extensions/4.3.0",
|
||||
"hashPath": "system.runtime.extensions.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
|
||||
"path": "system.runtime.serialization.primitives/4.3.0",
|
||||
"hashPath": "system.runtime.serialization.primitives.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.AccessControl/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-vW8Eoq0TMyz5vAG/6ce483x/CP83fgm4SJe5P8Tb1tZaobcvPrbMEL7rhH1DRdrYbbb6F0vq3OlzmK0Pkwks5A==",
|
||||
"path": "system.security.accesscontrol/4.5.0",
|
||||
"hashPath": "system.security.accesscontrol.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q==",
|
||||
"path": "system.security.cryptography.protecteddata/4.5.0",
|
||||
"hashPath": "system.security.cryptography.protecteddata.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Permissions/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-9gdyuARhUR7H+p5CjyUB/zPk7/Xut3wUSP8NJQB6iZr8L3XUXTMdoLeVAg9N4rqF8oIpE7MpdqHdDHQ7XgJe0g==",
|
||||
"path": "system.security.permissions/4.5.0",
|
||||
"hashPath": "system.security.permissions.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Principal.Windows/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-U77HfRXlZlOeIXd//Yoj6Jnk8AXlbeisf1oq1os+hxOGVnuG+lGSfGqTwTZBoORFF6j/0q7HXIl8cqwQ9aUGqQ==",
|
||||
"path": "system.security.principal.windows/4.5.0",
|
||||
"hashPath": "system.security.principal.windows.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Text.Encoding/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
|
||||
"path": "system.text.encoding/4.3.0",
|
||||
"hashPath": "system.text.encoding.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Threading.Tasks/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
|
||||
"path": "system.threading.tasks/4.3.0",
|
||||
"hashPath": "system.threading.tasks.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Threading.Tasks.Extensions/4.5.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"path": "system.threading.tasks.extensions/4.5.4",
|
||||
"hashPath": "system.threading.tasks.extensions.4.5.4.nupkg.sha512"
|
||||
},
|
||||
"System.ValueTuple/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==",
|
||||
"path": "system.valuetuple/4.5.0",
|
||||
"hashPath": "system.valuetuple.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"NodeNetwork/6.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,543 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v7.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v7.0": {
|
||||
"NodeNetworkToolkit/6.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"NodeNetwork": "6.0.0",
|
||||
"ReactiveUI": "13.2.18",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Collections.Immutable": "5.0.0",
|
||||
"System.Data.DataSetExtensions": "4.5.0",
|
||||
"System.Drawing.Primitives": "4.3.0",
|
||||
"System.Memory": "4.5.4",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "5.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4",
|
||||
"System.ValueTuple": "4.5.0"
|
||||
},
|
||||
"runtime": {
|
||||
"NodeNetworkToolkit.dll": {}
|
||||
}
|
||||
},
|
||||
"DynamicData/7.1.1": {
|
||||
"dependencies": {
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0/DynamicData.dll": {
|
||||
"assemblyVersion": "7.1.0.0",
|
||||
"fileVersion": "7.1.1.11487"
|
||||
}
|
||||
}
|
||||
},
|
||||
"log4net/2.0.12": {
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "4.5.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/log4net.dll": {
|
||||
"assemblyVersion": "2.0.12.0",
|
||||
"fileVersion": "2.0.12.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.CSharp/4.7.0": {},
|
||||
"Microsoft.NETCore.Platforms/2.0.0": {},
|
||||
"Microsoft.NETCore.Targets/1.1.0": {},
|
||||
"Pharmacist.Common/2.0.8": {
|
||||
"dependencies": {
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0/Pharmacist.Common.dll": {
|
||||
"assemblyVersion": "2.0.0.0",
|
||||
"fileVersion": "2.0.8.15338"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReactiveUI/13.2.18": {
|
||||
"dependencies": {
|
||||
"DynamicData": "7.1.1",
|
||||
"Splat": "11.0.1",
|
||||
"System.Reactive": "5.0.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/ReactiveUI.dll": {
|
||||
"assemblyVersion": "13.2.0.0",
|
||||
"fileVersion": "13.2.18.42750"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReactiveUI.Events.WPF/13.2.18": {
|
||||
"dependencies": {
|
||||
"Pharmacist.Common": "2.0.8",
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/ReactiveUI.Events.WPF.dll": {
|
||||
"assemblyVersion": "13.2.0.0",
|
||||
"fileVersion": "13.2.18.42750"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ReactiveUI.WPF/13.2.18": {
|
||||
"dependencies": {
|
||||
"ReactiveUI": "13.2.18",
|
||||
"System.Reactive": "5.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/ReactiveUI.Wpf.dll": {
|
||||
"assemblyVersion": "13.2.0.0",
|
||||
"fileVersion": "13.2.18.42750"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Splat/11.0.1": {
|
||||
"runtime": {
|
||||
"lib/net5.0/Splat.dll": {
|
||||
"assemblyVersion": "11.0.0.0",
|
||||
"fileVersion": "11.0.1.61461"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Splat.Drawing/11.0.1": {
|
||||
"dependencies": {
|
||||
"Splat": "11.0.1",
|
||||
"System.Diagnostics.Contracts": "4.3.0",
|
||||
"System.Drawing.Primitives": "4.3.0",
|
||||
"System.Runtime.Serialization.Primitives": "4.3.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net5.0-windows7.0/Splat.Drawing.dll": {
|
||||
"assemblyVersion": "11.0.0.0",
|
||||
"fileVersion": "11.0.1.61461"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Buffers/4.5.1": {},
|
||||
"System.Collections.Immutable/5.0.0": {},
|
||||
"System.Configuration.ConfigurationManager/4.5.0": {
|
||||
"dependencies": {
|
||||
"System.Security.Cryptography.ProtectedData": "4.5.0",
|
||||
"System.Security.Permissions": "4.5.0"
|
||||
}
|
||||
},
|
||||
"System.Data.DataSetExtensions/4.5.0": {},
|
||||
"System.Diagnostics.Contracts/4.3.0": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Drawing.Primitives/4.3.0": {
|
||||
"dependencies": {
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Globalization/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.IO/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0",
|
||||
"System.Text.Encoding": "4.3.0",
|
||||
"System.Threading.Tasks": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Memory/4.5.4": {},
|
||||
"System.Numerics.Vectors/4.5.0": {},
|
||||
"System.Reactive/5.0.0": {
|
||||
"runtime": {
|
||||
"lib/net5.0/System.Reactive.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.0.0.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Reflection/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.IO": "4.3.0",
|
||||
"System.Reflection.Primitives": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Reflection.Primitives/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Resources.ResourceManager/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Globalization": "4.3.0",
|
||||
"System.Reflection": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe/5.0.0": {},
|
||||
"System.Runtime.Extensions/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives/4.3.0": {
|
||||
"dependencies": {
|
||||
"System.Resources.ResourceManager": "4.3.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl/4.5.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"System.Security.Principal.Windows": "4.5.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/4.5.0": {},
|
||||
"System.Security.Permissions/4.5.0": {
|
||||
"dependencies": {
|
||||
"System.Security.AccessControl": "4.5.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Principal.Windows/4.5.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks/4.3.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "2.0.0",
|
||||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions/4.5.4": {},
|
||||
"System.ValueTuple/4.5.0": {},
|
||||
"NodeNetwork/6.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.CSharp": "4.7.0",
|
||||
"ReactiveUI": "13.2.18",
|
||||
"ReactiveUI.Events.WPF": "13.2.18",
|
||||
"ReactiveUI.WPF": "13.2.18",
|
||||
"Splat.Drawing": "11.0.1",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Collections.Immutable": "5.0.0",
|
||||
"System.Data.DataSetExtensions": "4.5.0",
|
||||
"System.Drawing.Primitives": "4.3.0",
|
||||
"System.Memory": "4.5.4",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "5.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4",
|
||||
"System.ValueTuple": "4.5.0",
|
||||
"log4net": "2.0.12"
|
||||
},
|
||||
"runtime": {
|
||||
"NodeNetwork.dll": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"NodeNetworkToolkit/6.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"DynamicData/7.1.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Pc6J5bFnSxEa64PV2V67FMcLlDdpv6m+zTBKSnRN3aLon/WtWWy8kuDpHFbJlgXHtqc6Nxloj9ItuvDlvKC/8w==",
|
||||
"path": "dynamicdata/7.1.1",
|
||||
"hashPath": "dynamicdata.7.1.1.nupkg.sha512"
|
||||
},
|
||||
"log4net/2.0.12": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-9P67BCftJ7KG+B7rNOM1A9KczUwyEDed6zbAddy5Cj/73xVkzi+rEAHeOgUnW5wDqy1JFlY8+oTP0m1PgJ03Tg==",
|
||||
"path": "log4net/2.0.12",
|
||||
"hashPath": "log4net.2.0.12.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.CSharp/4.7.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA==",
|
||||
"path": "microsoft.csharp/4.7.0",
|
||||
"hashPath": "microsoft.csharp.4.7.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.NETCore.Platforms/2.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-VdLJOCXhZaEMY7Hm2GKiULmn7IEPFE4XC5LPSfBVCUIA8YLZVh846gtfBJalsPQF2PlzdD7ecX7DZEulJ402ZQ==",
|
||||
"path": "microsoft.netcore.platforms/2.0.0",
|
||||
"hashPath": "microsoft.netcore.platforms.2.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.NETCore.Targets/1.1.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==",
|
||||
"path": "microsoft.netcore.targets/1.1.0",
|
||||
"hashPath": "microsoft.netcore.targets.1.1.0.nupkg.sha512"
|
||||
},
|
||||
"Pharmacist.Common/2.0.8": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-NNiYvv2oTd18ckJMBt8zatCBPj0KwbzbxMuxgu45m20VtqvkvR6AborbOhkhmJC70iaSv3uLvhTnFExIJGDnQA==",
|
||||
"path": "pharmacist.common/2.0.8",
|
||||
"hashPath": "pharmacist.common.2.0.8.nupkg.sha512"
|
||||
},
|
||||
"ReactiveUI/13.2.18": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-w457p8goRjJgbggK2whtgYO8U9SOT1JbMDyZOKceibWoZVuOGME4RfUc60/AsLVmfwlkI+9ve+xc2S696nJZuQ==",
|
||||
"path": "reactiveui/13.2.18",
|
||||
"hashPath": "reactiveui.13.2.18.nupkg.sha512"
|
||||
},
|
||||
"ReactiveUI.Events.WPF/13.2.18": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-m9mFgMdSWFAdlCEFOahD2bfDo+zV8BlLxOhTSVSEFbtiSC0loYHSbJDBZYu/nxTTYzjqHTN86PZ7T9NoRgfVGw==",
|
||||
"path": "reactiveui.events.wpf/13.2.18",
|
||||
"hashPath": "reactiveui.events.wpf.13.2.18.nupkg.sha512"
|
||||
},
|
||||
"ReactiveUI.WPF/13.2.18": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ALpQe9Y970v4d/RfFT/keb93POq1WEYwUq0bfvZchUiYG4j8GOcFe085x+D5bfwh2aCRz/hHNl+9fTFVnCRisw==",
|
||||
"path": "reactiveui.wpf/13.2.18",
|
||||
"hashPath": "reactiveui.wpf.13.2.18.nupkg.sha512"
|
||||
},
|
||||
"Splat/11.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-C1p+fZE+xgwKCqnf9Qsk0lrJYGiUplWpS2wp9/RR/YNHkjx7vBCRebau1Uej7ZXda71eJgZVBYzZq0/qsQOc3Q==",
|
||||
"path": "splat/11.0.1",
|
||||
"hashPath": "splat.11.0.1.nupkg.sha512"
|
||||
},
|
||||
"Splat.Drawing/11.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-hSho9yLfiv2+QhWqZImg01lhZZzz/6qPP3r2AQQRRJdxIoqgcgw1VqBWYC5bT+4QzcX/hAcjtpmQXmYEg2KBZw==",
|
||||
"path": "splat.drawing/11.0.1",
|
||||
"hashPath": "splat.drawing.11.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Buffers/4.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
|
||||
"path": "system.buffers/4.5.1",
|
||||
"hashPath": "system.buffers.4.5.1.nupkg.sha512"
|
||||
},
|
||||
"System.Collections.Immutable/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==",
|
||||
"path": "system.collections.immutable/5.0.0",
|
||||
"hashPath": "system.collections.immutable.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-UIFvaFfuKhLr9u5tWMxmVoDPkFeD+Qv8gUuap4aZgVGYSYMdERck4OhLN/2gulAc0nYTEigWXSJNNWshrmxnng==",
|
||||
"path": "system.configuration.configurationmanager/4.5.0",
|
||||
"hashPath": "system.configuration.configurationmanager.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Data.DataSetExtensions/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-221clPs1445HkTBZPL+K9sDBdJRB8UN8rgjO3ztB0CQ26z//fmJXtlsr6whGatscsKGBrhJl5bwJuKSA8mwFOw==",
|
||||
"path": "system.data.datasetextensions/4.5.0",
|
||||
"hashPath": "system.data.datasetextensions.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Diagnostics.Contracts/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-eelRRbnm+OloiQvp9CXS0ixjNQldjjkHO4iIkR5XH2VIP8sUB/SIpa1TdUW6/+HDcQ+MlhP3pNa1u5SbzYuWGA==",
|
||||
"path": "system.diagnostics.contracts/4.3.0",
|
||||
"hashPath": "system.diagnostics.contracts.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Drawing.Primitives/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-1QU/c35gwdhvj77fkScXQQbjiVAqIL3fEYn/19NE0CV/ic5TN5PyWAft8HsrbRd4SBLEoErNCkWSzMDc0MmbRw==",
|
||||
"path": "system.drawing.primitives/4.3.0",
|
||||
"hashPath": "system.drawing.primitives.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Globalization/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==",
|
||||
"path": "system.globalization/4.3.0",
|
||||
"hashPath": "system.globalization.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.IO/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==",
|
||||
"path": "system.io/4.3.0",
|
||||
"hashPath": "system.io.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Memory/4.5.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==",
|
||||
"path": "system.memory/4.5.4",
|
||||
"hashPath": "system.memory.4.5.4.nupkg.sha512"
|
||||
},
|
||||
"System.Numerics.Vectors/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==",
|
||||
"path": "system.numerics.vectors/4.5.0",
|
||||
"hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Reactive/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
|
||||
"path": "system.reactive/5.0.0",
|
||||
"hashPath": "system.reactive.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Reflection/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==",
|
||||
"path": "system.reflection/4.3.0",
|
||||
"hashPath": "system.reflection.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Reflection.Primitives/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==",
|
||||
"path": "system.reflection.primitives/4.3.0",
|
||||
"hashPath": "system.reflection.primitives.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Resources.ResourceManager/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==",
|
||||
"path": "system.resources.resourcemanager/4.3.0",
|
||||
"hashPath": "system.resources.resourcemanager.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==",
|
||||
"path": "system.runtime/4.3.0",
|
||||
"hashPath": "system.runtime.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe/5.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==",
|
||||
"path": "system.runtime.compilerservices.unsafe/5.0.0",
|
||||
"hashPath": "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.Extensions/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==",
|
||||
"path": "system.runtime.extensions/4.3.0",
|
||||
"hashPath": "system.runtime.extensions.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.Serialization.Primitives/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Wz+0KOukJGAlXjtKr+5Xpuxf8+c8739RI1C+A2BoQZT+wMCCoMDDdO8/4IRHfaVINqL78GO8dW8G2lW/e45Mcw==",
|
||||
"path": "system.runtime.serialization.primitives/4.3.0",
|
||||
"hashPath": "system.runtime.serialization.primitives.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.AccessControl/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-vW8Eoq0TMyz5vAG/6ce483x/CP83fgm4SJe5P8Tb1tZaobcvPrbMEL7rhH1DRdrYbbb6F0vq3OlzmK0Pkwks5A==",
|
||||
"path": "system.security.accesscontrol/4.5.0",
|
||||
"hashPath": "system.security.accesscontrol.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q==",
|
||||
"path": "system.security.cryptography.protecteddata/4.5.0",
|
||||
"hashPath": "system.security.cryptography.protecteddata.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Permissions/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-9gdyuARhUR7H+p5CjyUB/zPk7/Xut3wUSP8NJQB6iZr8L3XUXTMdoLeVAg9N4rqF8oIpE7MpdqHdDHQ7XgJe0g==",
|
||||
"path": "system.security.permissions/4.5.0",
|
||||
"hashPath": "system.security.permissions.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Principal.Windows/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-U77HfRXlZlOeIXd//Yoj6Jnk8AXlbeisf1oq1os+hxOGVnuG+lGSfGqTwTZBoORFF6j/0q7HXIl8cqwQ9aUGqQ==",
|
||||
"path": "system.security.principal.windows/4.5.0",
|
||||
"hashPath": "system.security.principal.windows.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"System.Text.Encoding/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==",
|
||||
"path": "system.text.encoding/4.3.0",
|
||||
"hashPath": "system.text.encoding.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Threading.Tasks/4.3.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==",
|
||||
"path": "system.threading.tasks/4.3.0",
|
||||
"hashPath": "system.threading.tasks.4.3.0.nupkg.sha512"
|
||||
},
|
||||
"System.Threading.Tasks.Extensions/4.5.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"path": "system.threading.tasks.extensions/4.5.4",
|
||||
"hashPath": "system.threading.tasks.extensions.4.5.4.nupkg.sha512"
|
||||
},
|
||||
"System.ValueTuple/4.5.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==",
|
||||
"path": "system.valuetuple/4.5.0",
|
||||
"hashPath": "system.valuetuple.4.5.0.nupkg.sha512"
|
||||
},
|
||||
"NodeNetwork/6.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>NodeNetworkToolkit</id>
|
||||
<version>6.0.0</version>
|
||||
<authors>Wouter De Keersmaecker</authors>
|
||||
<license type="expression">Apache-2.0</license>
|
||||
<licenseUrl>https://licenses.nuget.org/Apache-2.0</licenseUrl>
|
||||
<description>Package Description</description>
|
||||
<tags>wpf reactiveui node network editor node-editor graph</tags>
|
||||
<repository type="Github" url="https://www.github.com/wouterdek/nodenetwork" />
|
||||
<dependencies>
|
||||
<group targetFramework=".NETFramework4.8">
|
||||
<dependency id="NodeNetwork" version="6.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.CSharp" version="4.7.0" exclude="Build,Analyzers" />
|
||||
<dependency id="ReactiveUI" version="13.2.18" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Buffers" version="4.5.1" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Collections.Immutable" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Data.DataSetExtensions" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Primitives" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Memory" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Numerics.Vectors" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ValueTuple" version="4.5.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
<group targetFramework="net7.0-windows7.0">
|
||||
<dependency id="NodeNetwork" version="6.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.CSharp" version="4.7.0" exclude="Build,Analyzers" />
|
||||
<dependency id="ReactiveUI" version="13.2.18" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Buffers" version="4.5.1" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Collections.Immutable" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Data.DataSetExtensions" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Primitives" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Memory" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Numerics.Vectors" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ValueTuple" version="4.5.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
<frameworkReferences>
|
||||
<group targetFramework="net7.0-windows7.0">
|
||||
<frameworkReference name="Microsoft.WindowsDesktop.App.WPF" />
|
||||
</group>
|
||||
<group targetFramework=".NETFramework4.8" />
|
||||
</frameworkReferences>
|
||||
<frameworkAssemblies>
|
||||
<frameworkAssembly assemblyName="System.Drawing.Primitives" targetFramework=".NETFramework4.8" />
|
||||
</frameworkAssemblies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\NodeNetworkToolkit.dll" target="lib\net48\NodeNetworkToolkit.dll" />
|
||||
<file src="E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net7.0-windows7.0\NodeNetworkToolkit.dll" target="lib\net7.0-windows7.0\NodeNetworkToolkit.dll" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>NodeNetworkToolkit</id>
|
||||
<version>6.0.0</version>
|
||||
<authors>Wouter De Keersmaecker</authors>
|
||||
<license type="expression">Apache-2.0</license>
|
||||
<licenseUrl>https://licenses.nuget.org/Apache-2.0</licenseUrl>
|
||||
<description>Package Description</description>
|
||||
<tags>wpf reactiveui node network editor node-editor graph</tags>
|
||||
<repository type="Github" url="https://www.github.com/wouterdek/nodenetwork" />
|
||||
<dependencies>
|
||||
<group targetFramework=".NETFramework4.8">
|
||||
<dependency id="NodeNetwork" version="6.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.CSharp" version="4.7.0" exclude="Build,Analyzers" />
|
||||
<dependency id="ReactiveUI" version="13.2.18" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Buffers" version="4.5.1" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Collections.Immutable" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Data.DataSetExtensions" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Primitives" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Memory" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Numerics.Vectors" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ValueTuple" version="4.5.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
<group targetFramework="net7.0-windows7.0">
|
||||
<dependency id="NodeNetwork" version="6.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.CSharp" version="4.7.0" exclude="Build,Analyzers" />
|
||||
<dependency id="ReactiveUI" version="13.2.18" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Buffers" version="4.5.1" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Collections.Immutable" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Data.DataSetExtensions" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Drawing.Primitives" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Memory" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Numerics.Vectors" version="4.5.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ValueTuple" version="4.5.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
<frameworkReferences>
|
||||
<group targetFramework="net7.0-windows7.0">
|
||||
<frameworkReference name="Microsoft.WindowsDesktop.App.WPF" />
|
||||
</group>
|
||||
<group targetFramework=".NETFramework4.8" />
|
||||
</frameworkReferences>
|
||||
<frameworkAssemblies>
|
||||
<frameworkAssembly assemblyName="System.Drawing.Primitives" targetFramework=".NETFramework4.8" />
|
||||
</frameworkAssemblies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\NodeNetworkToolkit.pdb" target="lib\net48\NodeNetworkToolkit.pdb" />
|
||||
<file src="E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net7.0-windows7.0\NodeNetworkToolkit.pdb" target="lib\net7.0-windows7.0\NodeNetworkToolkit.pdb" />
|
||||
<file src="E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\NodeNetworkToolkit.dll" target="lib\net48\NodeNetworkToolkit.dll" />
|
||||
<file src="E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net7.0-windows7.0\NodeNetworkToolkit.dll" target="lib\net7.0-windows7.0\NodeNetworkToolkit.dll" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
|
||||
Binary file not shown.
@@ -0,0 +1,89 @@
|
||||
#pragma checksum "..\..\..\..\BreadcrumbBar\BreadcrumbBarView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8E255DB6093D94A718E821B78E34ED873EE35DC3"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.BreadcrumbBar {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// BreadcrumbBarView
|
||||
/// </summary>
|
||||
public partial class BreadcrumbBarView : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
|
||||
#line 8 "..\..\..\..\BreadcrumbBar\BreadcrumbBarView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.ListView list;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/breadcrumbbar/breadcrumbbarview.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\BreadcrumbBar\BreadcrumbBarView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.list = ((System.Windows.Controls.ListView)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#pragma checksum "..\..\..\..\BreadcrumbBar\BreadcrumbBarView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8E255DB6093D94A718E821B78E34ED873EE35DC3"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.BreadcrumbBar {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// BreadcrumbBarView
|
||||
/// </summary>
|
||||
public partial class BreadcrumbBarView : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
|
||||
#line 8 "..\..\..\..\BreadcrumbBar\BreadcrumbBarView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.ListView list;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/breadcrumbbar/breadcrumbbarview.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\BreadcrumbBar\BreadcrumbBarView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.list = ((System.Windows.Controls.ListView)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,135 @@
|
||||
#pragma checksum "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6AA246F30ABEA423818A4A835A95D99AA711C243"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NodeNetwork.Toolkit.ContextMenu;
|
||||
using NodeNetwork.ViewModels;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.ContextMenu {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// SearchableContextMenuView
|
||||
/// </summary>
|
||||
public partial class SearchableContextMenuView : System.Windows.Controls.ContextMenu, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
|
||||
#line 9 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal NodeNetwork.Toolkit.ContextMenu.SearchableContextMenuView self;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 23 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.MenuItem SearchMenuItem;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 25 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBox SearchTextBox;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 28 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Data.CollectionContainer CollectionContainer;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 30 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Data.CollectionContainer ContainerBelowSearch;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/contextmenu/searchablecontextmenuview.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.self = ((NodeNetwork.Toolkit.ContextMenu.SearchableContextMenuView)(target));
|
||||
return;
|
||||
case 2:
|
||||
this.SearchMenuItem = ((System.Windows.Controls.MenuItem)(target));
|
||||
return;
|
||||
case 3:
|
||||
this.SearchTextBox = ((System.Windows.Controls.TextBox)(target));
|
||||
return;
|
||||
case 4:
|
||||
this.CollectionContainer = ((System.Windows.Data.CollectionContainer)(target));
|
||||
return;
|
||||
case 5:
|
||||
this.ContainerBelowSearch = ((System.Windows.Data.CollectionContainer)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#pragma checksum "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6AA246F30ABEA423818A4A835A95D99AA711C243"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NodeNetwork.Toolkit.ContextMenu;
|
||||
using NodeNetwork.ViewModels;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.ContextMenu {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// SearchableContextMenuView
|
||||
/// </summary>
|
||||
public partial class SearchableContextMenuView : System.Windows.Controls.ContextMenu, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
|
||||
#line 9 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal NodeNetwork.Toolkit.ContextMenu.SearchableContextMenuView self;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 23 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.MenuItem SearchMenuItem;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 25 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBox SearchTextBox;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 28 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Data.CollectionContainer CollectionContainer;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 30 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Data.CollectionContainer ContainerBelowSearch;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/contextmenu/searchablecontextmenuview.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\ContextMenu\SearchableContextMenuView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.self = ((NodeNetwork.Toolkit.ContextMenu.SearchableContextMenuView)(target));
|
||||
return;
|
||||
case 2:
|
||||
this.SearchMenuItem = ((System.Windows.Controls.MenuItem)(target));
|
||||
return;
|
||||
case 3:
|
||||
this.SearchTextBox = ((System.Windows.Controls.TextBox)(target));
|
||||
return;
|
||||
case 4:
|
||||
this.CollectionContainer = ((System.Windows.Data.CollectionContainer)(target));
|
||||
return;
|
||||
case 5:
|
||||
this.ContainerBelowSearch = ((System.Windows.Data.CollectionContainer)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace XamlGeneratedNamespace {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// GeneratedInternalTypeHelper
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public sealed class GeneratedInternalTypeHelper : System.Windows.Markup.InternalTypeHelper {
|
||||
|
||||
/// <summary>
|
||||
/// CreateInstance
|
||||
/// </summary>
|
||||
protected override object CreateInstance(System.Type type, System.Globalization.CultureInfo culture) {
|
||||
return System.Activator.CreateInstance(type, ((System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic)
|
||||
| (System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.CreateInstance)), null, null, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GetPropertyValue
|
||||
/// </summary>
|
||||
protected override object GetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, System.Globalization.CultureInfo culture) {
|
||||
return propertyInfo.GetValue(target, System.Reflection.BindingFlags.Default, null, null, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SetPropertyValue
|
||||
/// </summary>
|
||||
protected override void SetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, object value, System.Globalization.CultureInfo culture) {
|
||||
propertyInfo.SetValue(target, value, System.Reflection.BindingFlags.Default, null, null, culture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CreateDelegate
|
||||
/// </summary>
|
||||
protected override System.Delegate CreateDelegate(System.Type delegateType, object target, string handler) {
|
||||
return ((System.Delegate)(target.GetType().InvokeMember("_CreateDelegate", (System.Reflection.BindingFlags.InvokeMethod
|
||||
| (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)), null, target, new object[] {
|
||||
delegateType,
|
||||
handler}, null)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AddEventHandler
|
||||
/// </summary>
|
||||
protected override void AddEventHandler(System.Reflection.EventInfo eventInfo, object target, System.Delegate handler) {
|
||||
eventInfo.AddEventHandler(target, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,90 @@
|
||||
#pragma checksum "..\..\..\..\..\Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4B843E318B237C6F5C72D4FF330303240DAA0C30"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.Group.AddEndpointDropPanel {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// AddEndpointDropPanelView
|
||||
/// </summary>
|
||||
public partial class AddEndpointDropPanelView : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
|
||||
#line 7 "..\..\..\..\..\Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal NodeNetwork.Toolkit.Group.AddEndpointDropPanel.AddEndpointDropPanelView Self;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/group/addendpointdroppanel/addendpointdroppanelview" +
|
||||
".xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\..\Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.Self = ((NodeNetwork.Toolkit.Group.AddEndpointDropPanel.AddEndpointDropPanelView)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#pragma checksum "..\..\..\..\..\Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4B843E318B237C6F5C72D4FF330303240DAA0C30"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.Group.AddEndpointDropPanel {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// AddEndpointDropPanelView
|
||||
/// </summary>
|
||||
public partial class AddEndpointDropPanelView : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector {
|
||||
|
||||
|
||||
#line 7 "..\..\..\..\..\Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal NodeNetwork.Toolkit.Group.AddEndpointDropPanel.AddEndpointDropPanelView Self;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/group/addendpointdroppanel/addendpointdroppanelview" +
|
||||
".xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\..\Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.Self = ((NodeNetwork.Toolkit.Group.AddEndpointDropPanel.AddEndpointDropPanelView)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,195 @@
|
||||
#pragma checksum "..\..\..\..\NodeList\NodeListView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "FD95BDD952CF5756320B0793E330657997B32353"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NodeNetwork.Views.Controls;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.NodeList {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// NodeListView
|
||||
/// </summary>
|
||||
public partial class NodeListView : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector, System.Windows.Markup.IStyleConnector {
|
||||
|
||||
|
||||
#line 10 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal NodeNetwork.Toolkit.NodeList.NodeListView self;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 72 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBlock titleLabel;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 73 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.ComboBox viewComboBox;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 76 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.Grid searchBoxGrid;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 77 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBox searchBox;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 78 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBlock emptySearchBoxMessage;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 83 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.ItemsControl elementsList;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 104 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBlock emptyMessage;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/nodelist/nodelistview.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.self = ((NodeNetwork.Toolkit.NodeList.NodeListView)(target));
|
||||
return;
|
||||
case 4:
|
||||
this.titleLabel = ((System.Windows.Controls.TextBlock)(target));
|
||||
return;
|
||||
case 5:
|
||||
this.viewComboBox = ((System.Windows.Controls.ComboBox)(target));
|
||||
return;
|
||||
case 6:
|
||||
this.searchBoxGrid = ((System.Windows.Controls.Grid)(target));
|
||||
return;
|
||||
case 7:
|
||||
this.searchBox = ((System.Windows.Controls.TextBox)(target));
|
||||
return;
|
||||
case 8:
|
||||
this.emptySearchBoxMessage = ((System.Windows.Controls.TextBlock)(target));
|
||||
return;
|
||||
case 9:
|
||||
this.elementsList = ((System.Windows.Controls.ItemsControl)(target));
|
||||
return;
|
||||
case 10:
|
||||
this.emptyMessage = ((System.Windows.Controls.TextBlock)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
void System.Windows.Markup.IStyleConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 2:
|
||||
|
||||
#line 19 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
((System.Windows.Controls.Grid)(target)).MouseMove += new System.Windows.Input.MouseEventHandler(this.OnNodeMouseMove);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
break;
|
||||
case 3:
|
||||
|
||||
#line 31 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
((System.Windows.Controls.Grid)(target)).MouseMove += new System.Windows.Input.MouseEventHandler(this.OnNodeMouseMove);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
#pragma checksum "..\..\..\..\NodeList\NodeListView.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "FD95BDD952CF5756320B0793E330657997B32353"
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using NodeNetwork.Views.Controls;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Automation;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Controls.Ribbon;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Ink;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Effects;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Media.Media3D;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Shell;
|
||||
|
||||
|
||||
namespace NodeNetwork.Toolkit.NodeList {
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// NodeListView
|
||||
/// </summary>
|
||||
public partial class NodeListView : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector, System.Windows.Markup.IStyleConnector {
|
||||
|
||||
|
||||
#line 10 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal NodeNetwork.Toolkit.NodeList.NodeListView self;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 72 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBlock titleLabel;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 73 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.ComboBox viewComboBox;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 76 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.Grid searchBoxGrid;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 77 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBox searchBox;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 78 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBlock emptySearchBoxMessage;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 83 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.ItemsControl elementsList;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
|
||||
#line 104 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
|
||||
internal System.Windows.Controls.TextBlock emptyMessage;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// InitializeComponent
|
||||
/// </summary>
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
public void InitializeComponent() {
|
||||
if (_contentLoaded) {
|
||||
return;
|
||||
}
|
||||
_contentLoaded = true;
|
||||
System.Uri resourceLocater = new System.Uri("/NodeNetworkToolkit;component/nodelist/nodelistview.xaml", System.UriKind.Relative);
|
||||
|
||||
#line 1 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
System.Windows.Application.LoadComponent(this, resourceLocater);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 1:
|
||||
this.self = ((NodeNetwork.Toolkit.NodeList.NodeListView)(target));
|
||||
return;
|
||||
case 4:
|
||||
this.titleLabel = ((System.Windows.Controls.TextBlock)(target));
|
||||
return;
|
||||
case 5:
|
||||
this.viewComboBox = ((System.Windows.Controls.ComboBox)(target));
|
||||
return;
|
||||
case 6:
|
||||
this.searchBoxGrid = ((System.Windows.Controls.Grid)(target));
|
||||
return;
|
||||
case 7:
|
||||
this.searchBox = ((System.Windows.Controls.TextBox)(target));
|
||||
return;
|
||||
case 8:
|
||||
this.emptySearchBoxMessage = ((System.Windows.Controls.TextBlock)(target));
|
||||
return;
|
||||
case 9:
|
||||
this.elementsList = ((System.Windows.Controls.ItemsControl)(target));
|
||||
return;
|
||||
case 10:
|
||||
this.emptyMessage = ((System.Windows.Controls.TextBlock)(target));
|
||||
return;
|
||||
}
|
||||
this._contentLoaded = true;
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "7.0.3.0")]
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
void System.Windows.Markup.IStyleConnector.Connect(int connectionId, object target) {
|
||||
switch (connectionId)
|
||||
{
|
||||
case 2:
|
||||
|
||||
#line 19 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
((System.Windows.Controls.Grid)(target)).MouseMove += new System.Windows.Input.MouseEventHandler(this.OnNodeMouseMove);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
break;
|
||||
case 3:
|
||||
|
||||
#line 31 "..\..\..\..\NodeList\NodeListView.xaml"
|
||||
((System.Windows.Controls.Grid)(target)).MouseMove += new System.Windows.Input.MouseEventHandler(this.OnNodeMouseMove);
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
is_global = true
|
||||
build_property.RootNamespace = NodeNetwork.Toolkit
|
||||
build_property.ProjectDir = E:\p4\bluflame\intromat\NodeNetworkToolkit\
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
4d60b4fb02d3e818c76aed6fc26f7d85578917d1
|
||||
@@ -0,0 +1,38 @@
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\NodeNetworkToolkit.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\NodeNetworkToolkit.pdb
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\DynamicData.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\log4net.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\Pharmacist.Common.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\ReactiveUI.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\ReactiveUI.Events.WPF.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\ReactiveUI.Wpf.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\Splat.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\Splat.Drawing.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.Buffers.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.Collections.Immutable.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.Memory.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.Numerics.Vectors.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.Reactive.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.Runtime.CompilerServices.Unsafe.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.Threading.Tasks.Extensions.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\System.ValueTuple.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\NodeNetwork.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\bin\Debug\net48\NodeNetwork.pdb
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit.csproj.AssemblyReference.cache
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\BreadcrumbBar\BreadcrumbBarView.baml
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\Group\AddEndpointDropPanel\AddEndpointDropPanelView.baml
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeList\NodeListView.baml
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\BreadcrumbBar\BreadcrumbBarView.g.cs
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\ContextMenu\SearchableContextMenuView.g.cs
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\Group\AddEndpointDropPanel\AddEndpointDropPanelView.g.cs
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeList\NodeListView.g.cs
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\GeneratedInternalTypeHelper.g.cs
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit_MarkupCompile.cache
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit_MarkupCompile.lref
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\ContextMenu\SearchableContextMenuView.baml
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit.g.resources
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit.csproj.CoreCompileInputs.cache
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit.csproj.CopyComplete
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit.dll
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit.pdb
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\NodeNetworkToolkit.GeneratedMSBuildEditorConfig.editorconfig
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
||||
NodeNetworkToolkit
|
||||
|
||||
|
||||
library
|
||||
C#
|
||||
.cs
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\
|
||||
NodeNetwork.Toolkit
|
||||
none
|
||||
false
|
||||
TRACE;DEBUG;NETFRAMEWORK;NET48;
|
||||
|
||||
4290141240
|
||||
|
||||
26-1670165176
|
||||
44735160913
|
||||
BreadcrumbBar\BreadcrumbBarView.xaml;ContextMenu\SearchableContextMenuView.xaml;Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml;NodeList\NodeListView.xaml;
|
||||
|
||||
False
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
NodeNetworkToolkit
|
||||
|
||||
|
||||
library
|
||||
C#
|
||||
.cs
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\
|
||||
NodeNetwork.Toolkit
|
||||
none
|
||||
false
|
||||
TRACE;DEBUG;NETFRAMEWORK;NET48;
|
||||
|
||||
4290141240
|
||||
|
||||
27-1943407535
|
||||
44735160913
|
||||
BreadcrumbBar\BreadcrumbBarView.xaml;ContextMenu\SearchableContextMenuView.xaml;Group\AddEndpointDropPanel\AddEndpointDropPanelView.xaml;NodeList\NodeListView.xaml;
|
||||
|
||||
False
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
E:\p4\bluflame\intromat\NodeNetworkToolkit\obj\Debug\net48\GeneratedInternalTypeHelper.g.cs
|
||||
|
||||
FE:\p4\bluflame\intromat\NodeNetworkToolkit\ContextMenu\SearchableContextMenuView.xaml;;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
is_global = true
|
||||
build_property.RootNamespace = NodeNetwork.Toolkit
|
||||
build_property.ProjectDir = E:\p4\bluflame\intromat\NodeNetworkToolkit\
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
is_global = true
|
||||
build_property.RootNamespace = NodeNetwork.Toolkit
|
||||
build_property.ProjectDir = E:\p4\bluflame\intromat\NodeNetworkToolkit\
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
is_global = true
|
||||
build_property.RootNamespace = NodeNetwork.Toolkit
|
||||
build_property.ProjectDir = E:\p4\bluflame\intromat\NodeNetworkToolkit\
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user