/// <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;
 }
Exemple #3
0
 public Connection(Component owner, ConnectionFlags flags, ConnectionDescription description)
 {
     Owner = owner;
     Flags = flags;
     Description = description;
 }
Exemple #4
0
        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);
            }
        }
Exemple #7
0
        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;
        }
Exemple #16
0
        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;
 }