Пример #1
0
        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;
        }
Пример #2
0
        /// <summary>
        /// Add all gates from a given canvas into our canvas at the selected offset.
        /// A clone of each gate will be made, both at the visual and internal level.
        /// A map will be produced indicated the relationship between the gates in the original
        /// canvas and the gates added to this canvas.
        /// </summary>
        /// <param name="icgc"></param>
        /// <param name="offset"></param>
        /// <param name="gatemap"></param>
        /// <returns></returns>
        protected UndoRedo.Transaction AddGates(GateCanvas icgc, Point offset, out Dictionary<Gate, Gate> gatemap)
        {
            UndoRedo.Transaction addgates = new UndoRedo.Transaction("Add Gates");
            gatemap = new Dictionary<Gate, Gate>();

            // step 1. bring the circuit in
            foreach (Gate g in icgc.gates.Values)
            {
                gatemap[g] = g.CreateUserInstance();
                AddGate(gatemap[g], new GateLocation(offset.X + g.Margin.Left, g.Margin.Top + offset.Y, ((RotateTransform)g.RenderTransform).Angle));
                addgates.Add(new UndoRedo.AddGate(this, gatemap[g]));
            }

            // step 2. connect internal wiring
            foreach (ConnectedWire cw in icgc.wires.Values)
            {
                Gates.Terminal target = new Gates.Terminal(cw.DestTerminalID.ID, gatemap[icgc.FindGate(cw.DestinationGate)].AbGate);
                Gates.Terminal source = new Gates.Terminal(cw.OriginTerminalID.ID, gatemap[icgc.FindGate(cw.OriginGate)].AbGate);
                c[target] = source;
                addgates.Add(new UndoRedo.ConnectWire(c, source, target));
            }

            return addgates;
        }