public IEnumerable <Circuit.Element> InRect(Circuit.Coord x1, Circuit.Coord x2)
 {
     Circuit.Coord a = new Circuit.Coord(Math.Min(x1.x, x2.x), Math.Min(x1.y, x2.y));
     Circuit.Coord b = new Circuit.Coord(Math.Max(x1.x, x2.x), Math.Max(x1.y, x2.y));
     return(Symbols.Where(i => i.Intersects(a, b)).Cast <Circuit.Element>().Concat(
                Wires.Where(i => i.Intersects(a, b))));
 }
Example #2
0
 public override void MouseUp(Circuit.Coord At)
 {
     b = At;
     Target.Select();
     if (a == b)
     {
         Circuit.Node node = Simulation.NodeAt(At);
         IEnumerable <Circuit.Element> at     = Target.AtPoint(a);
         IEnumerable <Circuit.Symbol>  probes = ProbesOf(at);
         if (!probes.Any() && node != null)
         {
             Probe probe = Simulation.Probes.FirstOrDefault(i => i.ConnectedTo == node);
             if (probe != null)
             {
                 // There's already a probe on this node, move the probe here.
                 ((Circuit.Symbol)probe.Tag).Position = a;
             }
             else
             {
                 // Make a new probe connected to this node.
                 probe = new Probe(Colors.ArgMin(i => Simulation.Probes.Count(j => j.Color == i)));
                 Target.Schematic.Add(new Circuit.Symbol(probe)
                 {
                     Position = a
                 });
             }
         }
         else
         {
             Target.Select(probes.FirstOrDefault());
         }
     }
 }
Example #3
0
 private static double Distance(Circuit.Coord x1, Circuit.Coord x2, Circuit.Coord p)
 {
     // TODO: This is wrong.
     return(Math.Min(
                Math.Min(Distance(p, x1), Distance(p, x2)),
                x1.y == x2.y ? Math.Abs(p.y - x1.y) : Math.Abs(p.x - x1.x)));
 }
Example #4
0
 private IEnumerable <Circuit.Wire> CoincidentWires(Circuit.Coord A, Circuit.Coord B)
 {
     return(Wires.Where(i =>
                        Circuit.Wire.PointOnLine(A, i.A, i.B) && Circuit.Wire.PointOnLine(B, i.A, i.B) && (
                            Circuit.Wire.PointOnSegment(A, i.A, i.B) || Circuit.Wire.PointOnSegment(B, i.A, i.B) ||
                            Circuit.Wire.PointOnSegment(i.A, A, B) || Circuit.Wire.PointOnSegment(i.B, A, B))));
 }
Example #5
0
 public override void MouseMove(Circuit.Coord At)
 {
     Circuit.Coord dx = At - x;
     if (dx.x != 0 || dx.y != 0)
         Editor.Edits.Do(new MoveElements(Target.Selected, dx));
     x = At;
 }
        // Mouse events.
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            Focus();
            Keyboard.Focus(this);
            Circuit.Coord at = SnapToGrid(e.GetPosition(root));
            if (e.ChangedButton == MouseButton.Left)
            {
                CaptureMouse();
                if (Tool != null)
                {
                    if (e.ClickCount == 2)
                    {
                        Tool.MouseDoubleClick(at);
                    }
                    else
                    {
                        Tool.MouseDown(at);
                    }
                }
            }
            else
            {
                ReleaseMouseCapture();
                if (Tool != null)
                {
                    Tool.Cancel();
                }
            }

            e.Handled = true;
        }
Example #7
0
 public override void MouseDown(Circuit.Coord At)
 {
     mouse = new List <Circuit.Coord>()
     {
         At
     };
     path.Visibility = Visibility.Visible;
 }
Example #8
0
 public override void MouseMove(Circuit.Coord At)
 {
     Circuit.Coord dx = At - x;
     if (dx.x != 0 || dx.y != 0)
     {
         Editor.Edits.Do(new MoveElements(Target.Selected, dx));
     }
     x = At;
 }
Example #9
0
        public override void MouseMove(Circuit.Coord At)
        {
            Circuit.Symbol symbol = overlay.Symbol;

            symbol.Position = At;

            // Don't allow symbols to be placed on an existing symbol.
            //Target.Cursor = Target.InRect(symbol.LowerBound, symbol.UpperBound).Any() ? Cursors.No : Cursors.None;
            overlay.Visibility = Visibility.Visible;
        }
 protected override void OnMouseLeave(MouseEventArgs e)
 {
     Circuit.Coord at = SnapToGrid(e.GetPosition(root));
     mouse = null;
     if (Tool != null)
     {
         Tool.MouseLeave(at);
     }
     e.Handled = true;
 }
Example #11
0
 public override void MouseUp(Circuit.Coord At)
 {
     b = At;
     if (a == b)
     {
         if (Clicked != null)
         {
             Clicked(RelevantOf(Target.AtPoint(a)));
         }
     }
 }
Example #12
0
        public override void MouseUp(Circuit.Coord At)
        {
            ((PathGeometry)path.Data).Clear();
            path.Visibility = Visibility.Hidden;
            Editor.AddWire(Editor.FindWirePath(mouse));
            mouse = null;

            if ((Keyboard.Modifiers & ModifierKeys.Control) == 0)
            {
                Target.Tool = new SelectionTool(Editor);
            }
        }
Example #13
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            Circuit.Coord center = (layout.LowerBound + layout.UpperBound) / 2;
            double        scale  = Math.Min(Math.Min(ActualWidth / layout.Width, ActualHeight / layout.Height), 1.0);

            Matrix transform = new Matrix();

            transform.Translate(-center.x, -center.y);
            transform.Scale(scale, -scale);
            transform.Translate(ActualWidth / 2, ActualHeight / 2);

            SymbolControl.DrawLayout(layout, drawingContext, transform, ShowText ? FontFamily : null, FontWeight, FontSize);
        }
Example #14
0
 public override void MouseDown(Circuit.Coord At)
 {
     if (Movable(At))
     {
         Target.Tool = new MoveTool(Editor, At);
     }
     else
     {
         a = b = At;
         ((RectangleGeometry)path.Data).Rect = new Rect(Target.ToPoint(a), Target.ToPoint(b));
         path.Visibility = Visibility.Visible;
     }
 }
Example #15
0
 public override void MouseMove(Circuit.Coord At)
 {
     b = At;
     if (path.Visibility != Visibility.Visible)
     {
         a             = b;
         Target.Cursor = Movable(At) ? Cursors.SizeAll : Cursors.Cross;
     }
     else
     {
         Vector dx = new Vector(-0.5, -0.5);
         ((RectangleGeometry)path.Data).Rect = new Rect(Target.ToPoint(a) + dx, Target.ToPoint(b) + dx);
     }
     Target.Highlight(a == b ? Target.AtPoint(a).Take(1) : Target.InRect(a, b));
 }
        private void ElementLayoutChanged(object sender, EventArgs e)
        {
            Circuit.Element element = (Circuit.Element)sender;
            Circuit.Coord   lb      = element.LowerBound;
            Circuit.Coord   ub      = element.UpperBound;

            ElementControl control = (ElementControl)element.Tag;

            Canvas.SetLeft(control, lb.x + origin.x);
            Canvas.SetTop(control, lb.y + origin.y);

            control.Width  = ub.x - lb.x;
            control.Height = ub.y - lb.y;

            control.InvalidateVisual();
        }
Example #17
0
 public override void MouseUp(Circuit.Coord At)
 {
     b = At;
     if (path.Visibility == Visibility.Visible)
     {
         if (a == b)
         {
             Target.ToggleSelect(Target.AtPoint(a).FirstOrDefault());
         }
         else
         {
             Target.Select(Target.InRect(a, b));
         }
         path.Visibility = Visibility.Hidden;
         Target.Cursor   = Movable(b) ? Cursors.SizeAll : Cursors.Cross;
     }
 }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            Point x = e.GetPosition(root);

            if (IsMouseCaptured)
            {
                BringIntoView(new Rect(x - AutoScrollBorder, x + AutoScrollBorder));
            }
            Circuit.Coord at = SnapToGrid(x);
            if (!mouse.HasValue || mouse.Value != at)
            {
                mouse = at;
                if (Tool != null)
                {
                    Tool.MouseMove(at);
                }
                e.Handled = true;
            }
        }
Example #19
0
        protected void OnMouseMove(object sender, MouseEventArgs e)
        {
            Point x = e.GetPosition(this);

            Matrix transform = Transform;

            foreach (Circuit.Terminal i in Symbol.Terminals)
            {
                Circuit.Coord tx = layout.MapTerminal(i);
                Point         tp = new Point(tx.x, tx.y);
                tp = transform.Transform(tp);
                if ((tp - x).Length < 5.0)
                {
                    ToolTip = "Terminal '" + i.ToString() + "'";
                    return;
                }
            }

            TextBlock text = new TextBlock();

            Circuit.Component component = Symbol.Component;

            text.Inlines.Add(new Bold(new Run(component.ToString())));

            foreach (PropertyInfo i in component.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(j =>
                                                                                                                            j.CustomAttribute <Circuit.Serialize>() != null &&
                                                                                                                            (j.CustomAttribute <BrowsableAttribute>() == null || j.CustomAttribute <BrowsableAttribute>().Browsable)))
            {
                object value = i.GetValue(component, null);
                DefaultValueAttribute def = i.CustomAttribute <DefaultValueAttribute>();
                if (def == null || !Equals(def.Value, value))
                {
                    System.ComponentModel.TypeConverter tc = System.ComponentModel.TypeDescriptor.GetConverter(i.PropertyType);
                    text.Inlines.Add(new Run("\n" + i.Name + " = "));
                    text.Inlines.Add(new Bold(new Run(tc.ConvertToString(value))));
                }
            }

            ToolTip = new ToolTip()
            {
                Content = text
            };
        }
Example #20
0
        public override ContextMenu BuildContextMenu(Circuit.Coord At)
        {
            Circuit.Element at = Target.AtPoint(At).FirstOrDefault();
            if (at != null && !((ElementControl)at.Tag).Selected)
            {
                Target.ToggleSelect(at);
            }

            ContextMenu menu = new ContextMenu();

            menu.Items.Add(new MenuItem()
            {
                Command = ApplicationCommands.SelectAll, CommandTarget = Target
            });
            menu.Items.Add(new Separator());
            menu.Items.Add(new MenuItem()
            {
                Command = ApplicationCommands.Cut, CommandTarget = Target
            });
            menu.Items.Add(new MenuItem()
            {
                Command = ApplicationCommands.Copy, CommandTarget = Target
            });
            menu.Items.Add(new MenuItem()
            {
                Command = ApplicationCommands.Paste, CommandTarget = Target
            });
            menu.Items.Add(new MenuItem()
            {
                Command = ApplicationCommands.Delete, CommandTarget = Target
            });
            menu.Items.Add(new Separator());
            menu.Items.Add(new MenuItem()
            {
                Command = ApplicationCommands.Undo, CommandTarget = Target
            });
            menu.Items.Add(new MenuItem()
            {
                Command = ApplicationCommands.Redo, CommandTarget = Target
            });
            return(menu);
        }
Example #21
0
        public override void MouseMove(Circuit.Coord At)
        {
            if (mouse == null)
            {
                return;
            }
            mouse.Add(At);
            List <Circuit.Coord> points = Editor.FindWirePath(mouse);

            ((PathGeometry)path.Data).Clear();
            for (int i = 0; i < points.Count - 1; ++i)
            {
                LineGeometry line = new LineGeometry()
                {
                    StartPoint = Target.ToPoint(points[i]) + new Vector(0.5, -0.5),
                    EndPoint   = Target.ToPoint(points[i + 1]) + new Vector(0.5, -0.5)
                };
                ((PathGeometry)path.Data).AddGeometry(line);
            }
        }
Example #22
0
        public override void MouseDown(Circuit.Coord At)
        {
            if (overlay.Visibility != Visibility.Visible)
            {
                return;
            }

            Circuit.Symbol S = new Circuit.Symbol(overlay.Component.Clone())
            {
                Position = overlay.Symbol.Position,
                Rotation = overlay.Symbol.Rotation,
                Flip     = overlay.Symbol.Flip,
            };
            Editor.Add(S);
            Editor.Select(S);

            overlay.Pen.Brush = Brushes.Black;
            if ((Keyboard.Modifiers & ModifierKeys.Control) == 0)
            {
                Target.Tool = new SelectionTool(Editor);
            }
        }
Example #23
0
        public List <Circuit.Coord> FindWirePath(List <Circuit.Coord> Mouse)
        {
            Circuit.Coord A = Mouse.First();
            Circuit.Coord B = Mouse.Last();

            // Candidate wire paths.
            List <List <Circuit.Coord> > Candidates = new List <List <Circuit.Coord> >()
            {
                new List <Circuit.Coord>()
                {
                    A, new Circuit.Coord(A.x, B.y), B
                },
                new List <Circuit.Coord>()
                {
                    A, new Circuit.Coord(B.x, A.y), B
                },
            };

            // Find the path with the minimum cost:
            // - Distance from mouse path.
            // - TODO: Avoids existing symbols?
            return(Candidates.ArgMin(i =>
            {
                double d = 0.0;
                foreach (Circuit.Coord j in Mouse)
                {
                    double dj = double.PositiveInfinity;
                    for (int k = 0; k < i.Count - 1; ++k)
                    {
                        Circuit.Coord a = i[k];
                        Circuit.Coord b = i[k + 1];

                        dj = Math.Min(dj, Distance(a, b, j));
                    }
                    d += dj;
                }
                return d;
            }));
        }
 protected override void OnMouseUp(MouseButtonEventArgs e)
 {
     Circuit.Coord at = SnapToGrid(e.GetPosition(root));
     if (e.ChangedButton == MouseButton.Left)
     {
         if (Tool != null)
         {
             Tool.MouseUp(at);
         }
         ReleaseMouseCapture();
     }
     else if (e.ChangedButton == MouseButton.Right && e.ClickCount == 1)
     {
         if (Tool != null)
         {
             ContextMenu = Tool.BuildContextMenu(at);
             if (ContextMenu != null)
             {
                 ContextMenu.IsOpen = true;
             }
         }
     }
     e.Handled = true;
 }
        public SimulationSchematic(Circuit.Schematic Schematic) : base(Schematic)
        {
            InitializeComponent();

            CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, Delete_Executed, Delete_CanExecute));
            CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, SelectAll_Executed, SelectAll_CanExecute));

            Focusable = true;
            Cursor    = Cursors.Cross;

            Tool = new ProbeTool(this);

            int pad   = Grid * 2;
            int align = Grid * 10;

            Circuit.Coord lb = Schematic.LowerBound;
            Circuit.Coord ub = Schematic.UpperBound;
            lb = Floor(lb - pad, align);
            ub = Ceiling(ub + pad, align);

            Width  = ub.x - lb.x;
            Height = ub.y - lb.y;
            Origin = -lb;
        }
Example #26
0
 public override void MouseDown(Circuit.Coord At)
 {
     a = b = At;
 }
Example #27
0
 public override void MouseUp(Circuit.Coord At)
 {
     Target.Tool = new SelectionTool(Editor);
 }
Example #28
0
 public MoveTool(SchematicEditor Target, Circuit.Coord At)
     : base(Target)
 {
     x = At;
 }
Example #29
0
 public virtual void MouseLeave(Circuit.Coord At)
 {
 }
Example #30
0
 public virtual void MouseEnter(Circuit.Coord At)
 {
 }
Example #31
0
 public virtual void MouseUp(Circuit.Coord At)
 {
 }
Example #32
0
 public virtual void MouseDown(Circuit.Coord At)
 {
 }
 public IEnumerable<Circuit.Element> InRect(Circuit.Coord x1, Circuit.Coord x2)
 {
     Circuit.Coord a = new Circuit.Coord(Math.Min(x1.x, x2.x), Math.Min(x1.y, x2.y));
     Circuit.Coord b = new Circuit.Coord(Math.Max(x1.x, x2.x), Math.Max(x1.y, x2.y));
     return Symbols.Where(i => i.Intersects(a, b)).Cast<Circuit.Element>().Concat(
         Wires.Where(i => i.Intersects(a, b)));
 }
Example #34
0
        public void AddWire(Circuit.Coord A, Circuit.Coord B)
        {
            if (A == B) return;

            Debug.Assert(A.x == B.x || A.y == B.y);

            Edits.BeginEditGroup();

            // Find all of the wires that are parallel and overlapping this wire.
            List<Circuit.Wire> overlapping = CoincidentWires(A, B).ToList();
            bool selected = overlapping.Any(i => ((WireControl)i.Tag).Selected);

            Circuit.Coord a = new Circuit.Coord(
                overlapping.Min(i => Math.Min(i.A.x, i.B.x), Math.Min(A.x, B.x)),
                overlapping.Min(i => Math.Min(i.A.y, i.B.y), Math.Min(A.y, B.y)));
            Circuit.Coord b = new Circuit.Coord(
                overlapping.Max(i => Math.Max(i.A.x, i.B.x), Math.Max(A.x, B.x)),
                overlapping.Max(i => Math.Max(i.A.y, i.B.y), Math.Max(A.y, B.y)));

            List<Circuit.Coord> terminals = new List<Circuit.Coord>() { a, b };
            foreach (Circuit.Element i in InRect(a - 1, b + 1))
            {
                // Find all of the terminals between a and b.
                foreach (Circuit.Terminal j in i.Terminals)
                {
                    if (Circuit.Wire.PointOnSegment(i.MapTerminal(j), a, b))
                    {
                        // If i is not a wire, or it is a wire that is not coincident with a, b, add the terminal to the list.
                        if (!(i is Circuit.Wire) ||
                            i.Terminals.Any(k => !Circuit.Wire.PointOnLine(i.MapTerminal(k), a, b)))
                            terminals.Add(i.MapTerminal(j));
                    }
                }

                // If i is a Wire that crosses a, b, add a terminal at the intersection.
                if (i is Circuit.Wire)
                {
                    Circuit.Wire w = (Circuit.Wire)i;

                    Circuit.Coord ia = w.MapTerminal(w.Anode);
                    Circuit.Coord ib = w.MapTerminal(w.Cathode);

                    // If one of A, B is intersecting this wire, we shouldn't merge wires across this point.
                    if (Circuit.Wire.PointOnLine(A, ia, ib) && !Circuit.Wire.PointOnLine(B, ia, ib))
                        terminals.Add(A);
                    else if (Circuit.Wire.PointOnLine(B, ia, ib) && !Circuit.Wire.PointOnLine(A, ia, ib))
                        terminals.Add(B);
                }
            }
            terminals.Sort((t1, t2) => t1.x == t2.x ? t1.y.CompareTo(t2.y) : t1.x.CompareTo(t2.x));

            // Remove the original wires, and add new ones between each terminal between a and b.
            Remove(overlapping);
            for (int i = 0; i < terminals.Count - 1; ++i)
                if (terminals[i] != terminals[i + 1])
                    Add(new Circuit.Wire(terminals[i], terminals[i + 1]));

            Edits.EndEditGroup();
        }
Example #35
0
 public MoveTool(SchematicEditor Target, Circuit.Coord At)
     : base(Target)
 {
     x = At;
 }