//Load circuit from an XML file, see section 2.3.3.1 for format public void LoadCircuit(string filename) { ClearCircuit(); bool wasError = false; try { XmlDocument circuitXml = new XmlDocument(); circuitXml.Load(filename); //Load settings foreach (var settingElement in circuitXml.GetElementsByTagName("setting").OfType <XmlElement>()) { try { if (settingElement.HasAttribute("key") && settingElement.HasAttribute("value")) { switch (settingElement.GetAttribute("key")) { case "numberOfBreadboards": ParentWindow.SetNumberOfBreadboards(int.Parse(settingElement.GetAttribute("value"))); break; case "simulationSpeed": SimulationSpeed.Val = double.Parse(settingElement.GetAttribute("value")); break; case "positiveRailVoltage": PositiveRailVoltage = double.Parse(settingElement.GetAttribute("value")); break; case "negativeRailVoltage": NegativeRailVoltage = double.Parse(settingElement.GetAttribute("value")); break; } } } catch { wasError = true; } } //Load components foreach (var componentElement in circuitXml.GetElementsByTagName("component").OfType <XmlElement>()) { try { Dictionary <string, string> parameters = new Dictionary <string, string>(); foreach (var attribute in componentElement.Attributes.OfType <XmlAttribute>()) { parameters[attribute.Name] = attribute.Value; } AddComponent(Component.CreateFromParameters(this, parameters)); } catch { wasError = true; } } //Load wires foreach (var wireElement in circuitXml.GetElementsByTagName("wire").OfType <XmlElement>()) { try { Dictionary <string, string> parameters = new Dictionary <string, string>(); foreach (var attribute in wireElement.Attributes.OfType <XmlAttribute>()) { parameters[attribute.Name] = attribute.Value; } AddWire(Wire.CreateFromParameters(this, parameters)); } catch { wasError = true; } } } catch { wasError = true; } if (wasError) { MessageBox.Show("An error occurred while loading the file. The file you selected may not be compatible with this version of the Breadboard Simulator," + " or it may have become corrupted.\r\nAs a result, the circuit may be missing entirely, incomplete or have broken components.", "Failure to open file", MessageBoxButton.OK, MessageBoxImage.Warning); } //Rebuild circuit UpdateWireColours(); }
//Adds a wire to the circuit public void AddWire(Wire newWire) { Wires.Add(newWire); ParentWindow.DrawArea.Children.Add(newWire); }
private void Breadboard_MouseUp(object sender, MouseButtonEventArgs e) { ParentCircuit.DeselectAll(); if (ParentCircuit.ParentWindow.SelectedTool == "WIRE") { if (StartedWire) { Point actualCoord = GetHoleCoord(e.GetPosition(this), true); if (BreadBoardHolePositions.Contains(actualCoord)) { actualCoord = GetAbsolutePosition(actualCoord); Orientation o = Util.getBestOrientation(WirePointA, actualCoord); int length = 0; if (o == Orientation.Horizontal) { length = (int)((actualCoord.X - WirePointA.X) / Constants.ScaleFactor); } else { length = (int)((actualCoord.Y - WirePointA.Y) / Constants.ScaleFactor); } NewWire.Length = length; NewWire.WireOrientation = o; NewWire.MakePermanentWire(); StartedWire = false; ParentCircuit.UpdateWireColours(); ParentCircuit.AddUndoAction(new AddAction(NewWire, ParentCircuit)); } } else { Point rawCoord = GetHoleCoord(e.GetPosition(this), false); Point actualCoord = new Point(0, 0); bool isValid = false; //We only want to start a new wire if the user clicks on or near a hole foreach (Point p in BreadBoardHolePositions) { double distance = Math.Sqrt(Math.Pow((p.X - rawCoord.X), 2) + Math.Pow((p.Y - rawCoord.Y), 2)); if (distance < 0.4) { isValid = true; actualCoord = p; break; } } if (isValid) { WirePointA = GetAbsolutePosition(actualCoord); StartedWire = true; NewWire = new Wire(ParentCircuit, Orientation.Horizontal, 0, Constants.RandomWireColours[new Random().Next(Constants.RandomWireColours.Length)], new Point(WirePointA.X + 1, WirePointA.Y + 1)); NewWire.MakeTemporaryWire(); ParentCircuit.AddWire(NewWire); } } } else if (ParentCircuit.ParentWindow.SelectedTool == "COMPONENT") { if (StartedLeadedComponent) { Point actualCoord = GetHoleCoord(e.GetPosition(this), true); if (BreadBoardHolePositions.Contains(actualCoord)) { actualCoord = GetAbsolutePosition(actualCoord); Orientation o = Util.getBestOrientation(ComponentPointA, actualCoord); int length = 0; if (o == Orientation.Horizontal) { length = (int)((actualCoord.X - ComponentPointA.X) / Constants.ScaleFactor); } else { length = (int)((actualCoord.Y - ComponentPointA.Y) / Constants.ScaleFactor); } if (Math.Abs(length) >= NewLeadedComponent.MinLength) { NewLeadedComponent.Length = length; NewLeadedComponent.orientation = o; NewLeadedComponent.MakePermanent(); ParentCircuit.UpdateNetConnectivity(); StartedLeadedComponent = false; ParentCircuit.AddUndoAction(new AddAction(NewLeadedComponent, ParentCircuit)); } } } else { ComponentData selectedComponentType = ParentCircuit.ParentWindow.GetSelectedComponent(); if (selectedComponentType != null) { Point rawCoord = GetHoleCoord(e.GetPosition(this), false); Point actualCoord = new Point(0, 0); bool isValid = false; //We only want to start a new wire if the user clicks on or near a hole foreach (Point p in BreadBoardHolePositions) { double distance = Math.Sqrt(Math.Pow((p.X - rawCoord.X), 2) + Math.Pow((p.Y - rawCoord.Y), 2)); if (distance < 0.4) { isValid = true; actualCoord = p; break; } } if (isValid) { Component newComponent = Component.CreateComponent(ParentCircuit, GetAbsolutePosition(actualCoord), selectedComponentType); if (newComponent != null) { if (newComponent is LeadedComponent) { ComponentPointA = GetAbsolutePosition(actualCoord); StartedLeadedComponent = true; NewLeadedComponent = (LeadedComponent)newComponent; NewLeadedComponent.MakeTemporary(); } else { ParentCircuit.AddUndoAction(new AddAction(newComponent, ParentCircuit)); } ParentCircuit.AddComponent(newComponent); ParentCircuit.UpdateNetConnectivity(); } } } } } ParentCircuit.ParentWindow.UpdatePrompt(); }