port from perforce

This commit is contained in:
2026-04-18 22:31:51 +02:00
commit 8d0ab5b7cc
8409 changed files with 3972376 additions and 0 deletions

View File

@@ -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>

View File

@@ -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);
});
}
}
}

View File

@@ -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);
}
}
}