using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using NodeNetwork.Views;
using ReactiveUI;
namespace NodeNetwork.ViewModels
{
///
/// Viewmodel for a connection that is currently being build by the user.
///
public class PendingConnectionViewModel : ReactiveObject
{
static PendingConnectionViewModel()
{
NNViewRegistrar.AddRegistration(() => new PendingConnectionView(), typeof(IViewFor));
}
#region Logger
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#endregion
#region Parent
///
/// The network viewmodel that this connection is being build in.
///
public NetworkViewModel Parent { get; }
#endregion
#region Input
///
/// The node input viewmodel, if any, that is on one side of the connection.
/// Can be null.
///
public NodeInputViewModel Input
{
get => _input;
set => this.RaiseAndSetIfChanged(ref _input, value);
}
private NodeInputViewModel _input;
#endregion
#region InputIsLocked
///
/// If true, Input will not be changed.
/// This is used to mark Input as the starting point of the pending connection.
///
public bool InputIsLocked
{
get => _inputIsLocked;
set => this.RaiseAndSetIfChanged(ref _inputIsLocked, value);
}
private bool _inputIsLocked;
#endregion
#region Output
///
/// The node output viewmodel, if any, that is on one side of the connection.
/// Can be null.
///
public NodeOutputViewModel Output
{
get => _output;
set => this.RaiseAndSetIfChanged(ref _output, value);
}
private NodeOutputViewModel _output;
#endregion
#region OutputIsLocked
///
/// If true, Output will not be changed.
/// This is used to mark Output as the starting point of the pending connection.
///
public bool OutputIsLocked
{
get => _outputIsLocked;
set => this.RaiseAndSetIfChanged(ref _outputIsLocked, value);
}
private bool _outputIsLocked;
#endregion
#region LooseEndPoint
///
/// The current coordinates of the point where the pending connection ends on the loose side.
/// This value is used when the Input or Output is null.
///
public Point LooseEndPoint
{
get => _looseEndPoint;
set => this.RaiseAndSetIfChanged(ref _looseEndPoint, value);
}
private Point _looseEndPoint;
#endregion
#region BoundingBox
///
/// The rectangle that contains the entire connection view.
///
public Rect BoundingBox => _boundingBox.Value;
private readonly ObservableAsPropertyHelper _boundingBox;
#endregion
#region Validation
///
/// The validation of the current connection state.
/// If invalid, the connection will be displayed as such and an error message will be displayed.
/// The pending connection must be valid before it can be added to the network as a real connection.
///
public ConnectionValidationResult Validation
{
get => _validation;
set => this.RaiseAndSetIfChanged(ref _validation, value);
}
private ConnectionValidationResult _validation;
#endregion
public PendingConnectionViewModel(NetworkViewModel parent)
{
Parent = parent;
this.WhenAnyValue(vm => vm.Input, vm => vm.Output, vm => vm.LooseEndPoint)
.Select(_ =>
{
Point p1 = Output?.Port.CenterPoint ?? LooseEndPoint;
Point p2 = Input?.Port.CenterPoint ?? LooseEndPoint;
return new Rect(p1, p2);
}).ToProperty(this, vm => vm.BoundingBox, out _boundingBox);
}
}
}