/// <summary> /// Restore deleted objects /// </summary> public override void Undo(DrawingCanvas drawingCanvas) { // Insert all objects from cloneList to GraphicsList int currentIndex = 0; int indexToInsert; foreach (PropertiesGraphicsBase o in cloneList) { indexToInsert = indexes[currentIndex]; if ( indexToInsert >=0 && indexToInsert <= drawingCanvas.GraphicsList.Count ) // "<=" is correct ! { drawingCanvas.GraphicsList.Insert(indexToInsert, o.CreateGraphics()); } else { // Bug: we should not be here. // Add to the end anyway. drawingCanvas.GraphicsList.Add(o.CreateGraphics()); System.Diagnostics.Trace.WriteLine("CommandDelete.Undo - incorrect index"); } currentIndex++; } drawingCanvas.RefreshClip(); }
/// <summary> /// Delete objects again. /// </summary> public override void Redo(DrawingCanvas drawingCanvas) { // Delete from list all objects kept in cloneList. // Use object IDs for deleting, don't beleive to objects order. int n = drawingCanvas.GraphicsList.Count; for (int i = n - 1; i >= 0; i--) { bool toDelete = false; GraphicsBase currentObject = (GraphicsBase)drawingCanvas.GraphicsList[i]; foreach (PropertiesGraphicsBase o in cloneList) { if (o.ID == currentObject.Id) { toDelete = true; break; } } if (toDelete) { drawingCanvas.GraphicsList.RemoveAt(i); } } }
/// <summary> /// Apply new font family /// </summary> public static bool ApplyFontFamily(DrawingCanvas drawingCanvas, string value, bool addToHistory) { CommandChangeState command = new CommandChangeState(drawingCanvas); bool wasChange = false; foreach (GraphicsBase g in drawingCanvas.Selection) { GraphicsText gt = g as GraphicsText; if (gt != null) { if (gt.TextFontFamilyName != value) { gt.TextFontFamilyName = value; wasChange = true; } } } if (wasChange && addToHistory ) { command.NewState(drawingCanvas); drawingCanvas.AddCommandToHistory(command); } return wasChange; }
/// <summary> /// Add all deleted objects to GraphicsList /// </summary> public override void Undo(DrawingCanvas drawingCanvas) { foreach (PropertiesGraphicsBase o in cloneList) { drawingCanvas.GraphicsList.Add(o.CreateGraphics()); } drawingCanvas.RefreshClip(); }
/// <summary> /// Set cursor and resize new object. /// </summary> public override void OnMouseMove(DrawingCanvas drawingCanvas, MouseEventArgs e) { drawingCanvas.Cursor = ToolCursor; if (e.LeftButton == MouseButtonState.Pressed) { drawingCanvas[drawingCanvas.Count - 1].MoveHandleTo( e.GetPosition(drawingCanvas), 2); } }
/// <summary> /// Add change to history. /// Called after finishing moving/resizing. /// </summary> public void AddChangeToHistory(DrawingCanvas drawingCanvas) { if (commandChangeState != null && wasMove) { // Keep state after moving/resizing and add command to history commandChangeState.NewState(drawingCanvas); drawingCanvas.AddCommandToHistory(commandChangeState); commandChangeState = null; } }
// Create this command BEFORE applying Delete All function. public CommandDeleteAll(DrawingCanvas drawingCanvas) { cloneList = new List<PropertiesGraphicsBase>(); // Make clone of the whole list. foreach(GraphicsBase g in drawingCanvas.GraphicsList) { cloneList.Add(g.CreateSerializedObject()); } }
/// <summary> /// Add new object to drawing canvas. /// Function is called when user left-clicks drawing canvas, /// and one of ToolObject-derived tools is active. /// </summary> protected static void AddNewObject(DrawingCanvas drawingCanvas, GraphicsBase o) { HelperFunctions.UnselectAll(drawingCanvas); o.IsSelected = true; o.Clip = new RectangleGeometry(new Rect(0, 0, drawingCanvas.ActualWidth, drawingCanvas.ActualHeight)); drawingCanvas.GraphicsList.Add(o); drawingCanvas.CaptureMouse(); }
/// <summary> /// Add object again /// </summary> public override void Redo(DrawingCanvas drawingCanvas) { HelperFunctions.UnselectAll(drawingCanvas); // Create full object from the clone and add it to list drawingCanvas.GraphicsList.Add(newObjectClone.CreateGraphics()); // Object created from the clone doesn't contain clip information, // refresh it. drawingCanvas.RefreshClip(); }
/// <summary> /// Create new object /// </summary> public override void OnMouseDown(DrawingCanvas drawingCanvas, MouseButtonEventArgs e) { Point p = e.GetPosition(drawingCanvas); AddNewObject(drawingCanvas, new GraphicsLine( p, new Point(p.X + 1, p.Y + 1), drawingCanvas.LineWidth, drawingCanvas.ObjectColor, drawingCanvas.ActualScale)); }
/// <summary> /// Left mouse is released. /// New object is created and resized. /// </summary> public override void OnMouseUp(DrawingCanvas drawingCanvas, MouseButtonEventArgs e) { if (drawingCanvas.Count > 0) { drawingCanvas[drawingCanvas.Count - 1].Normalize(); drawingCanvas.AddCommandToHistory(new CommandAdd(drawingCanvas[drawingCanvas.Count - 1])); } drawingCanvas.Tool = ToolType.Pointer; drawingCanvas.Cursor = HelperFunctions.DefaultCursor; drawingCanvas.ReleaseMouseCapture(); }
List<int> indexes; // contains indexes of deleted items #endregion Fields #region Constructors // Create this command BEFORE applying Delete function. public CommandDelete(DrawingCanvas drawingCanvas) { cloneList = new List<PropertiesGraphicsBase>(); indexes = new List<int>(); // Make clone of the list selection. int currentIndex = 0; foreach (GraphicsBase g in drawingCanvas.Selection) { cloneList.Add(g.CreateSerializedObject()); indexes.Add(currentIndex); currentIndex++; } }
/// <summary> /// Create new object /// </summary> public override void OnMouseDown(DrawingCanvas drawingCanvas, MouseButtonEventArgs e) { Point p = e.GetPosition(drawingCanvas); newPolyLine = new GraphicsPolyLine( new Point[] { p, new Point(p.X + 1, p.Y + 1) }, drawingCanvas.LineWidth, drawingCanvas.ObjectColor, drawingCanvas.ActualScale); AddNewObject(drawingCanvas, newPolyLine); lastX = p.X; lastY = p.Y; }
/// <summary> /// Create textbox for in-place editing /// </summary> public void CreateTextBox(GraphicsText graphicsText, DrawingCanvas drawingCanvas) { graphicsText.IsSelected = false; // selection marks don't look good with textbox // Keep old text in the case Esc is pressed while editing oldText = graphicsText.Text; // Keep reference to edited object editedGraphicsText = graphicsText; textBox = new TextBox(); textBox.Width = graphicsText.Rectangle.Width; textBox.Height = graphicsText.Rectangle.Height; textBox.FontFamily = new FontFamily(graphicsText.TextFontFamilyName); textBox.FontSize = graphicsText.TextFontSize; textBox.FontStretch = graphicsText.TextFontStretch; textBox.FontStyle = graphicsText.TextFontStyle; textBox.FontWeight = graphicsText.TextFontWeight; textBox.Text = graphicsText.Text; textBox.AcceptsReturn = true; textBox.TextWrapping = TextWrapping.Wrap; drawingCanvas.Children.Add(textBox); Canvas.SetLeft(textBox, graphicsText.Rectangle.Left); Canvas.SetTop(textBox, graphicsText.Rectangle.Top); textBox.Width = textBox.Width; textBox.Height = textBox.Height; textBox.Focus(); textBox.LostFocus += new RoutedEventHandler(textBox_LostFocus); textBox.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(textBox_LostKeyboardFocus); textBox.PreviewKeyDown += new KeyEventHandler(textBox_PreviewKeyDown); textBox.ContextMenu = null; // see notes in textBox_LostKeyboardFocus // Initially textbox is set to the same rectangle as graphicsText. // After textbox loading its template is available, and we can // correct textbox position - see details in the textBox_Loaded function. textBox.Loaded += new RoutedEventHandler(textBox_Loaded); }
/// <summary> /// Set cursor and resize new polyline /// </summary> public override void OnMouseMove(DrawingCanvas drawingCanvas, MouseEventArgs e) { drawingCanvas.Cursor = ToolCursor; if (e.LeftButton != MouseButtonState.Pressed) { return; } if ( ! drawingCanvas.IsMouseCaptured ) { return; } if ( newPolyLine == null ) { return; // precaution } Point p = e.GetPosition(drawingCanvas); double distance = (p.X - lastX) * (p.X - lastX) + (p.Y - lastY) * (p.Y - lastY); double d = drawingCanvas.ActualScale <= 0 ? minDistance * minDistance : minDistance * minDistance / drawingCanvas.ActualScale; if ( distance < d) { // Distance between last two points is less than minimum - // move last point newPolyLine.MoveHandleTo(p, newPolyLine.HandleCount); } else { // Add new segment newPolyLine.AddPoint(p); lastX = p.X; lastY = p.Y; } }
/// <summary> /// Delete added object /// </summary> public override void Undo(DrawingCanvas drawingCanvas) { // Find object to delete by its ID. // Don't use objects order in the list. GraphicsBase objectToDelete = null; // Remove object from the list foreach(GraphicsBase b in drawingCanvas.GraphicsList) { if ( b.Id == newObjectClone.ID ) { objectToDelete = b; break; } } if ( objectToDelete != null ) { drawingCanvas.GraphicsList.Remove(objectToDelete); } }
/// <summary> /// Apply new color /// </summary> public static bool ApplyColor(DrawingCanvas drawingCanvas, Color value, bool addToHistory) { CommandChangeState command = new CommandChangeState(drawingCanvas); bool wasChange = false; foreach (GraphicsBase g in drawingCanvas.Selection) { if (g.ObjectColor != value) { g.ObjectColor = value; wasChange = true; } } if ( wasChange && addToHistory ) { command.NewState(drawingCanvas); drawingCanvas.AddCommandToHistory(command); } return wasChange; }
/// <summary> /// Detete All again /// </summary> public override void Redo(DrawingCanvas drawingCanvas) { drawingCanvas.GraphicsList.Clear(); }
/// <summary> /// Return true if currently active properties (line width, color etc.) /// can be applied to selected items. /// /// If at least one selected object has property different from currently /// active property value, properties can be applied. /// </summary> public static bool CanApplyProperties(DrawingCanvas drawingCanvas) { foreach(GraphicsBase graphicsBase in drawingCanvas.GraphicsList) { if ( ! graphicsBase.IsSelected ) { continue; } // ObjectColor - used in all graphics objects if ( graphicsBase.ObjectColor != drawingCanvas.ObjectColor ) { return true; } GraphicsText graphicsText = graphicsBase as GraphicsText; if ( graphicsText == null ) { // LineWidth - used in all objects except of GraphicsText if ( graphicsBase.LineWidth != drawingCanvas.LineWidth ) { return true; } } else { // Font - for GraphicsText if ( graphicsText.TextFontFamilyName != drawingCanvas.TextFontFamilyName ) { return true; } if ( graphicsText.TextFontSize != drawingCanvas.TextFontSize ) { return true; } if ( graphicsText.TextFontStretch != drawingCanvas.TextFontStretch ) { return true; } if ( graphicsText.TextFontStyle != drawingCanvas.TextFontStyle ) { return true; } if ( graphicsText.TextFontWeight != drawingCanvas.TextFontWeight ) { return true; } } } return false; }
/// <summary> /// Unselect all graphic objects /// </summary> public static void UnselectAll(DrawingCanvas drawingCanvas) { for (int i = 0; i < drawingCanvas.Count; i++) { drawingCanvas[i].IsSelected = false; } }
public abstract void OnMouseUp(DrawingCanvas drawingCanvas, MouseButtonEventArgs e);
public abstract void OnMouseMove(DrawingCanvas drawingCanvas, MouseEventArgs e);
public ToolText(DrawingCanvas drawingCanvas) { this.drawingCanvas = drawingCanvas; MemoryStream stream = new MemoryStream(DrawControl.Properties.Resources.Text); ToolCursor = new Cursor(stream); }
/// <summary> /// Left mouse is released. /// New object is created and resized. /// </summary> public override void OnMouseUp(DrawingCanvas drawingCanvas, MouseButtonEventArgs e) { drawingCanvas.Tool = ToolType.Pointer; drawingCanvas.Cursor = HelperFunctions.DefaultCursor; drawingCanvas.ReleaseMouseCapture(); if (drawingCanvas.Count > 0) { drawingCanvas[drawingCanvas.Count - 1].Normalize(); GraphicsText t = drawingCanvas[drawingCanvas.Count - 1] as GraphicsText; if ( t != null ) { // Create textbox for editing of graphics object which is just created CreateTextBox(t, drawingCanvas); } } // Commnnd will be added to History later, after closing // in-place textbox. }
/// <summary> /// Delete all graphic objects /// </summary> public static void DeleteAll(DrawingCanvas drawingCanvas) { if (drawingCanvas.GraphicsList.Count > 0 ) { drawingCanvas.AddCommandToHistory(new CommandDeleteAll(drawingCanvas)); drawingCanvas.GraphicsList.Clear(); } }
/// <summary> /// Delete selected graphic objects /// </summary> public static void DeleteSelection(DrawingCanvas drawingCanvas) { CommandDelete command = new CommandDelete(drawingCanvas); bool wasChange = false; for (int i = drawingCanvas.Count - 1; i >= 0; i--) { if ( drawingCanvas[i].IsSelected ) { drawingCanvas.GraphicsList.RemoveAt(i); wasChange = true; } } if ( wasChange ) { drawingCanvas.AddCommandToHistory(command); } }
/// <summary> /// Set cursor /// </summary> public override void SetCursor(DrawingCanvas drawingCanvas) { drawingCanvas.Cursor = this.toolCursor; }
public abstract void SetCursor(DrawingCanvas drawingCanvas);
/// <summary> /// Create new text object /// </summary> public override void OnMouseDown(DrawingCanvas drawingCanvas, MouseButtonEventArgs e) { Point p = e.GetPosition(drawingCanvas); AddNewObject(drawingCanvas, new GraphicsText( String.Empty, p.X, p.Y, p.X + 1, p.Y + 1, drawingCanvas.ObjectColor, drawingCanvas.TextFontSize, drawingCanvas.TextFontFamilyName, drawingCanvas.TextFontStyle, drawingCanvas.TextFontWeight, drawingCanvas.TextFontStretch, drawingCanvas.ActualScale)); }
/// <summary> /// Move selection to front /// </summary> public static void MoveSelectionToFront(DrawingCanvas drawingCanvas) { // Moving to front of z-order means moving // to the end of VisualCollection. // Read GraphicsList in the reverse order, and move every selected object // to temporary list. List<GraphicsBase> list = new List<GraphicsBase>(); CommandChangeOrder command = new CommandChangeOrder(drawingCanvas); for(int i = drawingCanvas.Count - 1; i >= 0; i--) { if ( drawingCanvas[i].IsSelected ) { list.Insert(0, drawingCanvas[i]); drawingCanvas.GraphicsList.RemoveAt(i); } } // Add all items from temporary list to the end of GraphicsList foreach(GraphicsBase g in list) { drawingCanvas.GraphicsList.Add(g); } if ( list.Count > 0 ) { command.NewState(drawingCanvas); drawingCanvas.AddCommandToHistory(command); } }