/// <summary> /// Add a gate to this canvas. An appropriate visual representation will be created. /// </summary> /// <param name="gate"></param> /// <param name="pos"></param> public void AddGate(Gates.AbstractGate gate, GateLocation pos) { // maybe we could use extension methods // to add a method to create a UIGate for each AbstractGate? Gate uigate; if (gate is Gates.BasicGates.And) { uigate = new UIGates.And((Gates.BasicGates.And)gate); } else if (gate is Gates.BasicGates.Not) { uigate = new UIGates.Not((Gates.BasicGates.Not)gate); } else if (gate is Gates.BasicGates.Or) { uigate = new UIGates.Or((Gates.BasicGates.Or)gate); } else if (gate is Gates.BasicGates.Nand) { uigate = new UIGates.Nand((Gates.BasicGates.Nand)gate); } else if (gate is Gates.BasicGates.Nor) { uigate = new UIGates.Nor((Gates.BasicGates.Nor)gate); } else if (gate is Gates.BasicGates.Xor) { uigate = new UIGates.Xor((Gates.BasicGates.Xor)gate); } else if (gate is Gates.BasicGates.Xnor) { uigate = new UIGates.Xnor((Gates.BasicGates.Xnor)gate); } else if (gate is Gates.BasicGates.Buffer) { uigate = new UIGates.Buffer((Gates.BasicGates.Buffer)gate); } else if (gate is Gates.IOGates.UserInput) { uigate = new UIGates.UserInput((Gates.IOGates.UserInput)gate); } else if (gate is Gates.IOGates.UserOutput) { uigate = new UIGates.UserOutput((Gates.IOGates.UserOutput)gate); } else if (gate is Gates.IOGates.AbstractNumeric) { uigate = new UIGates.Numeric((Gates.IOGates.AbstractNumeric)gate); } else if (gate is Gates.IOGates.Clock) { uigate = new UIGates.Clock((Gates.IOGates.Clock)gate); } else if (gate is Gates.IOGates.Comment) { uigate = new UIGates.Comment((Gates.IOGates.Comment)gate); } else if (gate is Gates.IC) { uigate = UIGates.IC.CreateFromTemplate((Gates.IC)gate, icl.GetIC(gate.Name)); } else throw new ArgumentException("gate not of known subclass"); AddGate(uigate, pos); }
/// <summary> /// Add a pre-existing visual gate at a particular location. The gate will also /// be added to the circuit if it is not already a member. /// </summary> /// <param name="uigate"></param> /// <param name="pos"></param> public void AddGate(Gate uigate, GateLocation pos) { Gates.AbstractGate gate = uigate.AbGate; gates[gate] = uigate; uigate.Margin = new Thickness(pos.x, pos.y, 0, 0); GC.Children.Add(uigate); if (!c.Contains(gate)) c.Add(gate); uigate.RenderTransform = new RotateTransform(pos.angle, uigate.Width / 2.0, uigate.Height / 2.0); uigate.Tag = new GateLocation() { x = pos.x, y = pos.y, angle = pos.angle }; // NOTE that we need a separate angle and transform // for the snap-to to work properly // so I am using the tag to store the angle uigate.MouseDown += new MouseButtonEventHandler(uigate_MouseDown); uigate.MouseUp += new MouseButtonEventHandler(uigate_MouseUp); if (uigate is UIGates.IC) { uigate.MouseDoubleClick += new MouseButtonEventHandler(uigate_MouseDoubleClick); uigate.ContextMenu = new ContextMenu(); MenuItem inline = new MenuItem(); inline.Header = "Inline Circuit"; inline.Tag = uigate; uigate.ContextMenu.Items.Add(inline); inline.Click += new RoutedEventHandler(inline_Click); uigate.ContextMenu.IsEnabled = !IsReadOnly; } // can add inputs if (uigate.AbGate is Gates.IVariableInputs) { uigate.ContextMenu = new ContextMenu(); MenuItem addInput = new MenuItem(); addInput.Header = "Add Input"; addInput.Tag = uigate; uigate.ContextMenu.Items.Add(addInput); addInput.Click += (sender2, e2) => { Gates.AbstractGate newgate = ((Gates.IVariableInputs)uigate.AbGate).Clone(uigate.AbGate.NumberOfInputs + 1); c.ReplaceGate(uigate.AbGate, newgate); if (UndoProvider != null) UndoProvider.Add(new UndoRedo.ChangeNumInputs(c, uigate.AbGate, newgate)); }; if (uigate.AbGate.NumberOfInputs > 2) { MenuItem removeInput = new MenuItem(); removeInput.Header = "Remove Input"; removeInput.Tag = uigate; uigate.ContextMenu.Items.Add(removeInput); removeInput.Click += (sender2, e2) => { UndoRedo.Transaction removeInp = new GatesWpf.UndoRedo.Transaction("Remove Input"); // remember wires connected to removed input Gates.Terminal dest = new Gates.Terminal(uigate.AbGate.NumberOfInputs - 1, uigate.AbGate); Gates.Terminal origin = c.GetSource(dest); if (origin != null) removeInp.Add(new UndoRedo.Reverse(new UndoRedo.ConnectWire(c, origin, dest))); Gates.AbstractGate newgate = ((Gates.IVariableInputs)uigate.AbGate).Clone(uigate.AbGate.NumberOfInputs - 1); c.ReplaceGate(uigate.AbGate, newgate); removeInp.Add(new UndoRedo.ChangeNumInputs(c, uigate.AbGate, newgate)); if (UndoProvider != null) UndoProvider.Add(removeInp); }; } uigate.ContextMenu.IsEnabled = !IsReadOnly; } if (uigate is UIGates.UserIO) ((UIGates.UserIO)uigate).UndoProvider = UndoProvider; if (uigate is UIGates.Comment) ((UIGates.Comment)uigate).UndoProvider = UndoProvider; SetInfoLine(uigate); }