/// <summary> /// Serializes the specified component. /// </summary> /// <param name="component"></param> public void AddComponent(Component component) { Dictionary<string, object> properties = new Dictionary<string, object>(); component.Serialize(properties); string serialized = ComponentDataString.ConvertToString(properties, ","); m_builder.AppendLine(serialized); }
public ComponentUpdatedEventArgs(Component component, string previousData) { Component = component; PreviousData = previousData; }
public Connection(Component owner, ConnectionFlags flags, ConnectionDescription description) { Owner = owner; Flags = flags; Description = description; }
public static Component Create(string data) { // Load data data = data.Replace(",", "\r\n"); Dictionary<string, object> properties = ComponentDataString.ConvertToDictionary(data); // Find component description ComponentDescription description; if (properties.ContainsKey("@rid")) description = ComponentHelper.FindDescriptionByRuntimeID(int.Parse(properties["@rid"].ToString())); else if (properties.ContainsKey("@guid")) description = ComponentHelper.FindDescription(new Guid(properties["@guid"].ToString())); else description = ComponentHelper.FindDescription(properties["@type"].ToString()); Component newComponent = new Component(description); // Apply configuration if (properties.ContainsKey("@config")) { ComponentConfiguration configuration = description.Metadata.Configurations.FirstOrDefault(item => item.Name == properties["@config"].ToString()); if (configuration != null) { foreach (var setter in configuration.Setters) { if (!properties.ContainsKey(setter.Key)) properties.Add(setter.Key, setter.Value); else properties[setter.Key] = setter.Value; } } } // Load other properties newComponent.Deserialize(properties); newComponent.ResetConnections(); if (newComponent.Editor != null) newComponent.Editor.Update(); return newComponent; }
public Point Resolve(Component component) { ComponentPoint tempPoint = this; if (component.IsFlipped == true) tempPoint = Flip(component.Orientation == Orientation.Horizontal); double x = tempPoint.Offset.X; double y = tempPoint.Offset.Y; if (tempPoint.RelativeToX == ComponentPosition.Middle && component.Orientation == Orientation.Horizontal) x += component.Size / 2; else if (tempPoint.RelativeToY == ComponentPosition.Middle && component.Orientation == Orientation.Vertical) y += component.Size / 2; if (tempPoint.RelativeToX == ComponentPosition.End && component.Orientation == Orientation.Horizontal) x += component.Size; else if (tempPoint.RelativeToY == ComponentPosition.End && component.Orientation == Orientation.Vertical) y += component.Size; FlagOptions flags = ComponentHelper.ApplyFlags(component); if ((flags & FlagOptions.MiddleMustAlign) == FlagOptions.MiddleMustAlign) { if (component.Orientation == Orientation.Horizontal && tempPoint.RelativeToX == ComponentPosition.Middle) { if ((x - tempPoint.Offset.X) % ComponentHelper.GridSize != 0d) x += 5d; } else if (tempPoint.RelativeToY == ComponentPosition.Middle) { if ((y - tempPoint.Offset.Y) % ComponentHelper.GridSize != 0d) y += 5d; } } return new Point(x, y); }
void DocumentChanged() { if (Document == null) return; m_resizing = ComponentResizeMode.None; m_resizingComponent = null; this.Width = Document.Size.Width; this.Height = Document.Size.Height; RenderBackground(); foreach (CircuitDiagram.Elements.ICircuitElement element in Document.Elements) { m_elementVisuals.Add(element, new CircuitElementDrawingVisual(element)); AddVisualChild(m_elementVisuals[element]); AddLogicalChild(m_elementVisuals[element]); m_elementVisuals[element].UpdateVisual(); element.Updated += new EventHandler(Component_Updated); } }
public static Component Create(ComponentIdentifier identifier, Dictionary<string, object> data) { Component newComponent = new Component(identifier.Description); // Apply configuration if (identifier.Configuration != null) { foreach (var setter in identifier.Configuration.Setters) { if (!data.ContainsKey(setter.Key)) data.Add(setter.Key, setter.Value); else data[setter.Key] = setter.Value; } } // Load other properties newComponent.Deserialize(data); newComponent.ResetConnections(); if (newComponent.Editor != null) newComponent.Editor.Update(); return newComponent; }
public static IComponentEditor CreateEditor(Component component) { return new ComponentEditor(component); }
public ComponentEditor(Component component) { EditorControls = new Dictionary<ComponentProperty, object>(); ComponentUpdated += new ComponentUpdatedDelegate(ComponentEditor_ComponentUpdated); Component = component; ComponentProperty[] propertyInfo = component.Description.Properties; this.DataContext = component; Grid mainGrid = new Grid(); mainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star) }); mainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star) }); int i = 0; foreach (ComponentProperty info in component.Description.Properties) { mainGrid.RowDefinitions.Add(new RowDefinition() { Height = System.Windows.GridLength.Auto }); if (info.Type == PropertyType.Boolean) { CheckBox checkbox = new CheckBox(); checkbox.Content = info.DisplayName; checkbox.IsChecked = (bool)component.GetProperty(info).Value; checkbox.Margin = new Thickness(5d); checkbox.Tag = info; checkbox.SetValue(Grid.RowProperty, i); checkbox.SetValue(Grid.ColumnProperty, 0); checkbox.SetValue(Grid.ColumnSpanProperty, 2); checkbox.Checked += new System.Windows.RoutedEventHandler(BoolChanged); checkbox.Unchecked += new System.Windows.RoutedEventHandler(BoolChanged); mainGrid.Children.Add(checkbox); EditorControls.Add(info, checkbox); } else if (info.Type == PropertyType.Decimal) { Label label = new Label(); label.Content = info.DisplayName; label.SetValue(Grid.RowProperty, i); label.SetValue(Grid.ColumnProperty, 0); label.Margin = new Thickness(5d); mainGrid.Children.Add(label); TextBox textbox = new TextBox(); textbox.Tag = info; textbox.Text = component.GetProperty(info).ToString(); textbox.Margin = new Thickness(5d); textbox.SetValue(Grid.RowProperty, i); textbox.SetValue(Grid.ColumnProperty, 1); textbox.TextChanged += new TextChangedEventHandler(DoubleChanged); mainGrid.Children.Add(textbox); EditorControls.Add(info, textbox); } else if (info.Type == PropertyType.Integer) { Label label = new Label(); label.Content = info.DisplayName; label.SetValue(Grid.RowProperty, i); label.SetValue(Grid.ColumnProperty, 0); label.Margin = new Thickness(5d); mainGrid.Children.Add(label); TextBox textbox = new TextBox(); textbox.Margin = new Thickness(5d); textbox.SetValue(Grid.RowProperty, i); textbox.SetValue(Grid.ColumnProperty, 1); textbox.TextChanged += new TextChangedEventHandler(DoubleChanged); mainGrid.Children.Add(textbox); EditorControls.Add(info, textbox); } else if (info.Type == PropertyType.Enum) { Label label = new Label(); label.Content = info.DisplayName; label.SetValue(Grid.RowProperty, i); label.SetValue(Grid.ColumnProperty, 0); label.Margin = new Thickness(5d); mainGrid.Children.Add(label); ComboBox combobox = new ComboBox(); combobox.Margin = new Thickness(5d); combobox.Tag = info; foreach (string option in info.EnumOptions) combobox.Items.Add(option); combobox.SelectedItem = component.GetProperty(info); combobox.SetValue(Grid.RowProperty, i); combobox.SetValue(Grid.ColumnProperty, 1); combobox.SelectionChanged += new SelectionChangedEventHandler(EnumChanged); mainGrid.Children.Add(combobox); EditorControls.Add(info, combobox); } else if (info.Type == PropertyType.String) { Label label = new Label(); label.Content = info.DisplayName; label.SetValue(Grid.RowProperty, i); label.SetValue(Grid.ColumnProperty, 0); label.Margin = new Thickness(5d); mainGrid.Children.Add(label); TextBox textbox = new TextBox(); textbox.Margin = new Thickness(5d); textbox.Tag = info; textbox.Text = component.GetProperty(info).Value as string; textbox.TextChanged += new TextChangedEventHandler(StringChanged); textbox.SetValue(Grid.RowProperty, i); textbox.SetValue(Grid.ColumnProperty, 1); mainGrid.Children.Add(textbox); EditorControls.Add(info, textbox); } i++; } this.Content = mainGrid; this.Loaded += new RoutedEventHandler(AutomaticEditor_Loaded); // Set previous component data }
protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e) { base.OnMouseUp(e); m_movingMouse = false; if (m_resizing != ComponentResizeMode.None) { m_resizingComponent.ResetConnections(); m_resizingComponent.ApplyConnections(Document); DrawConnections(); UndoAction undoAction = new UndoAction(UndoCommand.ModifyComponents, "Move component", new Component[] { m_resizingComponent }); undoAction.AddData("before", m_undoManagerBeforeData); Dictionary<Component, string> afterDictionary = new Dictionary<Component, string>(1); afterDictionary.Add(m_resizingComponent, m_resizingComponent.SerializeToString()); undoAction.AddData("after", afterDictionary); UndoManager.AddAction(undoAction); m_undoManagerBeforeData = new Dictionary<Component, string>(); } m_resizing = ComponentResizeMode.None; this.Cursor = System.Windows.Input.Cursors.Arrow; m_resizingComponent = null; if (m_placingComponent) { Component newComponent = Component.Create(NewComponentData); ComponentHelper.SizeComponent(newComponent, m_mouseDownPos, e.GetPosition(this)); // Flip if necessary if (newComponent.Orientation == Orientation.Horizontal && newComponent.Description.CanFlip) { if (m_mouseDownPos.X > e.GetPosition(this).X) newComponent.IsFlipped = true; else newComponent.IsFlipped = false; } else if (newComponent.Description.CanFlip) { if (m_mouseDownPos.Y > e.GetPosition(this).Y) newComponent.IsFlipped = true; else newComponent.IsFlipped = false; } Document.Elements.Add(newComponent); newComponent.ApplyConnections(Document); DrawConnections(); m_placingComponent = false; UndoAction undoAction = new UndoAction(UndoCommand.AddComponents, "Add component", new Component[] { newComponent }); UndoManager.AddAction(undoAction); RemoveVisualChild(m_elementVisuals[m_tempComponent]); RemoveLogicalChild(m_elementVisuals[m_tempComponent]); m_elementVisuals.Remove(m_tempComponent); m_tempComponent = null; } else if (m_selectedComponents.Count > 0) { Dictionary<Component, string> afterData = new Dictionary<Component, string>(); foreach (Component component in m_selectedComponents) { string afterDataString = component.SerializeToString(); if (afterDataString == m_undoManagerBeforeData[component]) break; afterData.Add(component, afterDataString); } if (afterData.Count > 0) { UndoAction undoAction = new UndoAction(UndoCommand.ModifyComponents, "move", m_selectedComponents.ToArray()); undoAction.AddData("before", m_undoManagerBeforeData); undoAction.AddData("after", afterData); UndoManager.AddAction(undoAction); m_undoManagerBeforeData = new Dictionary<Component, string>(); } } else if (m_selectionBox) { using (DrawingContext dc = m_selectedVisual.RenderOpen()) { enclosingRect = Rect.Empty; VisualTreeHelper.HitTest(this, new HitTestFilterCallback(delegate(DependencyObject testObject) { if (testObject is CircuitElementDrawingVisual) return HitTestFilterBehavior.ContinueSkipChildren; else return HitTestFilterBehavior.ContinueSkipSelf; }), new HitTestResultCallback(delegate(HitTestResult result) { m_selectedComponents.Add((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component); if (result.VisualHit is CircuitElementDrawingVisual) { Rect rect = VisualTreeHelper.GetContentBounds(result.VisualHit as Visual); dc.PushTransform(new TranslateTransform((result.VisualHit as CircuitElementDrawingVisual).Offset.X, (result.VisualHit as CircuitElementDrawingVisual).Offset.Y)); dc.DrawRectangle(new SolidColorBrush(Color.FromArgb(100, 0, 0, 100)), null, rect); dc.Pop(); if (enclosingRect.IsEmpty) { rect.Offset((result.VisualHit as CircuitElementDrawingVisual).Offset.X, (result.VisualHit as CircuitElementDrawingVisual).Offset.Y); enclosingRect = rect; } else { rect.Offset((result.VisualHit as CircuitElementDrawingVisual).Offset.X, (result.VisualHit as CircuitElementDrawingVisual).Offset.Y); enclosingRect.Union(rect); } } return HitTestResultBehavior.Continue; }), new GeometryHitTestParameters(new RectangleGeometry(new Rect(m_mouseDownPos, e.GetPosition(this))))); dc.DrawRectangle(Brushes.Transparent, new Pen(Brushes.Black, 1d), enclosingRect); } m_selectionBox = false; } }
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) { base.OnMouseMove(e); if (m_resizing == ComponentResizeMode.None) this.Cursor = System.Windows.Input.Cursors.Arrow; if (m_selectedComponents.Count > 0 && m_movingMouse) { // Clear resize visual using (DrawingContext dc = m_resizeVisual.RenderOpen()) { } Point mousePos = e.GetPosition(this); Vector offsetDelta = new Vector(mousePos.X - m_mouseDownPos.X, mousePos.Y - m_mouseDownPos.Y); foreach (Component component in m_selectedComponents) { Vector newOffset = m_originalOffsets[component] + offsetDelta; // Keep within bounds if (newOffset.X + m_elementVisuals[component].ContentBounds.Left < 0) newOffset = new Vector(1 - m_elementVisuals[component].ContentBounds.Left, newOffset.Y); if (newOffset.Y + m_elementVisuals[component].ContentBounds.Top < 0) newOffset = new Vector(newOffset.X, 1 - m_elementVisuals[component].ContentBounds.Top); if (newOffset.X + m_elementVisuals[component].ContentBounds.Right > this.Width) newOffset = new Vector(this.Width - m_elementVisuals[component].ContentBounds.Right, newOffset.Y); if (newOffset.Y + m_elementVisuals[component].ContentBounds.Bottom > this.Height) newOffset = new Vector(newOffset.X, this.Height - m_elementVisuals[component].ContentBounds.Bottom); // Snap to grid if (Math.IEEERemainder(newOffset.X, 20d) != 0) newOffset.X = ComponentHelper.Snap(new Point(newOffset.X, newOffset.Y), ComponentHelper.GridSize).X; if (Math.IEEERemainder(newOffset.Y, 20d) != 0) newOffset.Y = ComponentHelper.Snap(new Point(newOffset.X, newOffset.Y), ComponentHelper.GridSize).Y; offsetDelta = newOffset - m_originalOffsets[component]; } // Update component positions foreach (Component component in m_selectedComponents) { (component as Component).Location = m_originalOffsets[component] + offsetDelta; m_elementVisuals[component].Offset = component.Location; } // update selection rect m_selectedVisual.Offset = m_originalSelectedVisualOffset + offsetDelta; if (enclosingRect != Rect.Empty) { enclosingRect.X = m_selectedVisual.Offset.X; enclosingRect.Y = m_selectedVisual.Offset.Y; } // update connections foreach (Component component in Document.Components) component.DisconnectConnections(); foreach (Component component in Document.Components) component.ApplyConnections(Document); DrawConnections(); } else if (m_placingComponent) { ComponentHelper.SizeComponent(m_tempComponent, m_mouseDownPos, e.GetPosition(this)); // Flip if necessary if (m_tempComponent.Orientation == Orientation.Horizontal && m_tempComponent.Description.CanFlip) { if (m_mouseDownPos.X > e.GetPosition(this).X) m_tempComponent.IsFlipped = true; else m_tempComponent.IsFlipped = false; } else if (m_tempComponent.Description.CanFlip) { if (m_mouseDownPos.Y > e.GetPosition(this).Y) m_tempComponent.IsFlipped = true; else m_tempComponent.IsFlipped = false; } m_elementVisuals[m_tempComponent].Offset = m_tempComponent.Location; m_elementVisuals[m_tempComponent].UpdateVisual(); } else if (m_selectionBox) { m_selectedComponents.Clear(); m_originalOffsets.Clear(); using (DrawingContext dc = m_selectedVisual.RenderOpen()) { VisualTreeHelper.HitTest(this, new HitTestFilterCallback(delegate(DependencyObject testObject) { if (testObject is CircuitElementDrawingVisual) return HitTestFilterBehavior.ContinueSkipChildren; else return HitTestFilterBehavior.ContinueSkipSelf; }), new HitTestResultCallback(delegate(HitTestResult result) { if (result.VisualHit is CircuitElementDrawingVisual) { Rect rect = VisualTreeHelper.GetContentBounds(result.VisualHit as Visual); dc.PushTransform(new TranslateTransform(((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component).Location.X, ((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component).Location.Y)); dc.DrawRectangle(new SolidColorBrush(Color.FromArgb(100, 0, 0, 100)), null, rect); dc.Pop(); } return HitTestResultBehavior.Continue; }), new GeometryHitTestParameters(new RectangleGeometry(new Rect(m_mouseDownPos, e.GetPosition(this))))); dc.DrawRectangle(Brushes.Transparent, new Pen(Brushes.Black, 1d), new Rect(m_mouseDownPos, e.GetPosition(this))); } } else if (m_resizing != ComponentResizeMode.None) { Point mousePos = e.GetPosition(this); if (m_resizing == ComponentResizeMode.Left) ComponentHelper.SizeComponent(m_resizingComponent, new Point(mousePos.X, m_resizingComponent.Location.Y), m_resizeComponentOriginalStartEnd); else if (m_resizing == ComponentResizeMode.Top) ComponentHelper.SizeComponent(m_resizingComponent, new Point(m_resizingComponent.Location.X, mousePos.Y), m_resizeComponentOriginalStartEnd); else if (m_resizing == ComponentResizeMode.Right) ComponentHelper.SizeComponent(m_resizingComponent, m_resizeComponentOriginalStartEnd, new Point(mousePos.X, m_resizingComponent.Location.Y)); else if (m_resizing == ComponentResizeMode.Bottom) ComponentHelper.SizeComponent(m_resizingComponent, m_resizeComponentOriginalStartEnd, new Point(m_resizingComponent.Location.X, mousePos.Y)); m_resizeVisual.Offset = m_resizingComponent.Location; using (DrawingContext dc = m_resizeVisual.RenderOpen()) { if (m_resizingComponent.Orientation == Orientation.Horizontal) { dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.X - 2d, m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d)); dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.Right - 4d, m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d)); } else { dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_elementVisuals[m_resizingComponent].ContentBounds.Y - 2d, 6d, 6d)); dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_elementVisuals[m_resizingComponent].ContentBounds.Bottom - 4d, 6d, 6d)); } } m_elementVisuals[m_resizingComponent].Offset = m_resizingComponent.Location; m_elementVisuals[m_resizingComponent].UpdateVisual(); DrawConnections(); } else if (m_selectedComponents.Count == 0 && NewComponentData == null) { bool foundHit = false; VisualTreeHelper.HitTest(this, new HitTestFilterCallback(delegate(DependencyObject testObject) { if (testObject is CircuitElementDrawingVisual) return HitTestFilterBehavior.ContinueSkipChildren; else return HitTestFilterBehavior.ContinueSkipSelf; }), new HitTestResultCallback(delegate(HitTestResult result) { if (result.VisualHit is CircuitElementDrawingVisual) { Point mousePos = e.GetPosition(this); ComponentInternalMousePos = new Point(mousePos.X - (result.VisualHit as CircuitElementDrawingVisual).Offset.X, mousePos.Y - (result.VisualHit as CircuitElementDrawingVisual).Offset.Y); using (DrawingContext dc = m_selectedVisual.RenderOpen()) { Pen stroke = new Pen(Brushes.Gray, 1d); //stroke.DashStyle = new DashStyle(new double[] { 2, 2 }, 0); Rect rect = VisualTreeHelper.GetContentBounds(result.VisualHit as Visual); dc.DrawRectangle(new SolidColorBrush(Color.FromArgb(100, 0, 0, 100)), stroke, Rect.Inflate(rect, new Size(2, 2))); } m_selectedVisual.Offset = (result.VisualHit as CircuitElementDrawingVisual).Offset; if (((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component).Description.CanResize) m_resizingComponent = (result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component; } foundHit = true; return HitTestResultBehavior.Stop; }), new PointHitTestParameters(e.GetPosition(this))); if (!foundHit) { // Clear selection box using (DrawingContext dc = m_selectedVisual.RenderOpen()) { } // Clear resize visual using (DrawingContext dc = m_resizeVisual.RenderOpen()) { } } else if (foundHit && m_resizingComponent != null) { // If only 1 component selected, can resize m_resizeVisual.Offset = m_resizingComponent.Location; using (DrawingContext dc = m_resizeVisual.RenderOpen()) { if (m_resizingComponent.Orientation == Orientation.Horizontal) { dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.X - 2d, m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d)); dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.Right - 4d, m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d)); } else { dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_elementVisuals[m_resizingComponent].ContentBounds.Y - 2d, 6d, 6d)); dc.DrawRectangle(Brushes.DarkBlue, null, new Rect(m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_elementVisuals[m_resizingComponent].ContentBounds.Bottom - 4d, 6d, 6d)); } } // Check if cursor should be changed to resizing Rect resizingRect1 = Rect.Empty; Rect resizingRect2 = Rect.Empty; if (m_resizingComponent != null && m_resizingComponent.Orientation == Orientation.Horizontal && m_resizingComponent.Description.CanResize) { // Resizing a horizontal component resizingRect1 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.X - 2d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d); resizingRect2 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.Right - 4d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d); } else if (m_resizingComponent != null && m_resizingComponent.Description.CanResize) { // Resizing a vertical component resizingRect1 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Y - 2d, 6d, 6d); resizingRect2 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Bottom - 4d, 6d, 6d); } Rect mouseRect = new Rect(e.GetPosition(this), new Size(1,1)); if (resizingRect1.IntersectsWith(mouseRect)) { if (m_resizingComponent.Orientation == Orientation.Horizontal) this.Cursor = System.Windows.Input.Cursors.SizeWE; else this.Cursor = System.Windows.Input.Cursors.SizeNS; } else if (resizingRect2.IntersectsWith(mouseRect)) { if (m_resizingComponent.Orientation == Orientation.Horizontal) this.Cursor = System.Windows.Input.Cursors.SizeWE; else this.Cursor = System.Windows.Input.Cursors.SizeNS; } } } }
protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) { base.OnMouseDown(e); Point mousePos = e.GetPosition(this); m_mouseDownPos = mousePos; Rect resizingRect1 = Rect.Empty; Rect resizingRect2 = Rect.Empty; if (m_resizingComponent != null && m_resizingComponent.Orientation == Orientation.Horizontal && m_resizingComponent.Description.CanResize) { // Resizing a horizontal component resizingRect1 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.X - 2d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d); resizingRect2 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.Right - 4d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Top + m_elementVisuals[m_resizingComponent].ContentBounds.Height / 2 - 3d, 6d, 6d); } else if (m_resizingComponent != null && m_resizingComponent.Description.CanResize) { // Resizing a vertical component resizingRect1 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Y - 2d, 6d, 6d); resizingRect2 = new Rect(m_resizingComponent.Location.X + m_elementVisuals[m_resizingComponent].ContentBounds.Left + m_elementVisuals[m_resizingComponent].ContentBounds.Width / 2 - 3d, m_resizingComponent.Location.Y + m_elementVisuals[m_resizingComponent].ContentBounds.Bottom - 4d, 6d, 6d); } if (NewComponentData == null && (resizingRect1.IntersectsWith(new Rect(mousePos, new Size(1, 1))) || resizingRect2.IntersectsWith(new Rect(mousePos, new Size(1, 1))))) { // Enter resizing mode m_undoManagerBeforeData[m_resizingComponent] = m_resizingComponent.SerializeToString(); if (resizingRect1.IntersectsWith(new Rect(mousePos, new Size(1, 1)))) { if (m_resizingComponent.Orientation == Orientation.Horizontal) { m_resizing = ComponentResizeMode.Left; m_resizeComponentOriginalStartEnd = new Point(m_resizingComponent.Location.X + m_resizingComponent.Size, m_resizingComponent.Location.Y); } else { m_resizing = ComponentResizeMode.Top; m_resizeComponentOriginalStartEnd = new Point(m_resizingComponent.Location.X, m_resizingComponent.Location.Y + m_resizingComponent.Size); } } else { if (m_resizingComponent.Orientation == Orientation.Horizontal) { m_resizing = ComponentResizeMode.Right; m_resizeComponentOriginalStartEnd = new Point(m_resizingComponent.Location.X, m_resizingComponent.Location.Y); } else { m_resizing = ComponentResizeMode.Bottom; m_resizeComponentOriginalStartEnd = new Point(m_resizingComponent.Location.X, m_resizingComponent.Location.Y); } } } else if (m_selectedComponents.Count == 0) { bool foundHit = false; if (NewComponentData == null) { // Check if user is selecting a component VisualTreeHelper.HitTest(this, new HitTestFilterCallback(delegate(DependencyObject testObject) { if (testObject is CircuitElementDrawingVisual) return HitTestFilterBehavior.ContinueSkipChildren; else return HitTestFilterBehavior.ContinueSkipSelf; }), new HitTestResultCallback(delegate(HitTestResult result) { if (result.VisualHit is CircuitElementDrawingVisual) { m_selectedComponents.Add((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component); m_undoManagerBeforeData.Add((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component, ((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component).SerializeToString()); m_originalOffsets.Add((result.VisualHit as CircuitElementDrawingVisual).CircuitElement as Component, (result.VisualHit as CircuitElementDrawingVisual).Offset); ComponentInternalMousePos = new Point(mousePos.X - m_selectedComponents[0].Location.X, mousePos.Y - m_selectedComponents[0].Location.Y); using (DrawingContext dc = m_selectedVisual.RenderOpen()) { Pen stroke = new Pen(Brushes.Gray, 1d); Rect rect = VisualTreeHelper.GetContentBounds(result.VisualHit as Visual); dc.DrawRectangle(new SolidColorBrush(Color.FromArgb(100, 0, 0, 100)), stroke, Rect.Inflate(rect, new Size(2, 2))); } m_selectedVisual.Offset = m_selectedComponents[0].Location; m_originalSelectedVisualOffset = m_selectedVisual.Offset; List<Component> removedItems = new List<Component>(); List<Component> addedItems = new List<Component>(); addedItems.Add(m_selectedComponents[0]); RaiseEvent(new SelectionChangedEventArgs(Selector.SelectionChangedEvent, removedItems, addedItems)); } foundHit = true; return HitTestResultBehavior.Stop; }), new PointHitTestParameters(e.GetPosition(this))); } m_movingMouse = foundHit; if (!foundHit) { if (NewComponentData != null) { m_placingComponent = true; m_tempComponent = Component.Create(NewComponentData); m_elementVisuals.Add(m_tempComponent, new CircuitElementDrawingVisual(m_tempComponent)); AddVisualChild(m_elementVisuals[m_tempComponent]); AddLogicalChild(m_elementVisuals[m_tempComponent]); ComponentHelper.SizeComponent(m_tempComponent, m_mouseDownPos, e.GetPosition(this)); m_elementVisuals[m_tempComponent].Offset = m_tempComponent.Location; m_elementVisuals[m_tempComponent].UpdateVisual(); } else { // Selection box m_originalOffsets.Clear(); m_selectedComponents.Clear(); m_selectedVisual.Offset = new Vector(); m_selectionBox = true; } } } else if (enclosingRect.IntersectsWith(new Rect(e.GetPosition(this), new Size(1, 1)))) { m_movingMouse = true; m_originalOffsets.Clear(); m_undoManagerBeforeData.Clear(); foreach (Component component in m_selectedComponents) { m_originalOffsets.Add(component, component.Location); m_undoManagerBeforeData.Add(component, component.SerializeToString()); } using (var dc = m_selectedVisual.RenderOpen()) dc.DrawRectangle(new SolidColorBrush(Color.FromArgb(100, 0, 0, 100)), new Pen(Brushes.Gray, 1d), new Rect(0, 0, enclosingRect.Width, enclosingRect.Height)); m_selectedVisual.Offset = new Vector(enclosingRect.X, enclosingRect.Y); m_originalSelectedVisualOffset = m_selectedVisual.Offset; } else { List<Component> removedItems = new List<Component>(m_selectedComponents); m_selectedComponents.Clear(); m_originalOffsets.Clear(); m_undoManagerBeforeData.Clear(); enclosingRect = Rect.Empty; using (DrawingContext dc = m_selectedVisual.RenderOpen()) { } RaiseEvent(new SelectionChangedEventArgs(Selector.SelectionChangedEvent, removedItems, new List<Component>())); } }
public void RedrawComponent(Component component) { if (m_elementVisuals.ContainsKey(component)) m_elementVisuals[component].UpdateVisual(); if (m_selectedComponents.Contains(component)) { if (m_elementVisuals[component].ContentBounds != Rect.Empty) { using (DrawingContext dc = m_selectedVisual.RenderOpen()) { Pen stroke = new Pen(Brushes.Gray, 1d); Rect rect = VisualTreeHelper.GetContentBounds(m_elementVisuals[component as ICircuitElement]); dc.DrawRectangle(new SolidColorBrush(Color.FromArgb(100, 0, 0, 100)), stroke, Rect.Inflate(rect, new Size(2, 2))); } } m_selectedVisual.Offset = component.Location; } }
public void DeleteComponentCommand(object sender, System.Windows.Input.ExecutedRoutedEventArgs e) { if (m_selectedComponents.Count > 0) { UndoAction undoAction = new UndoAction(UndoCommand.DeleteComponents, "delete", m_selectedComponents.ToArray()); UndoManager.AddAction(undoAction); foreach (Component component in m_selectedComponents) { Document.Elements.Remove(component); } m_selectedComponents.Clear(); foreach (Component component in Document.Components) component.DisconnectConnections(); foreach (Component component in Document.Components) component.ApplyConnections(Document); DrawConnections(); // Clear selection box using (DrawingContext dc = m_selectedVisual.RenderOpen()) { } // Clear resize visual using (DrawingContext dc = m_resizeVisual.RenderOpen()) { } } else if (m_resizingComponent != null) { UndoAction undoAction = new UndoAction(UndoCommand.DeleteComponents, "delete", new Component[] { m_resizingComponent }); UndoManager.AddAction(undoAction); Document.Elements.Remove(m_resizingComponent); m_resizingComponent = null; foreach (Component component in Document.Components) component.DisconnectConnections(); foreach (Component component in Document.Components) component.ApplyConnections(Document); DrawConnections(); // Clear selection box using (DrawingContext dc = m_selectedVisual.RenderOpen()) { } // Clear resize visual using (DrawingContext dc = m_resizeVisual.RenderOpen()) { } } }
public static FlagOptions ApplyFlags(Component component) { FlagOptions returnOptions = FlagOptions.None; foreach (Conditional<FlagOptions> option in component.Description.Flags) { if (option.Conditions.IsMet(component)) returnOptions |= option.Value; } return returnOptions; }
public static Component Create(ComponentDescription description, Dictionary<string, object> data) { Component newComponent = new Component(description); // Load other properties newComponent.Deserialize(data); newComponent.ResetConnections(); if (newComponent.Editor != null) newComponent.Editor.Update(); return newComponent; }
public static void SizeComponent(Component component, Point start, Point end) { // reverse points if necessary Point newStart = start; Point newEnd = end; bool switched = false; if (start.X < end.X) { newStart = end; newEnd = start; switched = true; } if (true) // snap to grid { if (Math.IEEERemainder(newStart.X, 20d) != 0) newStart.X = ComponentHelper.Snap(newStart, GridSize).X; if (Math.IEEERemainder(newStart.Y, 20d) != 0) newStart.Y = ComponentHelper.Snap(newStart, GridSize).Y; if (Math.IEEERemainder(newEnd.X, 20d) != 0) newEnd.X = ComponentHelper.Snap(newEnd, GridSize).X; if (Math.IEEERemainder(newEnd.Y, 20d) != 0) newEnd.Y = ComponentHelper.Snap(newEnd, GridSize).Y; } if (true) // snap to horizontal or vertical { double height = Math.Max(newStart.Y, newEnd.Y) - Math.Min(newStart.Y, newEnd.Y); double length = Math.Sqrt(Math.Pow(newEnd.X - newStart.X, 2d) + Math.Pow(newEnd.Y - newStart.Y, 2d)); double bearing = Math.Acos(height / length) * (180 / Math.PI); if (bearing <= 45 && switched) newStart.X = newEnd.X; else if (bearing <= 45 && !switched) newEnd.X = newStart.X; else if (bearing > 45 && switched) newStart.Y = newEnd.Y; else newEnd.Y = newStart.Y; } if (newStart.X > newEnd.X || newStart.Y > newEnd.Y) { component.Location = new Vector(newEnd.X, newEnd.Y); if (newStart.X == newEnd.X) { component.Size = newStart.Y - newEnd.Y; component.Orientation = Orientation.Vertical; } else { component.Size = newStart.X - newEnd.X; component.Orientation = Orientation.Horizontal; } } else { component.Location = new Vector(newStart.X, newStart.Y); if (newStart.X == newEnd.X) { component.Size = newEnd.Y - newStart.Y; component.Orientation = Orientation.Vertical; } else { component.Size = newEnd.X - newStart.X; component.Orientation = Orientation.Horizontal; } } FlagOptions flagOptions = ApplyFlags(component); if ((flagOptions & FlagOptions.HorizontalOnly) == FlagOptions.HorizontalOnly && component.Orientation == Orientation.Vertical) { component.Orientation = Orientation.Horizontal; component.Size = component.Description.MinSize; } else if ((flagOptions & FlagOptions.VerticalOnly) == FlagOptions.VerticalOnly && component.Orientation == Orientation.Horizontal) { component.Orientation = Orientation.Vertical; component.Size = component.Description.MinSize; } component.ImplementMinimumSize(GridSize); component.ImplementMinimumSize(component.Description.MinSize); component.ResetConnections(); }
public UniqueConnectionDescription(Component component, ConnectionDescription connectionDescription) { Component = component; ConnectionDescription = connectionDescription; }