public ResultNodeViewModel(IMixerViewModel mixer = null, IInConnectorViewModel input = null) { this.mixer = mixer ?? Locator.Current.GetService <IMixerViewModel>(); this.input = input ?? Locator.Current.GetService <IInConnectorViewModel>(); this.input.Node = this; this.WhenActivated(disposables => { this // Handle the connection .WhenAnyValue(vm => vm.Input.ConnectedTo) .Select(i => i != null ? i.Node.Color : DefaultColor) .BindTo(this, vm => vm.Color) .DisposeWith(disposables); this // Handle the color .WhenAnyValue(vm => vm.Input.ConnectedTo.Node.Color) .Where(_ => Input?.ConnectedTo?.Node != null) // when a node is connected .BindTo(this, vm => vm.Color) .DisposeWith(disposables); }); }
public Node(IInteractionService interactions = null, IMixerViewModel mixer = null) { this.interactions = interactions ?? Locator.Current.GetService <IInteractionService>(); this.mixer = mixer ?? Locator.Current.GetService <IMixerViewModel>(); this.WhenActivated(disposables => { title = this // Color -> Title .WhenAnyValue(vm => vm.Color, c => $"R: {c.R} / G: {c.G} / B {c.B}") .ToProperty(this, vm => vm.Title) .DisposeWith(disposables); DeleteNodeCommand = ReactiveCommand.CreateFromTask(async() => { await this.interactions .DeleteNode .Handle(this); }, this.WhenAnyValue(vm => vm.mixer.IsNodeBeingAdded, vm => vm.mixer.ConnectingConnector, (a, b) => !a && b == null)) .DisposeWith(disposables); }); }
public InConnectorViewModel(IInteractionService interactions = null, IMixerViewModel mixer = null) { this.interactions = interactions ?? Locator.Current.GetService <IInteractionService>(); this.mixer = mixer ?? Locator.Current.GetService <IMixerViewModel>(); this.WhenActivated(disposables => { isEnabled = this // Disable when not connectable to .WhenAnyValue(vm => vm.mixer.ConnectingConnector) .Select(c => c == null || (c.Direction != Direction && c.Node != Node)) .ToProperty(this, vm => vm.IsEnabled) .DisposeWith(disposables); isConnected = this // ConectedTo -> IsConnected .WhenAnyValue(vm => vm.ConnectedTo) .Select(ct => ct != null) .ToProperty(this, vm => vm.IsConnected) .DisposeWith(disposables); ConnectorCommand = ReactiveCommand.CreateFromTask(async() => { ConnectedTo = await this.interactions .GetOutConnector .Handle(this); }, this.WhenAnyValue(vm => vm.mixer.IsNodeBeingAdded, b => !b)) .DisposeWith(disposables); }); }
public static async Task ShouldNotAddNode <TNode>(this IMixerViewModel mixer, IInteractionService interactions, INodeFactory nodeFactory, Func <IMixerViewModel, Task> command) where TNode : INode { // Arrange var isInvoked = false; interactions.GetNewNodePoint .RegisterHandler(i => { isInvoked = true; i.SetOutput(null); }); // Act mixer.Activator .Activate(); await command(mixer); // Assert isInvoked.Should().BeTrue(); nodeFactory.DidNotReceive().Create <TNode>(); mixer.Nodes.IsEmpty.Should().BeTrue(); }
public OperationNode() { kernel = new StandardKernel(); interactions = new InteractionService(); mixer = Substitute.For <IMixerViewModel, ReactiveObject>(); inputA = Substitute.For <IInConnectorViewModel, ReactiveObject>(); inputB = Substitute.For <IInConnectorViewModel, ReactiveObject>(); output = Substitute.For <IOutConnectorViewModel, ReactiveObject>(); kernel.Bind <IInteractionService>() .ToConstant(interactions); kernel.Bind <IMixerViewModel>() .ToConstant(mixer); kernel.Bind <IOutConnectorViewModel>() .ToConstant(output); kernel.Bind <IOperationNodeViewModel>() .To <OperationNodeViewModel>() .InSingletonScope() .WithConstructorArgument("inputA", inputA) .WithConstructorArgument("inputB", inputB); // system under test inputA.ConnectedTo = Arg.Do <IOutConnectorViewModel>( _ => inputA.RaisePropertyChanged(nameof(inputA.ConnectedTo))); inputB.ConnectedTo = Arg.Do <IOutConnectorViewModel>( _ => inputB.RaisePropertyChanged(nameof(inputB.ConnectedTo))); }
public OperationNodeViewModel(IInteractionService interactions = null, IMixerViewModel mixer = null, IInConnectorViewModel inputA = null, IInConnectorViewModel inputB = null, IOutConnectorViewModel output = null) { this.interactions = interactions ?? Locator.Current.GetService <IInteractionService>(); this.mixer = mixer ?? Locator.Current.GetService <IMixerViewModel>(); InputA = inputA ?? Locator.Current.GetService <IInConnectorViewModel>(); InputB = inputB ?? Locator.Current.GetService <IInConnectorViewModel>(); Output = output ?? Locator.Current.GetService <IOutConnectorViewModel>(); InputA.Node = this; InputB.Node = this; Output.Node = this; this.WhenActivated(disposables => { this // Handle the connections .WhenAnyValue(vm => vm.InputA.ConnectedTo, vm => vm.InputB.ConnectedTo, vm => vm.Operation, (a, b, op) => new { A = a, B = b, Op = op }) .Select(i => i.A != null && i.B != null ? Execute(i.A.Node.Color, i.B.Node.Color, i.Op) : DefaultColor) .BindTo(this, vm => vm.Color) .DisposeWith(disposables); this // Handle the color .WhenAnyValue(vm => vm.InputA.ConnectedTo.Node.Color, vm => vm.InputB.ConnectedTo.Node.Color, vm => vm.Operation, (a, b, op) => new { A = a, B = b, Op = op }) .Where(_ => InputA?.ConnectedTo?.Node != null && // when nodes are connected InputB?.ConnectedTo?.Node != null) .Select(i => Execute(i.A, i.B, i.Op)) .BindTo(this, vm => vm.Color) .DisposeWith(disposables); EditNodeCommand = ReactiveCommand.CreateFromTask(async() => { Operation = await this.interactions .GetNodeOperation .Handle(Operation); }, this.WhenAnyValue(vm => vm.mixer.IsNodeBeingAdded, vm => vm.mixer.ConnectingConnector, (a, b) => !a && b == null)) .DisposeWith(disposables); }); }
public NodeModel() { kernel = new StandardKernel(); interactions = new InteractionService(); mixer = Substitute.For <IMixerViewModel, ReactiveObject>(); kernel.Bind <IInteractionService>() .ToConstant(interactions); kernel.Bind <IMixerViewModel>() .ToConstant(mixer); kernel.Bind <INode>() .To <TestNode>(); // system under test }
public ColorNode() { kernel = new StandardKernel(); interactions = new InteractionService(); mixer = Substitute.For <IMixerViewModel, ReactiveObject>(); output = Substitute.For <IOutConnectorViewModel>(); kernel.Bind <IInteractionService>() .ToConstant(interactions); kernel.Bind <IMixerViewModel>() .ToConstant(mixer); kernel.Bind <IOutConnectorViewModel>() .ToConstant(output); kernel.Bind <IColorNodeViewModel>() .To <ColorNodeViewModel>() .InSingletonScope(); // system under test }
public InConnector() { kernel = new StandardKernel(); interactions = new InteractionService(); mixer = Substitute.For <IMixerViewModel, ReactiveObject>(); node = Substitute.For <INode>(); kernel.Bind <IInteractionService>() .ToConstant(interactions); kernel.Bind <IMixerViewModel>() .ToConstant(mixer); kernel.Bind <IInConnectorViewModel>() .To <InConnectorViewModel>() .WithPropertyValue(nameof(IInConnectorViewModel.Node), node); // system under test mixer.ConnectingConnector = Arg.Do <IConnector>( _ => mixer.RaisePropertyChanged(nameof(mixer.ConnectingConnector))); }
public static async Task ShouldAddNode <TNode>(this IMixerViewModel mixer, Point point, IInteractionService interactions, INodeFactory nodeFactory, Func <IMixerViewModel, Task> command) where TNode : INode { // Arrange var isInvoked = false; interactions.GetNewNodePoint .RegisterHandler(i => { isInvoked = true; i.SetOutput(point); }); // Act mixer.Activator .Activate(); await command(mixer); var node = mixer.Nodes.Single(); // Assert isInvoked.Should().BeTrue(); nodeFactory.Received().Create <TNode>(); node.Should().BeAssignableTo <TNode>(); node.X.Should().Be(point.X); node.Y.Should().Be(point.Y); }
public ColorNodeViewModel(IInteractionService interactions = null, IMixerViewModel mixer = null, IOutConnectorViewModel output = null) { this.interactions = interactions ?? Locator.Current.GetService <IInteractionService>(); this.mixer = mixer ?? Locator.Current.GetService <IMixerViewModel>(); this.output = output ?? Locator.Current.GetService <IOutConnectorViewModel>(); this.output.Node = this; this.WhenActivated(disposables => { EditNodeCommand = ReactiveCommand.CreateFromTask(async() => { Color = await this.interactions .GetNodeColor .Handle(Color); }, this.WhenAnyValue(vm => vm.mixer.IsNodeBeingAdded, vm => vm.mixer.ConnectingConnector, (a, b) => !a && b == null)) .DisposeWith(disposables); }); }
public ResultNode() { kernel = new StandardKernel(); interactions = new InteractionService(); mixer = Substitute.For <IMixerViewModel>(); input = Substitute.For <IInConnectorViewModel, ReactiveObject>(); kernel.Bind <IInteractionService>() .ToConstant(interactions); kernel.Bind <IMixerViewModel>() .ToConstant(mixer); kernel.Bind <IInConnectorViewModel>() .ToConstant(input); kernel.Bind <IResultNodeViewModel>() .To <ResultNodeViewModel>() .InSingletonScope(); // system under test input.ConnectedTo = Arg.Do <IOutConnectorViewModel>( _ => input.RaisePropertyChanged(nameof(input.ConnectedTo))); }
public OperationNodeView(IMixerViewModel mixer = null) { InitializeComponent(); this.mixer = mixer ?? Locator.Current.GetService <IMixerViewModel>(); IDisposable activation = null; activation = this.WhenActivated(disposables => { activation .DisposeWith(disposables); this // ViewModel -> DataContext .WhenAnyValue(v => v.ViewModel) .BindTo(this, v => v.DataContext) .DisposeWith(disposables); this // ViewModel.Title -> TitleTextBlock.Text .OneWayBind(ViewModel, vm => vm.Title, v => v.TitleTextBlock.Text) .DisposeWith(disposables); this // ViewModel.Width <-> Thumb.Width .Bind(ViewModel, vm => vm.Width, v => v.Thumb.Width) .DisposeWith(disposables); this // ViewModel.Height <-> Thumb.Height .Bind(ViewModel, vm => vm.Height, v => v.Thumb.Height) .DisposeWith(disposables); this // ViewModel.InputA -> InputAConnector.ViewModel .WhenAnyValue(v => v.ViewModel.InputA) .BindTo(this, v => v.InputAConnector.ViewModel) .DisposeWith(disposables); this // ViewModel.InputB -> InputBConnector.ViewModel .WhenAnyValue(v => v.ViewModel.InputB) .BindTo(this, v => v.InputBConnector.ViewModel) .DisposeWith(disposables); this // ViewModel.Output -> OutputConnector.ViewModel .WhenAnyValue(v => v.ViewModel.Output) .BindTo(this, v => v.OutputConnector.ViewModel) .DisposeWith(disposables); Thumb // Thumb.DragDelta.HorizontalChange -> ViewModel.X .Events() .DragDelta .Select(e => ViewModel.X + e.HorizontalChange) .BindTo(ViewModel, vm => vm.X) .DisposeWith(disposables); Thumb // Thumb.DragDelta.VerticalChange -> ViewModel.Y .Events() .DragDelta .Select(e => ViewModel.Y + e.VerticalChange) .BindTo(ViewModel, vm => vm.Y) .DisposeWith(disposables); this // ViewModel.EditNodeCommand -> EditNodeButton.Command .OneWayBind(ViewModel, vm => vm.EditNodeCommand, v => v.EditNodeButton.Command) .DisposeWith(disposables); this // ViewModel.DeleteNodeCommand -> DeleteNodeButton.Command .OneWayBind(ViewModel, vm => vm.DeleteNodeCommand, v => v.DeleteNodeButton.Command) .DisposeWith(disposables); this // Make Thumb click-through when a node or connection is being added .WhenAnyValue(v => v.mixer.IsNodeBeingAdded, v => v.mixer.ConnectingConnector, (a, b) => !a && b == null) .BindTo(this, v => v.Thumb.IsHitTestVisible) .DisposeWith(disposables); }); }
public TestNode(IInteractionService interactions, IMixerViewModel mixer) : base(interactions, mixer) { }