Browse Source

More Progress on userstory 16

- Added Icons
- Started Connecting View to presenter
Martin Edlund 5 years ago
parent
commit
41f768e0c1

+ 8 - 8
SketchAssistant/SketchAssistantWPF/FileImporter.cs

@@ -15,7 +15,7 @@ namespace SketchAssistantWPF
         /// </summary>
         /// <param name="fileName">the path of the input file</param>
         /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
-        public Tuple<int, int, List<Line>> ParseISADInputFile(String fileName)
+        public Tuple<int, int, List<InternalLine>> ParseISADInputFile(String fileName)
         {
             return ParseISADInput(System.IO.File.ReadAllLines(fileName));
         }
@@ -25,7 +25,7 @@ namespace SketchAssistantWPF
         /// </summary>
         /// <param name="allLines">an array holding all lines of the input file</param>
         /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
-        private Tuple<int, int, List<Line>> ParseISADInput(String[] allLines)
+        private Tuple<int, int, List<InternalLine>> ParseISADInput(String[] allLines)
         {
 
             if (allLines.Length == 0)
@@ -42,9 +42,9 @@ namespace SketchAssistantWPF
             }
 
             Tuple<int, int> dimensions = ParseISADHeader(allLines);
-            List<Line> picture = ParseISADBody(allLines, dimensions.Item1, dimensions.Item2);
+            List<InternalLine> picture = ParseISADBody(allLines, dimensions.Item1, dimensions.Item2);
             
-            return new Tuple<int, int, List<Line>>(dimensions.Item1, dimensions.Item2, picture);
+            return new Tuple<int, int, List<InternalLine>>(dimensions.Item1, dimensions.Item2, picture);
         }
 
 
@@ -73,13 +73,13 @@ namespace SketchAssistantWPF
         /// </summary>
         /// <param name="allLines">the input file as an array of lines</param>
         /// <returns>the parsed picture as a list of lines</returns>
-        private List<Line> ParseISADBody(String[] allLines, int width, int height)
+        private List<InternalLine> ParseISADBody(String[] allLines, int width, int height)
         {
 
             String lineStartString = "line";
             String lineEndString = "endline";
 
-            List<Line> drawing = new List<Line>();
+            List<InternalLine> drawing = new List<InternalLine>();
 
             //number of the line currently being parsed, enumeration starting at 0, body starts at the third line, therefore lin number 2
             int i = 2;
@@ -117,7 +117,7 @@ namespace SketchAssistantWPF
                 //"parse" 'endline' token, syntax already checked at the beginning,  and start parsing next line
                 i++;
                 //add line to drawing
-                drawing.Add(new Line(newLine));
+                drawing.Add(new InternalLine(newLine));
                 //update lineStartPointer to the presumable start of the next line
                 lineStartPointer = i;
             }
@@ -135,7 +135,7 @@ namespace SketchAssistantWPF
         /// </summary>
         /// <param name="allLines">an array holding all lines of the input file</param>
         /// <returns>the width and height of the left canvas and the parsed picture as a list of lines</returns>
-        public Tuple<int, int, List<Line>> ParseISADInputForTesting(String[] allLines)
+        public Tuple<int, int, List<InternalLine>> ParseISADInputForTesting(String[] allLines)
         {
             return ParseISADInput(allLines);
         }

+ 21 - 9
SketchAssistant/SketchAssistantWPF/Line.cs → SketchAssistant/SketchAssistantWPF/InternalLine.cs

@@ -4,10 +4,11 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
+using System.Windows.Media;
 
 namespace SketchAssistantWPF
 {
-    public class Line
+    public class InternalLine
     {
         /// <summary>
         /// list saving all the points of the line in the order of the path from start to end point
@@ -21,15 +22,20 @@ namespace SketchAssistantWPF
         /// flag showing if this is only a temporary line
         /// </summary>
         private bool isTemporary;
+        /// <summary>
+        /// A collection of the original Points defining the line.
+        /// </summary>
+        private PointCollection pointColl;
 
         /// <summary>
         /// The constructor for lines which are only temporary.
         /// If you want nice lines use the other constructor.
         /// </summary>
         /// <param name="points">The points of the line</param>
-        public Line(List<Point> points)
+        public InternalLine(List<Point> points)
         {
             linePoints = new List<Point>(points);
+            pointColl = new PointCollection(linePoints);
             isTemporary = true;
         }
 
@@ -39,9 +45,10 @@ namespace SketchAssistantWPF
         /// </summary>
         /// <param name="points">The points of the line</param>
         /// <param name="id">The identifier of the line</param>
-        public Line(List<Point> points, int id)
+        public InternalLine(List<Point> points, int id)
         {
             linePoints = new List<Point>(points);
+            pointColl = new PointCollection(linePoints);
             identifier = id;
             CleanPoints();
             isTemporary = false;
@@ -67,6 +74,11 @@ namespace SketchAssistantWPF
             return identifier;
         }
 
+        public PointCollection GetPointCollection()
+        {
+            return pointColl;
+        }
+
         /// <summary>
         /// A function that takes a Graphics element and returns it with
         /// the line drawn on it.
@@ -98,12 +110,12 @@ namespace SketchAssistantWPF
                     if (currPoint.X >= 0 && currPoint.Y >= 0 &&
                         currPoint.X < boolMatrix.GetLength(0) && currPoint.Y < boolMatrix.GetLength(1))
                     {
-                        boolMatrix[currPoint.X, currPoint.Y] = true;
-                        if (listMatrix[currPoint.X, currPoint.Y] == null)
+                        boolMatrix[(int) currPoint.X, (int) currPoint.Y] = true;
+                        if (listMatrix[(int) currPoint.X, (int) currPoint.Y] == null)
                         {
-                            listMatrix[currPoint.X, currPoint.Y] = new HashSet<int>();
+                            listMatrix[(int) currPoint.X, (int) currPoint.Y] = new HashSet<int>();
                         }
-                        listMatrix[currPoint.X, currPoint.Y].Add(identifier);
+                        listMatrix[(int) currPoint.X, (int) currPoint.Y].Add(identifier);
                     }
                 }
             }
@@ -120,11 +132,11 @@ namespace SketchAssistantWPF
                 List<Point> tempList = new List<Point>();
                 //Since Point is non-nullable, we must ensure the nullPoints, 
                 //which we remove can not possibly be points of the original given line.
-                int nullValue = linePoints[0].X + 1;
+                int nullValue = (int) linePoints[0].X + 1;
                 //Fill the gaps between points
                 for (int i = 0; i < linePoints.Count - 1; i++)
                 {
-                    nullValue += linePoints[i + 1].X;
+                    nullValue += (int) linePoints[i + 1].X;
                     List<Point> partialList = GeometryCalculator.BresenhamLineAlgorithm(linePoints[i], linePoints[i + 1]);
                     tempList.AddRange(partialList);
                 }

+ 19 - 18
SketchAssistant/SketchAssistantWPF/MVP_Model.cs

@@ -93,13 +93,13 @@ namespace SketchAssistantWPF
         //Images
         Image leftImage;
 
-        List<Line> leftLineList;
+        List<InternalLine> leftLineList;
 
         Image rightImageWithoutOverlay;
 
         Image rightImageWithOverlay;
 
-        List<Tuple<bool, Line>> rightLineList;
+        List<Tuple<bool, InternalLine>> rightLineList;
 
         List<Point> currentLine;
 
@@ -110,7 +110,7 @@ namespace SketchAssistantWPF
             programPresenter = presenter;
             historyOfActions = new ActionHistory();
             //redrawAss = new RedrawAssistant();
-            rightLineList = new List<Tuple<bool, Line>>();
+            rightLineList = new List<Tuple<bool, InternalLine>>();
             overlayItems = new List<Tuple<bool, HashSet<Point>>>();
         }
 
@@ -139,6 +139,7 @@ namespace SketchAssistantWPF
                     + e.ToString() + "\n The Canvas will be set to match your window.");
                 newCanvas = new WriteableBitmap(leftImageBoxWidth, leftImageBoxHeight, 96, 96, PixelFormats.Bgra32, null);
             }
+            newCanvas.WritePixels()
             Graphics graph = Graphics.FromImage(image);
             graph.FillRectangle(Brushes.White, 0, 0, width + 10, height + 10);
             return image;
@@ -171,7 +172,7 @@ namespace SketchAssistantWPF
             var workingCanvas = GetEmptyCanvas(rightImageWithoutOverlay.Width, rightImageWithoutOverlay.Height);
             var workingGraph = Graphics.FromImage(workingCanvas);
             //Lines
-            foreach (Tuple<bool, Line> lineBoolTuple in rightLineList)
+            foreach (Tuple<bool, InternalLine> lineBoolTuple in rightLineList)
             {
                 if (lineBoolTuple.Item1)
                 {
@@ -181,7 +182,7 @@ namespace SketchAssistantWPF
             //The Line being currently drawn
             if (currentLine != null && currentLine.Count > 0 && inDrawingMode && mousePressed)
             {
-                var currLine = new Line(currentLine);
+                var currLine = new InternalLine(currentLine);
                 currLine.DrawLine(workingGraph);
             }
             rightImageWithoutOverlay = workingCanvas;
@@ -229,7 +230,7 @@ namespace SketchAssistantWPF
             {
                 if (lineId <= rightLineList.Count - 1 && lineId >= 0)
                 {
-                    rightLineList[lineId] = new Tuple<bool, Line>(shown, rightLineList[lineId].Item2);
+                    rightLineList[lineId] = new Tuple<bool, InternalLine>(shown, rightLineList[lineId].Item2);
                     changed = true;
                 }
             }
@@ -243,9 +244,9 @@ namespace SketchAssistantWPF
         {
             if (rightImageWithoutOverlay != null)
             {
-                isFilledMatrix = new bool[rightImageWithoutOverlay.Width, rightImageWithoutOverlay.Height];
-                linesMatrix = new HashSet<int>[rightImageWithoutOverlay.Width, rightImageWithoutOverlay.Height];
-                foreach (Tuple<bool, Line> lineTuple in rightLineList)
+                isFilledMatrix = new bool[(int) rightImageWithoutOverlay.Width, (int) rightImageWithoutOverlay.Height];
+                linesMatrix = new HashSet<int>[(int) rightImageWithoutOverlay.Width, (int) rightImageWithoutOverlay.Height];
+                foreach (Tuple<bool, InternalLine> lineTuple in rightLineList)
                 {
                     if (lineTuple.Item1)
                     {
@@ -270,9 +271,9 @@ namespace SketchAssistantWPF
             {
                 if (pnt.X >= 0 && pnt.Y >= 0 && pnt.X < rightImageWithoutOverlay.Width && pnt.Y < rightImageWithoutOverlay.Height)
                 {
-                    if (isFilledMatrix[pnt.X, pnt.Y])
+                    if (isFilledMatrix[(int) pnt.X, (int) pnt.Y])
                     {
-                        returnSet.UnionWith(linesMatrix[pnt.X, pnt.Y]);
+                        returnSet.UnionWith(linesMatrix[(int) pnt.X, (int) pnt.Y]);
                     }
                 }
             }
@@ -333,7 +334,7 @@ namespace SketchAssistantWPF
         /// <param name="width">The width of the left image.</param>
         /// <param name="height">The height of the left image.</param>
         /// <param name="listOfLines">The List of Lines to be displayed in the left image.</param>
-        public void SetLeftLineList(int width, int height, List<Line> listOfLines)
+        public void SetLeftLineList(int width, int height, List<InternalLine> listOfLines)
         {
             var workingCanvas = GetEmptyCanvas(width, height);
             var workingGraph = Graphics.FromImage(workingCanvas);
@@ -341,7 +342,7 @@ namespace SketchAssistantWPF
             //redrawAss = new RedrawAssistant(leftLineList);
             //overlayItems = redrawAss.Initialize(markerRadius);
             //Lines
-            foreach (Line line in leftLineList)
+            foreach (InternalLine line in leftLineList)
             {
                 line.DrawLine(workingGraph);
             }
@@ -349,7 +350,7 @@ namespace SketchAssistantWPF
             programPresenter.UpdateLeftImage(leftImage);
             //Set right image to same size as left image and delete linelist
             DrawEmptyCanvasRight();
-            rightLineList = new List<Tuple<bool, Line>>();
+            rightLineList = new List<Tuple<bool, InternalLine>>();
         }
 
         /// <summary>
@@ -473,8 +474,8 @@ namespace SketchAssistantWPF
             mousePressed = false;
             if (inDrawingMode && currentLine.Count > 0)
             {
-                Line newLine = new Line(currentLine, rightLineList.Count);
-                rightLineList.Add(new Tuple<bool, Line>(true, newLine));
+                InternalLine newLine = new InternalLine(currentLine, rightLineList.Count);
+                rightLineList.Add(new Tuple<bool, InternalLine>(true, newLine));
                 newLine.PopulateMatrixes(isFilledMatrix, linesMatrix);
                 programPresenter.PassLastActionTaken(historyOfActions.AddNewAction(new SketchAction(SketchAction.ActionType.Draw, newLine.GetID())));
                 if (leftImage != null)
@@ -500,7 +501,7 @@ namespace SketchAssistantWPF
             {
                 var rightGraph = Graphics.FromImage(rightImageWithoutOverlay);
                 currentLine.Add(currentCursorPosition);
-                Line drawline = new Line(currentLine);
+                InternalLine drawline = new InternalLine(currentLine);
                 drawline.DrawLine(rightGraph);
                 RedrawRightOverlay();
             }
@@ -516,7 +517,7 @@ namespace SketchAssistantWPF
                         programPresenter.PassLastActionTaken(historyOfActions.AddNewAction(new SketchAction(SketchAction.ActionType.Delete, linesToDelete)));
                         foreach (int lineID in linesToDelete)
                         {
-                            rightLineList[lineID] = new Tuple<bool, Line>(false, rightLineList[lineID].Item2);
+                            rightLineList[lineID] = new Tuple<bool, InternalLine>(false, rightLineList[lineID].Item2);
                         }
                         RepopulateDeletionMatrixes();
                         if (leftImage != null)

+ 4 - 4
SketchAssistant/SketchAssistantWPF/MVP_View.cs

@@ -43,16 +43,16 @@ namespace SketchAssistantWPF
         void SetToolStripButtonStatus(String buttonName, MainWindow.ButtonState state);
 
         /// <summary>
-        /// Displays an image in the left Picture box.
+        /// Displays a list of lines in the left Picture box.
         /// </summary>
         /// <param name="img">The new image.</param>
-        void DisplayInLeftPictureBox(Image img);
+        void DisplayInLeftPictureBox(List<Line> lineList);
 
         /// <summary>
-        /// Displays an image in the right Picture box.
+        /// Displays a list of lines in the right Picture box.
         /// </summary>
         /// <param name="img">The new image.</param>
-        void DisplayInRightPictureBox(Image img);
+        void DisplayInRightPictureBox(List<Line> lineList);
 
         /// <summary>
         /// shows the given info message in a popup and asks the user to aknowledge it

+ 132 - 31
SketchAssistant/SketchAssistantWPF/MainWindow.xaml

@@ -5,49 +5,150 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:SketchAssistantWPF"
         mc:Ignorable="d"
-        Title="MainWindow" Height="450" Width="800">
+        Title="Sketch Assistant" Height="612" Width="914" SizeChanged="Window_SizeChanged">
     <Grid>
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="auto"/>
             <ColumnDefinition Width="auto"/>
-            <ColumnDefinition Width="auto"/>
-            <ColumnDefinition Width="*"/>
-            <ColumnDefinition Width="auto"/>
+            <ColumnDefinition Width="450*"/>
+            <ColumnDefinition Width="5"/>
+            <ColumnDefinition Width="290*"/>
+            <ColumnDefinition Width="161*"/>
             <ColumnDefinition Width="auto"/>
             <ColumnDefinition Width="auto"/>
         </Grid.ColumnDefinitions>
         <Grid.RowDefinitions>
-            <RowDefinition Height="auto"/>
-            <RowDefinition Height="auto"/>
             <RowDefinition Height="auto"/>
             <RowDefinition Height="*"/>
             <RowDefinition Height="auto"/>
-            <RowDefinition Height="auto"/>
         </Grid.RowDefinitions>
-        <DockPanel Grid.Column="0" Grid.ColumnSpan="7">
-            <ToolBarTray DockPanel.Dock="Top">
-                <ToolBar x:Name="MenuToolbar" Grid.Column="0" Grid.ColumnSpan="4">
-                    <Menu>
-                        <MenuItem x:Name="LoadMenuButton" Header="Load">
-                            <MenuItem Header="Load SVG File"/>
-                        </MenuItem>
-                        <MenuItem x:Name="EditMenuButton" Header="Edit">
-                            <MenuItem Header="New Canvas"/>
-                            <MenuItem Header="Undo"/>
-                            <MenuItem Header="Redo"/>
-                        </MenuItem>
-                    </Menu>
-                </ToolBar>
-                <ToolBar x:Name="DrawingToolBar" Grid.Column="4" Grid.ColumnSpan="3">
-                    <Button x:Name="CanvasButton" Command="ApplicationCommands.New" ToolTip="Create a new Canvas" Content="New Canvas" Click="CanvasButton_Click" />
-                    <Button x:Name="DrawButton" Command="ApplicationCommands.New" ToolTip="Enter Drawing Mode" Content="Draw" Click="DrawButton_Click"/>
-                    <Button x:Name="DeleteButton" Command="ApplicationCommands.New" ToolTip="Enter Deletion Mode" Content="Delete" Click="DeleteButton_Click" />
-                    <Button x:Name="UndoButton" Command="ApplicationCommands.New" ToolTip="Undo the last action" Content="Undo" Click="UndoButton_Click" />
-                    <Button x:Name="RedoButton" Command="ApplicationCommands.New" ToolTip="Redo the last undone action" Content="Redo" Click="RedoButton_Click" />
-                </ToolBar>
-            </ToolBarTray>
+        <ToolBar x:Name="MenuToolbar" Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0">
+            <Menu>
+                <MenuItem x:Name="LoadMenuButton" Header="Load">
+                    <MenuItem Header="Load SVG File"/>
+                </MenuItem>
+                <MenuItem x:Name="EditMenuButton" Header="Edit">
+                    <MenuItem Header="New Canvas" Click="CanvasButton_Click"/>
+                    <MenuItem Header="Undo" Click="UndoButton_Click"/>
+                    <MenuItem Header="Redo" Click="RedoButton_Click"/>
+                </MenuItem>
+            </Menu>
+        </ToolBar>
+
+        <ToolBar x:Name="DrawingToolBar" Grid.Column="4" Grid.Row="0" Grid.ColumnSpan="2">
+            <Button x:Name="CanvasButton" ToolTip="Create a new Canvas" Click="CanvasButton_Click">
+                <Rectangle Width="30" Height="30">
+                    <Rectangle.Fill>
+                        <DrawingBrush>
+                            <DrawingBrush.Drawing>
+                                <DrawingGroup ClipGeometry="M0,0 V60 H60 V0 H0 Z">
+                                    <DrawingGroup Transform="1.0513,0,0,1.0513,-1.5376,-1.5376">
+                                        <GeometryDrawing Geometry="F1 M60,60z M0,0z M11.75,54.375L11.75,5.625 39.438,5.625 48.25,14.438 48.25,54.375 11.75,54.375z">
+                                            <GeometryDrawing.Pen>
+                                                <Pen Brush="#FFFFFFFF" Thickness="7.1343" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" />
+                                            </GeometryDrawing.Pen>
+                                        </GeometryDrawing>
+                                        <GeometryDrawing Brush="#FFFFFFFF" Geometry="F1 M60,60z M0,0z M11.75,54.375L11.75,5.625 39.438,5.625 48.25,14.438 48.25,54.375 11.75,54.375z">
+                                            <GeometryDrawing.Pen>
+                                                <Pen Brush="#FF000000" Thickness="2.3781" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" />
+                                            </GeometryDrawing.Pen>
+                                        </GeometryDrawing>
+                                        <GeometryDrawing Brush="#FF000000" Geometry="F1 M60,60z M0,0z M39.437,14.438L39.437,5.625 48.25,14.438 39.437,14.438z">
+                                            <GeometryDrawing.Pen>
+                                                <Pen Brush="#FF000000" Thickness="2.3781" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" />
+                                            </GeometryDrawing.Pen>
+                                        </GeometryDrawing>
+                                    </DrawingGroup>
+                                </DrawingGroup>
+                            </DrawingBrush.Drawing>
+                        </DrawingBrush>
+                    </Rectangle.Fill>
+                </Rectangle>
+            </Button>
+            <ToggleButton x:Name="DrawButton" ToolTip="Enter Drawing Mode" Click="DrawButton_Click">
+                <Rectangle Width="30" Height="30">
+                    <Rectangle.Fill>
+                        <DrawingBrush>
+                            <DrawingBrush.Drawing>
+                                <DrawingGroup>
+                                    <GeometryDrawing Brush="#FF000000" Geometry="F1 M485.219,485.22z M0,0z M467.476,146.438L446.031,167.893 317.35,39.23 338.795,17.773C362.484,-5.919,400.899,-5.919,424.59,17.773L467.476,60.67C491.133,84.349,491.133,122.748,467.476,146.438z M167.233,403.748C161.311,409.67 161.311,419.261 167.233,425.184 173.158,431.139 182.754,431.139 188.676,425.184L424.59,189.335 403.121,167.878 167.233,403.748z M60,296.54C54.075,302.467 54.075,312.054 60,317.98 65.922,323.903 75.518,323.903 81.443,317.98L317.35,82.113 295.914,60.67 60,296.54z M338.767,103.54L102.881,339.421C91.036,351.243 91.066,370.462 102.881,382.307 114.731,394.153 133.919,394.208 145.795,382.275L381.681,146.438 338.767,103.54z M145.734,446.572C138.481,439.31 134.985,430.107 133.684,420.624 130.601,421.1 127.496,421.543 124.324,421.543 108.122,421.543 92.905,415.21 81.443,403.748 69.981,392.257 63.673,377.061 63.673,360.861 63.673,357.907 64.116,355.028 64.532,352.158 54.729,350.823 45.668,346.529 38.56,339.421 37.878,338.744 37.643,337.825 37.022,337.083L0,485.216 147.748,448.23C147.097,447.637,146.36,447.193,145.734,446.572z" />
+                                </DrawingGroup>
+                            </DrawingBrush.Drawing>
+                        </DrawingBrush>
+                    </Rectangle.Fill>
+                </Rectangle>
+            </ToggleButton>
+            <ToggleButton x:Name="DeleteButton" ToolTip="Enter Deletion Mode" Click="DeleteButton_Click" >
+                <Rectangle Width="30" Height="30">
+                    <Rectangle.Fill>
+                        <DrawingBrush>
+                            <DrawingBrush.Drawing>
+                                <DrawingGroup ClipGeometry="M0,0 V512 H512 V0 H0 Z">
+                                    <GeometryDrawing Brush="#FF000000" Geometry="F1 M512,512z M0,0z M497.941,273.941C516.686,255.196,516.686,224.804,497.941,206.059L337.941,46.059C319.196,27.314,288.805,27.313,270.058,46.059L14.058,302.059C-4.68700000000001,320.804,-4.68700000000001,351.196,14.058,369.941L110.058,465.941A48.004,48.004,0,0,0,144,480L500,480C506.627,480,512,474.627,512,468L512,428C512,421.373,506.627,416,500,416L355.883,416 497.941,273.941z M195.314,211.314L332.687,348.687 265.373,416 150.628,416 70.628,336 195.314,211.314z" />
+                                </DrawingGroup>
+                            </DrawingBrush.Drawing>
+                        </DrawingBrush>
+                    </Rectangle.Fill>
+                </Rectangle>
+            </ToggleButton>
+            <Button x:Name="UndoButton" ToolTip="Undo the last action" Click="UndoButton_Click" >
+                <Rectangle Width="30" Height="30">
+                    <Rectangle.Fill>
+                        <DrawingBrush>
+                            <DrawingBrush.Drawing>
+                                <DrawingGroup ClipGeometry="M0,0 V60 H60 V0 H0 Z">
+                                    <GeometryDrawing Geometry="F1 M60,60z M0,0z M25.063,4.6882L9.445,20.1632 25.063,35.6012 25.063,25.9792C25.442,25.9292 25.778,25.7632 26.176,25.7632 33.176,25.7632 38.85,31.4742 38.85,38.4732 38.85,41.7872 37.521,44.7602 35.439,47.0182L43.733,55.3122C47.934,50.9322 50.555,45.0212 50.555,38.4732 50.555,25.0092 39.64,14.0592 26.176,14.0592 25.797,14.0592 25.437,14.1452 25.063,14.1672L25.063,4.68840000000001z">
+                                        <GeometryDrawing.Pen>
+                                            <Pen Brush="#FFFFFFFF" Thickness="8.125" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" />
+                                        </GeometryDrawing.Pen>
+                                    </GeometryDrawing>
+                                    <GeometryDrawing Brush="#FF000000" Geometry="F0 M60,60z M0,0z M25.063,4.6882L9.445,20.1632 25.063,35.6012 25.063,25.9792C25.442,25.9292 25.778,25.7632 26.176,25.7632 33.176,25.7632 38.85,31.4742 38.85,38.4732 38.85,41.7872 37.521,44.7602 35.439,47.0182L43.733,55.3122C47.934,50.9322 50.555,45.0212 50.555,38.4732 50.555,25.0092 39.64,14.0592 26.176,14.0592 25.797,14.0592 25.437,14.1452 25.063,14.1672L25.063,4.68840000000001z">
+                                        <GeometryDrawing.Pen>
+                                            <Pen Brush="#FF000000" Thickness="3.125" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" />
+                                        </GeometryDrawing.Pen>
+                                    </GeometryDrawing>
+                                </DrawingGroup>
+                            </DrawingBrush.Drawing>
+                        </DrawingBrush>
+                    </Rectangle.Fill>
+                </Rectangle>
+            </Button>
+            <Button x:Name="RedoButton" ToolTip="Redo the last undone action" Click="RedoButton_Click">
+                <Rectangle Width="30" Height="30">
+                    <Rectangle.Fill>
+                        <DrawingBrush>
+                            <DrawingBrush.Drawing>
+                                <DrawingGroup ClipGeometry="M0,0 V60 H60 V0 H0 Z">
+                                    <DrawingGroup Transform="-1,0,0,1,60,0">
+                                        <GeometryDrawing Geometry="F1 M60,60z M0,0z M25.063,4.6882L9.445,20.1632 25.063,35.6012 25.063,25.9792C25.442,25.9292 25.778,25.7632 26.176,25.7632 33.176,25.7632 38.85,31.4742 38.85,38.4732 38.85,41.7872 37.521,44.7602 35.439,47.0182L43.733,55.3122C47.934,50.9322 50.555,45.0212 50.555,38.4732 50.555,25.0092 39.64,14.0592 26.176,14.0592 25.797,14.0592 25.437,14.1452 25.063,14.1672L25.063,4.68840000000001z">
+                                            <GeometryDrawing.Pen>
+                                                <Pen Brush="#FFFFFFFF" Thickness="8.125" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" />
+                                            </GeometryDrawing.Pen>
+                                        </GeometryDrawing>
+                                        <GeometryDrawing Brush="#FF000000" Geometry="F0 M60,60z M0,0z M25.063,4.6882L9.445,20.1632 25.063,35.6012 25.063,25.9792C25.442,25.9292 25.778,25.7632 26.176,25.7632 33.176,25.7632 38.85,31.4742 38.85,38.4732 38.85,41.7872 37.521,44.7602 35.439,47.0182L43.733,55.3122C47.934,50.9322 50.555,45.0212 50.555,38.4732 50.555,25.0092 39.64,14.0592 26.176,14.0592 25.797,14.0592 25.437,14.1452 25.063,14.1672L25.063,4.68840000000001z">
+                                            <GeometryDrawing.Pen>
+                                                <Pen Brush="#FF000000" Thickness="3.125" StartLineCap="Round" EndLineCap="Round" LineJoin="Round" />
+                                            </GeometryDrawing.Pen>
+                                        </GeometryDrawing>
+                                    </DrawingGroup>
+                                </DrawingGroup>
+                            </DrawingBrush.Drawing>
+                        </DrawingBrush>
+                    </Rectangle.Fill>
+                </Rectangle>
+            </Button>
+        </ToolBar>
+        <Canvas Name="LeftCanvas" Background="SlateGray" Grid.Column="2" Grid.Row="1" Height="auto"/>
+
+        <Canvas Name="RightCanvas" Background="SlateGray" Grid.Column="4" Grid.Row="1" Height="auto"
+                    MouseDown="RightCanvas_MouseDown" MouseUp="RightCanvas_MouseUp" MouseMove="RightCanvas_MouseMove" Grid.ColumnSpan="2"/>
+
+        <DockPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="6">
+            <StatusBar DockPanel.Dock="Bottom" Name="StatusBar"  Background="LightGray">
+                <TextBox Name="LoadStatusBox" Text="nothing loaded" Background="LightGray"/>
+                <Separator/>
+                <TextBox Name="LastActionBox" Text="none" Background="LightGray"/>
+            </StatusBar>
         </DockPanel>
-        <Image Name="LeftImageBox"/>
-        <Image Name="RightImageBox" />
     </Grid>
 </Window>

+ 161 - 12
SketchAssistant/SketchAssistantWPF/MainWindow.xaml.cs

@@ -6,6 +6,7 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
 using System.Windows.Data;
 using System.Windows.Documents;
 using System.Windows.Input;
@@ -13,6 +14,7 @@ using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;
+using System.Windows.Threading;
 
 namespace SketchAssistantWPF
 {
@@ -25,6 +27,10 @@ namespace SketchAssistantWPF
         {
             InitializeComponent();
             ProgramPresenter = new MVP_Presenter(this);
+            //  DispatcherTimer setup
+            dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
+            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
+            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 33);
         }
 
         public enum ButtonState
@@ -34,6 +40,7 @@ namespace SketchAssistantWPF
             Active
         }
 
+        DispatcherTimer dispatcherTimer;
         /// <summary>
         /// Dialog to select a file.
         /// </summary>
@@ -41,7 +48,7 @@ namespace SketchAssistantWPF
         /// <summary>
         /// All Lines in the current session
         /// </summary>
-        List<Tuple<bool, Line>> rightLineList = new List<Tuple<bool, Line>>();
+        List<Tuple<bool, InternalLine>> rightLineList = new List<Tuple<bool, InternalLine>>();
         /// <summary>
         /// Queue for the cursorPositions
         /// </summary>
@@ -55,6 +62,11 @@ namespace SketchAssistantWPF
         /*** WINDOW SPECIFIC FUNCTIONS START HERE ***/
         /********************************************/
 
+        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+
+        }
+
         private void RedoButton_Click(object sender, RoutedEventArgs e)
         {
 
@@ -75,6 +87,21 @@ namespace SketchAssistantWPF
 
         }
 
+        private void RightCanvas_MouseDown(object sender, MouseButtonEventArgs e)
+        {
+
+        }
+
+        private void RightCanvas_MouseUp(object sender, MouseButtonEventArgs e)
+        {
+
+        }
+
+        private void RightCanvas_MouseMove(object sender, MouseEventArgs e)
+        {
+
+        }
+
         /// <summary>
         /// Button to create a new Canvas. Will create an empty image 
         /// which is the size of the left image, if there is one.
@@ -85,53 +112,175 @@ namespace SketchAssistantWPF
             ProgramPresenter.NewCanvas();
         }
 
+        /// <summary>
+        /// Ticks the Presenter.
+        /// </summary>
+        private void dispatcherTimer_Tick(object sender, EventArgs e)
+        {
+            ProgramPresenter.Tick();
+        }
+
         /*************************/
         /*** PRESENTER -> VIEW ***/
         /*************************/
 
-        public void DisplayInLeftPictureBox(Image img)
+        /// <summary>
+        /// Displays a list of lines in the left Picture box.
+        /// </summary>
+        /// <param name="img">The new image.</param>
+        public void DisplayInLeftPictureBox(List<InternalLine> lineList)
         {
-            throw new NotImplementedException();
+            foreach (InternalLine line in lineList)
+            {
+                Polyline newPolyLine = new Polyline();
+                newPolyLine.Stroke = Brushes.Black;
+                newPolyLine.Points = line.GetPointCollection();
+                LeftCanvas.Children.Add(newPolyLine);
+            }
         }
 
-        public void DisplayInRightPictureBox(Image img)
+        /// <summary>
+        /// Displays a list of lines in the right Picture box.
+        /// </summary>
+        /// <param name="img">The new image.</param>
+        public void DisplayInRightPictureBox(List<InternalLine> lineList)
         {
-            throw new NotImplementedException();
+            foreach (InternalLine line in lineList)
+            {
+                Polyline newPolyLine = new Polyline();
+                newPolyLine.Stroke = Brushes.Black;
+                newPolyLine.Points = line.GetPointCollection();
+                LeftCanvas.Children.Add(newPolyLine);
+            }
         }
 
+        /// <summary>
+        /// Enables the timer of the View, which will tick the Presenter.
+        /// </summary>
         public void EnableTimer()
         {
-            throw new NotImplementedException();
+            dispatcherTimer.Start();
         }
 
+        /// <summary>
+        /// A function that opens a file dialog and returns the filename.
+        /// </summary>
+        /// <param name="Filter">The filter that should be applied to the new Dialog.</param>
+        /// <returns>Returns the FileName and the SafeFileName if the user correctly selects a file, 
+        /// else returns a tuple with empty strigns</returns>
         public Tuple<string, string> openNewDialog(string Filter)
         {
-            throw new NotImplementedException();
+            openFileDialog.Filter = Filter;
+            if (openFileDialog.ShowDialog() == true)
+            {
+                return new Tuple<string, string>(openFileDialog.FileName, openFileDialog.SafeFileName);
+            }
+            else
+            {
+                return new Tuple<string, string>("", "");
+            }
         }
 
+        /// <summary>
+        /// Sets the contents of the last action taken indicator label.
+        /// </summary>
+        /// <param name="message">The new contents</param>
         public void SetLastActionTakenText(string message)
         {
-            throw new NotImplementedException();
+            LastActionBox.Text = message;
         }
 
+        /// <summary>
+        /// Changes the states of a tool strip button.
+        /// </summary>
+        /// <param name="buttonName">The name of the button.</param>
+        /// <param name="state">The new state of the button.</param>
         public void SetToolStripButtonStatus(string buttonName, MainWindow.ButtonState state)
         {
-            throw new NotImplementedException();
+            ButtonBase buttonToChange;
+            bool isToggleable = false;
+            switch (buttonName)
+            {
+                case "canvasButton":
+                    buttonToChange = CanvasButton;
+                    break;
+                case "drawButton":
+                    buttonToChange = DrawButton;
+                    isToggleable = true;
+                    break;
+                case "deleteButton":
+                    buttonToChange = DeleteButton;
+                    isToggleable = true;
+                    break;
+                case "undoButton":
+                    buttonToChange = UndoButton;
+                    break;
+                case "redoButton":
+                    buttonToChange = RedoButton;
+                    break;
+                default:
+                    Console.WriteLine("Invalid Button was given to SetToolStripButton. \nMaybe you forgot to add a case?");
+                    return;
+            }
+            if (isToggleable)
+            {
+                switch (state)
+                {
+                    case ButtonState.Active:
+                        ((ToggleButton)buttonToChange).IsEnabled = true;
+                        ((ToggleButton)buttonToChange).IsChecked = true;
+                        break;
+                    case ButtonState.Disabled:
+                        ((ToggleButton)buttonToChange).IsEnabled = false;
+                        ((ToggleButton)buttonToChange).IsChecked = false;
+                        break;
+                    case ButtonState.Enabled:
+                        ((ToggleButton)buttonToChange).IsEnabled = true;
+                        ((ToggleButton)buttonToChange).IsChecked = false;
+                        break;
+                }
+            }
+            else
+            {
+                switch (state)
+                {
+                    case ButtonState.Disabled:
+                        ((Button)buttonToChange).IsEnabled = false;
+                        break;
+                    default:
+                        ((Button)buttonToChange).IsEnabled = true;
+                        break;
+                }
+            }
         }
 
+        /// <summary>
+        /// Sets the contents of the load status indicator label.
+        /// </summary>
+        /// <param name="message">The new contents</param>
         public void SetToolStripLoadStatus(string message)
         {
-            throw new NotImplementedException();
+            LoadStatusBox.Text = message;
         }
 
+        /// <summary>
+        /// shows the given info message in a popup and asks the user to aknowledge it
+        /// </summary>
+        /// <param name="message">the message to show</param>
         public void ShowInfoMessage(string message)
         {
-            throw new NotImplementedException();
+            MessageBox.Show(message);
         }
 
+        /// <summary>
+        /// Shows a warning box with the given message (Yes/No Buttons)and returns true if the user aknowledges it.
+        /// </summary>
+        /// <param name="message">The message of the warning.</param>
+        /// <returns>True if the user confirms (Yes), negative if he doesn't (No)</returns>
         public bool ShowWarning(string message)
         {
-            throw new NotImplementedException();
+            MessageBoxResult result = MessageBox.Show(message, "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning);
+            return (result.Equals(MessageBoxResult.Yes));
         }
     }
 }

+ 18 - 26
SketchAssistant/SketchAssistantWPF/Properties/Resources.Designer.cs

@@ -8,10 +8,10 @@
 // </auto-generated>
 //------------------------------------------------------------------------------
 
-namespace SketchAssistantWPF.Properties
-{
-
-
+namespace SketchAssistantWPF.Properties {
+    using System;
+    
+    
     /// <summary>
     ///   A strongly-typed resource class, for looking up localized strings, etc.
     /// </summary>
@@ -19,51 +19,43 @@ namespace SketchAssistantWPF.Properties
     // class via a tool like ResGen or Visual Studio.
     // To add or remove a member, edit your .ResX file then rerun ResGen
     // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources
-    {
-
+    internal class Resources {
+        
         private static global::System.Resources.ResourceManager resourceMan;
-
+        
         private static global::System.Globalization.CultureInfo resourceCulture;
-
+        
         [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources()
-        {
+        internal Resources() {
         }
-
+        
         /// <summary>
         ///   Returns the cached ResourceManager instance used by this class.
         /// </summary>
         [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager
-        {
-            get
-            {
-                if ((resourceMan == null))
-                {
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
                     global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SketchAssistantWPF.Properties.Resources", typeof(Resources).Assembly);
                     resourceMan = temp;
                 }
                 return resourceMan;
             }
         }
-
+        
         /// <summary>
         ///   Overrides the current thread's CurrentUICulture property for all
         ///   resource lookups using this strongly typed resource class.
         /// </summary>
         [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture
-        {
-            get
-            {
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
                 return resourceCulture;
             }
-            set
-            {
+            set {
                 resourceCulture = value;
             }
         }

+ 8 - 5
SketchAssistant/SketchAssistantWPF/Properties/Resources.resx

@@ -46,7 +46,7 @@
     
     mimetype: application/x-microsoft.net.object.binary.base64
     value   : The object must be serialized with 
-            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
             : and then encoded with base64 encoding.
     
     mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
             : and then encoded with base64 encoding.
     -->
   <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
     <xsd:element name="root" msdata:IsDataSet="true">
       <xsd:complexType>
         <xsd:choice maxOccurs="unbounded">
@@ -68,9 +69,10 @@
               <xsd:sequence>
                 <xsd:element name="value" type="xsd:string" minOccurs="0" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="name" use="required" type="xsd:string" />
               <xsd:attribute name="type" type="xsd:string" />
               <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="assembly">
@@ -85,9 +87,10 @@
                 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
               </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
               <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
               <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
             </xsd:complexType>
           </xsd:element>
           <xsd:element name="resheader">
@@ -109,9 +112,9 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
 </root>

BIN
SketchAssistant/SketchAssistantWPF/Resources/NewCanvasIcon.ico


+ 5 - 1
SketchAssistant/SketchAssistantWPF/SketchAssistantWPF.csproj

@@ -37,6 +37,7 @@
   <ItemGroup>
     <Reference Include="System" />
     <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
     <Reference Include="System.Xml" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Core" />
@@ -68,7 +69,7 @@
       <DependentUpon>App.xaml</DependentUpon>
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="Line.cs" />
+    <Compile Include="InternalLine.cs" />
     <Compile Include="MainWindow.xaml.cs">
       <DependentUpon>MainWindow.xaml</DependentUpon>
       <SubType>Code</SubType>
@@ -103,5 +104,8 @@
   <ItemGroup>
     <None Include="App.config" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\NewCanvasIcon.ico" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>