/// <summary> /// Replace the existing canvas with a new canvas, based on the IC given. /// This is similar to closing this window and replacing it with another window /// based on that IC instead. /// </summary> /// <param name="newgcic"></param> public void RefreshGateCanvas(UIGates.IC newgcic) { Grid1.Children.Remove(gateCanvas); gateCanvas.Circuit.Stop(); gateCanvas = new GateCanvas(newgcic, icl); gateCanvas.UndoProvider = (UndoRedo.UndoManager)Resources["undoManager"]; this.UnregisterName("gateCanvas"); this.RegisterName("gateCanvas", gateCanvas); Grid1.Children.Insert(0 /*Grid1.Children.Count - 4*/,gateCanvas); Grid.SetColumn(gateCanvas, 1); Grid.SetRow(gateCanvas, 1); _basedon = newgcic; if (!string.IsNullOrEmpty(newgcic.AbGate.Name)) { _filename = newgcic.AbGate.Name; spGates.ICName = newgcic.AbGate.Name; UpdateTitle(); } if (MyEditLevel == EditLevel.FULL || MyEditLevel == EditLevel.EDIT) { // monitor the clipboard to provide cut/copy/paste visibility gateCanvas.selected.ListChanged += (s2, e2) => { btnCopy.IsEnabled = gateCanvas.selected.Count > 0; btnCut.IsEnabled = gateCanvas.selected.Count > 0; btnCopyAsImage.IsEnabled = gateCanvas.selected.Count > 0; }; } if (_myEditLevel == EditLevel.FULL) gateCanvas.Circuit.Start(); gateCanvas.SetCaptureICLChanges(); gateCanvas.Zoom = slZoom.Value; gateCanvas.UpdateLayout(); gateCanvas.UpdateWireConnections(); }
public GateInkCanvas(UIGates.IC ic, ICList icl) : this(((Gates.IC)ic.AbGate).Circuit, icl) { ICName = ic.AbGate.Name; foreach (KeyValuePair<Gates.AbstractGate, GateLocation> gp in ic.locationHints) { if (gp.Key is Gates.IC) { // must get terminal id template UIGates.IC templateic = icl.GetIC(gp.Key.Name); AddGate(UIGates.IC.CreateFromTemplate( (Gates.IC)gp.Key, templateic), gp.Value); } else AddGate(gp.Key, gp.Value); } // this.Loaded += ((sender, e) => { foreach (KeyValuePair<Gates.AbstractGate, GateLocation> gp in ic.locationHints) { for (int i = 0; i < gp.Key.NumberOfInputs; i++) { Gates.Terminal inp = new Gates.Terminal(i, gp.Key); if (c.GetSource(inp) != null) { c_CircuitConnection(c, inp, c.GetSource(inp)); } } } }//); this.Loaded += (sender, e) => { UpdateWireConnections(); }; }
private void DuplicateLocationHinting(UIGates.IC target) { // duplicate the location hinting foreach (KeyValuePair<Gates.AbstractGate, GateLocation> hint in locationHints) { int cidx = ((Gates.IC)_gate).Circuit.IndexOf(hint.Key); target.locationHints.Add(((Gates.IC)target.AbGate).Circuit[cidx], hint.Value); } }
public ReplaceIC(ICList icl, UIGates.IC oic, UIGates.IC nic) { this.icl = icl; this.oic = oic; this.nic = nic; }
public CreateIC(ICList icl, UIGates.IC ic) { this.icl = icl; this.ic = ic; }
/// <summary> /// Copies the contents of the given IC into this canvas at a slight offset /// from its original location hinted positions. This creates an undo action. /// </summary> /// <param name="ic"></param> public void PasteIC(UIGates.IC ic) { // +32 so they don't appear right on top of the originals Point offset = new Point(32, 32); Dictionary<Gate, Gate> blah; ClearSelection(); UndoRedo.IUndoable paste = AddGates(new GateCanvas(ic, icl), offset, out blah); foreach (Gate g in blah.Values) { g.Selected = true; selected.Add(g); } if (UndoProvider != null) { // use a transaction as a wrapper to change the name // to paste instead of add UndoRedo.Transaction pt = new UndoRedo.Transaction("Paste " + paste.Name.Substring(4)); // 4 is "Add " pt.Add(paste); UndoProvider.Add(pt); } UpdateLayout(); UpdateWireConnections(); }
private UndoRedo.IUndoable Flatten(UIGates.IC ic) { GateCanvas icgc = new GateCanvas((UIGates.IC)ic, icl); UndoRedo.Transaction undo_inline = new UndoRedo.Transaction("Inline Circuit"); // step 1. make room for the circuit // NOTE: exclude user i/o gates // because these will be removed anyways! Rect bounds = GetBounds(icgc.gates.Values.Where(g => !(g is UIGates.UserIO)), 0); foreach (Gate g in gates.Values) { if (g.Margin.Left > ic.Margin.Left || g.Margin.Top > ic.Margin.Top) { Point origin = new Point(g.Margin.Left, g.Margin.Top); double left = g.Margin.Left; double top = g.Margin.Top; if (g.Margin.Left > ic.Margin.Left && bounds.Width - ic.Width > 0) left += bounds.Width - ic.Width; if (g.Margin.Top > ic.Margin.Top && bounds.Height - ic.Height > 0) top += bounds.Height - ic.Height; g.Margin = new Thickness(left, top, 0, 0); ((GateLocation)g.Tag).x = left; ((GateLocation)g.Tag).y = top; undo_inline.Add(new UndoRedo.MoveGate(g, this, origin, new Point(g.Margin.Left, g.Margin.Top))); } } // steps 2 and 3. // bring in circuit and connect internal wiring Dictionary<Gate, Gate> newgates; // = new Dictionary<Gate, Gate>(); undo_inline.Add(AddGates(icgc, new Point(-bounds.Left + ic.Margin.Left, -bounds.Top + ic.Margin.Top), out newgates)); // step 4. connect external wiring Gates.IC gic = ic.AbGate as Gates.IC; // step 4a. connect inputs for (int i = 0; i < gic.NumberOfInputs; i++) { // for each input, find out which circuits within the ic // it is connected to List<Gates.Terminal> targets = gic.Circuit.GetTargets(new Gates.Terminal(0, gic.Inputs[i])); // and this particular ic input, what supplies it from outside the ic? Gates.Terminal source = c.GetSource(new Gates.Terminal(i, gic)); // then disconnect those inputs // and connect it them from the outer foreach (Gates.Terminal t in targets) { Gates.Terminal tt = new Gates.Terminal(t.portNumber, newgates[icgc.FindGate(t.gate)].AbGate); undo_inline.Add(new UndoRedo.Reverse(new UndoRedo.ConnectWire(c, c.GetSource(tt), tt))); c.Disconnect(tt); if (source != null) { c[tt] = source; undo_inline.Add(new UndoRedo.ConnectWire(c, source, tt)); } } } // step 4b. connect outputs for (int i = 0; i < gic.Output.Length; i++) { // for each output, find out which circuit within the ic // it comes from Gates.Terminal source = gic.Circuit.GetSource(new Gates.Terminal(0, gic.Outputs[i])); // translate into our circuit if (source != null) { source = new Gates.Terminal(source.portNumber, newgates[icgc.FindGate(source.gate)].AbGate); } // and this particular output supplies which sources in our circuit? List<Gates.Terminal> targets = c.GetTargets(new Gates.Terminal(i, gic)); // then disconnect those inputs // and connect it them from the outer foreach (Gates.Terminal t in targets) { undo_inline.Add(new UndoRedo.Reverse(new UndoRedo.ConnectWire(c, c.GetSource(t), t))); c.Disconnect(t); if (source != null) { c[t] = source; undo_inline.Add(new UndoRedo.ConnectWire(c, source, t)); } } } // step 5. delete user i/o and ic ClearSelection(); for (int i = 0; i < gic.NumberOfInputs; i++) { selected.Add(newgates[icgc.FindGate(gic.Inputs[i])]); } for (int i = 0; i < gic.Outputs.Length; i++) { selected.Add(newgates[icgc.FindGate(gic.Outputs[i])]); } selected.Add(ic); undo_inline.Add(DeleteSelectedGates()); // step 6. set selection to newly inlined gates ClearSelection(); foreach (Gate g in newgates.Values) { if (!(g is UIGates.UserIO)) { selected.Add(g); g.Selected = true; } } return undo_inline; }
/// <summary> /// Create an XML representation of a given IC. Nested ICs will be referenced, /// but not created by this method. /// </summary> /// <param name="cc"></param> /// <returns></returns> public XElement CreateCircuitXML(UIGates.IC cc) { XElement circuit = new XElement("Circuit"); circuit.SetAttributeValue("Name", cc.AbGate.Name); XElement gates = new XElement("Gates"); Dictionary<Gates.AbstractGate, int> gid = new Dictionary<Gates.AbstractGate, int>(); int cid = 1; Gates.Circuit circ = ((Gates.IC)cc.AbGate).Circuit; foreach (Gates.AbstractGate g in circ) { XElement gt = new XElement("Gate"); gt.SetAttributeValue("Type", g.GetType().Name); gt.SetAttributeValue("Name", g.Name); gt.SetAttributeValue("ID", cid); gt.Add(new XElement("Point")); gt.Element("Point").SetAttributeValue("X", cc.locationHints[g].x); gt.Element("Point").SetAttributeValue("Y", cc.locationHints[g].y); gt.Element("Point").SetAttributeValue("Angle", cc.locationHints[g].angle); if (g is Gates.IVariableInputs) { gt.SetAttributeValue("NumInputs", g.NumberOfInputs); } if (g is Gates.IOGates.AbstractNumeric) { gt.SetAttributeValue("Bits", ((Gates.IOGates.AbstractNumeric)g).Bits); gt.SetAttributeValue("SelRep", (int) (((Gates.IOGates.AbstractNumeric)g).SelectedRepresentation)); gt.SetAttributeValue("Value", ((Gates.IOGates.AbstractNumeric)g).Value); } if (g is Gates.IOGates.Clock) { gt.SetAttributeValue("Milliseconds", ((Gates.IOGates.Clock)g).Milliseconds); } if (g is Gates.IOGates.Comment) { gt.Add(new XElement("Comment", ((Gates.IOGates.Comment)g).Value)); } gates.Add(gt); gid.Add(g, cid); cid++; } XElement wires = new XElement("Wires"); foreach (Gates.AbstractGate g in circ) { for (int i = 0; i < g.NumberOfInputs; i++) { Gates.Terminal t = circ.GetSource(new Gates.Terminal(i, g)); if (t != null) { XElement wire = new XElement("Wire", new XElement("From"), new XElement("To")); wire.Element("From").SetAttributeValue("ID", gid[t.gate]); wire.Element("From").SetAttributeValue("Port", t.portNumber); wire.Element("To").SetAttributeValue("ID", gid[g]); wire.Element("To").SetAttributeValue("Port", i); wires.Add(wire); } } } circuit.Add(gates); circuit.Add(wires); return circuit; }
/// <summary> /// Create an XML representation of the given IC, and all nested ICs recursively, /// and save it to the given path. /// </summary> /// <param name="path"></param> /// <param name="ic"></param> public void Save(string path, UIGates.IC ic) { XElement root = CreateXML(ic); root.Save(path); }
/// <summary> /// Create an XML representation of this IC and all nested ICs, recursively. /// </summary> /// <param name="ic"></param> /// <returns></returns> public XElement CreateXML(UIGates.IC ic) { XElement root = new XElement("CircuitGroup"); root.SetAttributeValue("Version", "1.2"); TopologicalSort ts = new TopologicalSort(); List<UIGates.IC> ics = ts.Sort(ic, icl); foreach (UIGates.IC theic in ics) { root.Add(CreateCircuitXML(theic)); } return root; }
/// <summary> /// Create a window based on a given IC and IC List. Provide /// an edit level of either View or Edit as appropriate. /// </summary> /// <param name="IC"></param> /// <param name="useicl"></param> /// <param name="el"></param> public Window1(UIGates.IC IC, ICList useicl, EditLevel el) : this(el) { icl = useicl; gateCanvas.ICL = icl; gateCanvas.UndoProvider = (UndoRedo.UndoManager)Resources["undoManager"]; spGates.ICList = icl; _filename = IC.AbGate.Name; this.Loaded += (sender, e) => { RefreshGateCanvas(IC); spGates.ICName = IC.AbGate.Name; if (el == EditLevel.VIEW) gateCanvas.IsReadOnly = true; Dispatcher.BeginInvoke( new Action(() => { Activate(); Focus(); })); }; }
private void AddDragDropGate(UIGates.IC g) { //AddDragDropGate(spGates.Children.Count, g); }
private void AddDragDropGate(int pos, UIGates.IC g) { g.DataContext = g.CreateUserInstance(); DragDrop.DragDropHelper.SetIsDragSource(g, true); DragDrop.DragDropHelper.SetDragDropControl(g, new DragDrop.GateDragDropAdorner()); DragDrop.DragDropHelper.SetDropTarget(g, "inkCanvas"); DragDrop.DragDropHelper.SetAdornerLayer(g, "adornerLayer"); g.PreviewICNameChanged += (object sender2, string newname, ref bool cancel) => { if (newname == "") cancel = true; foreach (Gate g2 in icl) { if (newname == g2.AbGate.Name) cancel = true; } }; g.ICNameChanged += (sender2, newname) => { UIGates.IC oic = icl.GetIC((g.AbGate.Name)); UIGates.IC nic = g.CreateUserInstance(newname); icl[icl.IndexOf(oic)] = nic; if (undoProvider != null) undoProvider.Add(new UndoRedo.ReplaceIC(icl, oic, nic)); }; ScaleTransform st = new ScaleTransform(); st.CenterX = g.Width / 2.0; st.CenterY = g.Height / 2.0; double fac = 1.0; if (g.Width > MAX_SIZE) fac = Math.Min(MAX_SIZE / g.Width, fac); if (g.Height > MAX_SIZE) fac = Math.Min(MAX_SIZE / g.Height, fac); st.ScaleY = fac; st.ScaleX = fac; g.LayoutTransform = st; g.ContextMenu = new ContextMenu(); MenuItem exp = new MenuItem(); exp.Header = "Export..."; exp.Click += (sender2, e2) => { Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog(); dlg.DefaultExt = ".ic"; dlg.Filter = "IC (.ic)|*.ic"; bool? result = dlg.ShowDialog(); if (result == true) { CircuitXML cxml = new CircuitXML(icl); try { cxml.Save(dlg.FileName, g); } catch (Exception ex) { MessageBox.Show("Unable to save IC: " + ex.ToString()); } } }; g.ContextMenu.Items.Add(exp); MenuItem del = new MenuItem(); del.Header = "Delete"; del.Click += (sender2, e2) => { if (MessageBox.Show("All instances of this IC in all circuits will be removed. This operation cannot be undone. Proceed?", "Danger Zone", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes) { UIGates.IC todel = icl.GetIC(g.AbGate.Name); icl.Remove(todel); if (undoProvider != null) undoProvider.Clear(); } }; g.ContextMenu.Items.Add(del); MenuItem hid = new MenuItem(); hid.Header = "Hide"; hid.Click += (sender2, e2) => { g.Visibility = Visibility.Collapsed; }; //g.ContextMenu.Items.Add(hid); //BOKANG //spGates.Children.Insert(pos, g); //g.MouseDoubleClick += new MouseButtonEventHandler(g_MouseDoubleClick); //BOKANG //expUserGates.IsExpanded = true; g.BringIntoView(); g.IsReadOnly = _ro; g.ContextMenu.IsEnabled = !_ro; if (!string.IsNullOrEmpty(_icname)) if (((Gates.IC)g.AbGate).DeepIncludes(_icname)) g.Visibility = Visibility.Collapsed; ((Gates.IC)g.AbGate).Circuit.Start(); }
private void SetInfoLine(UIGates.IC ic) { string inf = "Left-drag to place"; if (!_ro) inf += ", double-click to edit, type to rename"; InfoLine.SetInfo(ic, inf); }
/// <summary> /// Sort all ICs used within a given IC, deferencing against an IC list /// for canonical instances. /// </summary> /// <param name="ic"></param> /// <param name="icl"></param> /// <returns></returns> public List<UIGates.IC> Sort(UIGates.IC ic, ICList icl) { return Sort(new UIGates.IC[] { ic }, icl); }