Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions ControlsLibrary.Tests/SceneOperationsCancelTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using ControlsLibrary.Controls.Scene;
using ControlsLibrary.Controls.Scene.Commands;
using ControlsLibrary.ViewModel;
using GraphX.Controls;
using NUnit.Framework;
using System.Threading;

namespace ControlsLibrary.Tests
{
public class SceneOperationsCancelTests
{
[Test]
public void SceneUndoingandRedoingCreateVertexAndEdgeControlsCommands()
{
var newWindowThread = new Thread(new ThreadStart(() =>
{
var scene = new Scene();

var stack = new UndoRedoStack();
scene.UndoRedoStack = stack;

var graphArea = scene.GraphArea;

var firstNodeData = new NodeViewModel() { Name = "S1", IsInitial = false, IsFinal = false };
var firstVertexControl = new CustomVertexControl(firstNodeData);
var command = new CreateVertexCommand(graphArea, firstVertexControl);
command.Execute();
stack.AddCommand(command);

var secondNodeData = new NodeViewModel() { Name = "S2", IsInitial = false, IsFinal = false };
var secondVertexControl = new CustomVertexControl(secondNodeData);
command = new CreateVertexCommand(graphArea, secondVertexControl);
command.Execute();
stack.AddCommand(command);

var edgeData = new EdgeViewModel(firstNodeData, secondNodeData);
var edgeControl = new EdgeControl(firstVertexControl, secondVertexControl, edgeData);
var createEdgeCommand = new CreateEdgeCommand(graphArea, edgeControl);

stack.Undo();
Assert.False(graphArea.EdgesList.ContainsKey(edgeData));
Assert.False(graphArea.GetRelatedEdgeControls(firstVertexControl).Contains(edgeControl));
Assert.IsNull(edgeControl.Source);
Assert.IsNull(edgeControl.Target);
Assert.IsNull(edgeControl.Edge);

stack.Undo();
Assert.False(graphArea.VertexList.ContainsKey(secondNodeData));
Assert.True(graphArea.VertexList.ContainsKey(firstNodeData));

stack.Undo();
Assert.False(graphArea.VertexList.ContainsKey(secondNodeData));
Assert.False(graphArea.VertexList.ContainsKey(firstNodeData));

stack.Redo();
Assert.False(graphArea.VertexList.ContainsKey(secondNodeData));
Assert.True(graphArea.VertexList.ContainsKey(firstNodeData));

stack.Redo();

stack.Redo();
Assert.True(graphArea.EdgesList.ContainsKey(edgeData));
Assert.True(graphArea.GetRelatedEdgeControls(firstVertexControl).Contains(edgeControl));
Assert.AreEqual(edgeControl.Source, firstVertexControl);
Assert.AreEqual(edgeControl.Target, secondVertexControl);
Assert.AreEqual(edgeControl.Edge as EdgeViewModel, edgeData);

stack.Undo();
Assert.False(graphArea.EdgesList.ContainsKey(edgeData));
Assert.False(graphArea.GetRelatedEdgeControls(firstVertexControl).Contains(edgeControl));
Assert.IsNull(edgeControl.Source);
Assert.IsNull(edgeControl.Target);
Assert.IsNull(edgeControl.Edge);

// start the Dispatcher processing
System.Windows.Threading.Dispatcher.Run();
}));

// set the apartment state
newWindowThread.SetApartmentState(ApartmentState.STA);

// make the thread a background thread
newWindowThread.IsBackground = true;

// start the thread
newWindowThread.Start();
}

[Test]
public void SceneUndoingandRedoingRemoveVertexCommand()
{
var newWindowThread = new Thread(new ThreadStart(() =>
{
var scene = new Scene();

var stack = new UndoRedoStack();
scene.UndoRedoStack = stack;

var graphArea = scene.GraphArea;

var data = new NodeViewModel() { Name = "S", IsInitial = false, IsFinal = false };
var vertexControl = new CustomVertexControl(data);
var createCommand = new CreateVertexCommand(graphArea, vertexControl);
createCommand.Execute();
stack.AddCommand(createCommand);

var oldVertexRelatedControls = graphArea.GetRelatedControls(vertexControl);

var removeCommand = new RemoveVertexCommand(graphArea, vertexControl);
removeCommand.Execute();
stack.AddCommand(removeCommand);
Assert.False(graphArea.VertexList.ContainsKey(data));
Assert.False(graphArea.VertexList.Values.Contains(vertexControl));
Assert.IsNull(vertexControl.Vertex);

stack.Undo();
Assert.True(graphArea.VertexList.ContainsKey(data));
Assert.True(graphArea.VertexList.Values.Contains(vertexControl));
Assert.AreEqual(vertexControl.Vertex as NodeViewModel, data);

var newVertexRelatedControls = graphArea.GetRelatedControls(vertexControl);
Assert.AreEqual(oldVertexRelatedControls, newVertexRelatedControls);

stack.Redo();
Assert.False(graphArea.VertexList.ContainsKey(data));
Assert.False(graphArea.VertexList.Values.Contains(vertexControl));
Assert.IsNull(vertexControl.Vertex);

// start the Dispatcher processing
System.Windows.Threading.Dispatcher.Run();
}));

// set the apartment state
newWindowThread.SetApartmentState(ApartmentState.STA);

// make the thread a background thread
newWindowThread.IsBackground = true;

// start the thread
newWindowThread.Start();
}
}
}
29 changes: 29 additions & 0 deletions ControlsLibrary/Controls/Scene/AdornerSelectedArea.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace ControlsLibrary.Controls.Scene
{
public class AdornerSelectedArea : Adorner
{
private SolidColorBrush renderBrush;
private Pen renderPen;
public AdornerSelectedArea(UIElement adornedElement)
: base(adornedElement)
{
SelectedRect = new Rect(new Size(0, 0));
renderBrush = new SolidColorBrush(Colors.Blue);
renderBrush.Opacity = 0.2;
renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
}

public Rect SelectedRect { get; set; }

protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawRectangle(renderBrush, renderPen, SelectedRect);
}
}
}

36 changes: 36 additions & 0 deletions ControlsLibrary/Controls/Scene/Commands/CreateEdgeCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using ControlsLibrary.ViewModel;
using GraphX.Controls;

namespace ControlsLibrary.Controls.Scene.Commands
{
public class CreateEdgeCommand : ISceneCommand
{
private readonly GraphArea graphArea;
private EdgeControl edgeControl;

public CreateEdgeCommand(GraphArea graphArea, EdgeControl edgeControl)
{
this.graphArea = graphArea;
this.edgeControl = edgeControl;
}
public bool CanBeUndone => true;

public void Execute()
{
var data = edgeControl.Edge as EdgeViewModel;
var copy = new EdgeControl(edgeControl.Source,
edgeControl.Target, data);
graphArea.InsertEdgeAndData(data, edgeControl, 0, true);
ParallelEdgesProblemSolver.AvoidParallelEdges(graphArea, edgeControl);
edgeControl = copy;
//references to properties may be lost because of execution of Undo command or independent Remove- one
}

public void Undo()
{
var command = new RemoveEdgeCommand(graphArea, edgeControl);
command.Execute();
//the data isn't lost as far as it is preserved in Execute method of RemoveEdgeCommand
}
}
}
29 changes: 29 additions & 0 deletions ControlsLibrary/Controls/Scene/Commands/CreateVertexCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using ControlsLibrary.ViewModel;
using GraphX.Controls;
using System;

namespace ControlsLibrary.Controls.Scene.Commands
{
public class CreateVertexCommand : ISceneCommand
{
private readonly GraphArea graphArea;
private readonly CustomVertexControl vertexControl;
public CreateVertexCommand(GraphArea graphArea, CustomVertexControl vertexControl)
{
this.graphArea = graphArea;
this.vertexControl = vertexControl;
}

public bool CanBeUndone => true;
public void Execute()
{
graphArea.AddVertexAndData(vertexControl.Vertex as NodeViewModel, vertexControl, true);
}

public void Undo()
{
var command = new RemoveVertexCommand(graphArea, vertexControl);
command.Execute();
}
}
}
38 changes: 38 additions & 0 deletions ControlsLibrary/Controls/Scene/Commands/DragCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using GraphX.Controls;
using System.Collections.Generic;

namespace ControlsLibrary.Controls.Scene.Commands
{
public class DragCommand : ISceneCommand
{
private readonly GraphArea graphArea;
private readonly ICollection<CustomVertexControl> vertices;
private readonly double X_coordDiff;
private readonly double Y_coordDiff;

public DragCommand(GraphArea graphArea, ICollection<CustomVertexControl> vertices,
double X_coordDiff, double Y_coordDiff)
{
this.graphArea = graphArea;
this.vertices = vertices;
this.X_coordDiff = X_coordDiff;
this.Y_coordDiff = Y_coordDiff;
}
public bool CanBeUndone => true;

public void Execute()
{
foreach (var vc in vertices)
{
vc.SetPosition(vc.GetPosition().X + X_coordDiff, vc.GetPosition().Y + Y_coordDiff);
}
}

public void Undo()
{
var command = new DragCommand(graphArea, vertices, -X_coordDiff, -Y_coordDiff);
command.Execute();
}
}
}

50 changes: 50 additions & 0 deletions ControlsLibrary/Controls/Scene/Commands/EditEdgeCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using ControlsLibrary.ViewModel;
using System;
using System.Collections.Generic;

namespace ControlsLibrary.Controls.Scene.Commands
{
public class EditEdgeCommand : ISceneCommand
{
static Dictionary<string, Action<EdgeViewModel, object>> setProperty =
new Dictionary<string, Action<EdgeViewModel, object>>
{
{nameof(EdgeViewModel.IsEpsilon),
(edgeViewModel, value) => edgeViewModel.IsEpsilon = (bool)value },
{nameof(EdgeViewModel.IsExpanded),
(edgeViewModel, value) => edgeViewModel.IsExpanded = (bool)value },
{nameof(EdgeViewModel.TransitionTokensString),
(edgeViewModel, value) => edgeViewModel.TransitionTokensString = (string)value }
};

private readonly EdgeViewModel edgeViewModel;
private readonly string propertyName;
private readonly object oldValue;
private readonly object newValue;

public EditEdgeCommand(EdgeViewModel edgeViewModel, string propertyName, object oldValue, object newValue)
{
this.edgeViewModel = edgeViewModel;
this.propertyName = propertyName;
this.oldValue = oldValue;
this.newValue = newValue;
}

public bool CanBeUndone => true;

public void Execute()
{
try
{
setProperty[propertyName](edgeViewModel, newValue);
}
catch (InvalidCastException) { }
}

public void Undo()
{
var command = new EditEdgeCommand(edgeViewModel, propertyName, newValue, oldValue);
command.Execute();
}
}
}
51 changes: 51 additions & 0 deletions ControlsLibrary/Controls/Scene/Commands/EditVertexCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using ControlsLibrary.ViewModel;
using System;
using System.Collections.Generic;

namespace ControlsLibrary.Controls.Scene.Commands
{
public class EditVertexCommand
{
static Dictionary<string, Action<NodeViewModel, object>> setProperty =
new Dictionary<string, Action<NodeViewModel, object>>
{
{nameof(NodeViewModel.IsInitial),
(nodeViewModel, value) => nodeViewModel.IsInitial = (bool)value },
{nameof(NodeViewModel.IsFinal),
(nodeViewModel, value) => nodeViewModel.IsFinal = (bool)value },
{nameof(NodeViewModel.Name),
(nodeViewModel, value) => nodeViewModel.Name = (string)value }
};

private readonly NodeViewModel nodeViewModel;
private readonly string propertyName;
private readonly object oldValue;
private readonly object newValue;

public EditVertexCommand(NodeViewModel nodeViewModel, string propertyName, object oldValue, object newValue)
{
this.nodeViewModel = nodeViewModel;
this.propertyName = propertyName;
this.oldValue = oldValue;
this.newValue = newValue;
}

public bool CanBeUndone => true;

public void Execute()
{
try
{
setProperty[propertyName](nodeViewModel, newValue);
}
catch (InvalidCastException) { }
}

public void Undo()
{
var command = new EditVertexCommand(nodeViewModel, propertyName, newValue, oldValue);
command.Execute();
}
}
}

Loading