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)))); }
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()); } } }
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))); }
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)))); }
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; }
public override void MouseDown(Circuit.Coord At) { mouse = new List <Circuit.Coord>() { At }; path.Visibility = Visibility.Visible; }
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; }
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; }
public override void MouseUp(Circuit.Coord At) { b = At; if (a == b) { if (Clicked != null) { Clicked(RelevantOf(Target.AtPoint(a))); } } }
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); } }
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); }
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; } }
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(); }
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; } }
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 }; }
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); }
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); } }
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); } }
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; }
public override void MouseDown(Circuit.Coord At) { a = b = At; }
public override void MouseUp(Circuit.Coord At) { Target.Tool = new SelectionTool(Editor); }
public MoveTool(SchematicEditor Target, Circuit.Coord At) : base(Target) { x = At; }
public virtual void MouseLeave(Circuit.Coord At) { }
public virtual void MouseEnter(Circuit.Coord At) { }
public virtual void MouseUp(Circuit.Coord At) { }
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))); }
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(); }