public MainViewModel(IComponentDescriptionService descriptionService, IDialogService dialogService, IDocumentService documentService, IPluginService pluginService, IToolboxReader toolboxReader, IConfigurationValues configurationValues, AboutViewModel aboutViewModel, CheckForUpdatesViewModel checkForUpdatesViewModel, Func <NewDocumentViewModel> newDocumentViewModelProvider) { this.dialogService = dialogService; this.documentService = documentService; this.aboutViewModel = aboutViewModel; this.checkForUpdatesViewModel = checkForUpdatesViewModel; this.newDocumentViewModelProvider = newDocumentViewModelProvider; SelectedElements = new ObservableCollection <PositionalComponent>(); this.pluginService = pluginService; DescriptionLookup = descriptionService; descriptionService.LoadDescriptions(); using (var toolboxStream = File.OpenRead(configurationValues.ToolboxConfigurationFile)) AvailableComponents = new[] { new[] { select } }.Concat(toolboxReader.GetToolbox(toolboxStream, descriptionService.AvailableTypes)).ToArray(); Document = new CircuitDocument { Size = new Size(640, 480) }; }
public void ApplyConnections(CircuitDocument document) { foreach (Component component in document.Components) { if (component == this) { continue; } foreach (KeyValuePair <Point, Connection> connection in this.GetConnections()) { double thisX = this.Location.X + connection.Key.X; double thisY = this.Location.Y + connection.Key.Y; foreach (KeyValuePair <Point, Connection> connection2 in component.GetConnections()) { double otherX = component.Location.X + connection2.Key.X; double otherY = component.Location.Y + connection2.Key.Y; if (thisX == otherX && thisY == otherY && (!connection2.Value.IsConnected || !connection2.Value.ConnectedTo.Contains(connection.Value))) { if ((connection.Value.Flags & ConnectionFlags.Edge) == ConnectionFlags.Edge || (connection2.Value.Flags & ConnectionFlags.Edge) == ConnectionFlags.Edge) { connection.Value.ConnectTo(connection2.Value); } } } } } }
private XDocument GenerateCorePropertiesXml(CircuitDocument document) { var xml = new XDocument(new XDeclaration("1.0", "utf-8", null)); var root = new XElement(Namespaces.CoreProperties + "coreProperties"); xml.Add(root); if (!string.IsNullOrEmpty(document.Metadata.Creator)) { root.Add(new XElement(Namespaces.DublinCore + "creator", document.Metadata.Creator)); } if (!string.IsNullOrEmpty(document.Metadata.Title)) { root.Add(new XElement(Namespaces.DublinCore + "title", document.Metadata.Creator)); } if (!string.IsNullOrEmpty(document.Metadata.Description)) { root.Add(new XElement(Namespaces.DublinCore + "decsription", document.Metadata.Creator)); } if (document.Metadata.Created.HasValue) { root.Add(new XElement(Namespaces.DublinCore + "date", document.Metadata.Created.Value.ToUniversalTime().ToString("u", CultureInfo.InvariantCulture))); } return(xml); }
public void RenderCircuit(CircuitDocument circuit, IDrawingContext drawingContext) { foreach (var component in circuit.Components .Where(c => c is PositionalComponent).Cast <PositionalComponent>()) { RenderComponent(component, drawingContext, ignoreOffset: false); } }
private XElement CreateElements(CircuitDocument document, WriterContext context) { var documentXml = new XElement(Ns.Document + "elements"); foreach (var component in document.Components) { var componentXml = new XElement(Ns.Document + "c"); componentXml.SetAttributeValue("id", context.GetOrAssignId(component)); var typeId = context.GetId(component.Type); componentXml.SetAttributeValue("tp", "{" + typeId + "}"); // Layout var positionalComponent = component as PositionalComponent; if (positionalComponent != null) { WriteLayout(positionalComponent.Layout, componentXml); } // Properties var properties = new XElement(Ns.Document + "prs"); if (component.Configuration != null) { properties.SetAttributeValue("configuration", component.Configuration.Name); } foreach (var property in component.Properties) { properties.Add(new XElement(Ns.Document + "p", new XAttribute("k", property.Key), new XAttribute("v", property.Value))); } componentXml.Add(properties); // Connections var connections = new XElement(Ns.Document + "cns"); foreach (var connection in component.Connections) { connections.Add(new XElement(Ns.Document + "cn", new XAttribute("id", context.GetOrAssignId(connection.Value.Connection)), new XAttribute("pt", connection.Key))); } componentXml.Add(connections); documentXml.Add(componentXml); } foreach (var wire in document.Wires) { var wireXml = new XElement(Ns.Document + "w"); WriteLayout(wire.Layout, wireXml); documentXml.Add(wireXml); } return(documentXml); }
private XElement CreateMetadata(CircuitDocument document, WriterContext context) { var metadata = new XElement(Ns.Document + "properties"); if (document.Size != null) { metadata.Add(new XElement(Ns.Document + "width", document.Size.Width)); metadata.Add(new XElement(Ns.Document + "height", document.Size.Height)); } return(metadata); }
private XElement CreateDefinitions(CircuitDocument document, WriterContext context) { var componentSources = new XElement(Ns.Document + "definitions"); var componentTypes = document.Elements.Where(x => x is Component) .Cast <Component>() .Select(c => c.Type) .Distinct(); foreach (var source in componentTypes.GroupBy(x => x.Collection)) { var sourceXml = new XElement(Ns.Document + "src"); if (source.Key != ComponentTypeCollection.Unknown) { sourceXml.SetAttributeValue("col", source.Key.Value); } foreach (var type in source) { var typeXml = new XElement(Ns.Document + "add"); typeXml.SetAttributeValue("id", context.AssignId(type)); if (type.CollectionItem != null) { typeXml.SetAttributeValue("item", type.CollectionItem); } typeXml.SetAttributeValue(Ns.DocumentComponentDescriptions + "name", type.Name); if (type.Id.HasValue) { typeXml.SetAttributeValue(Ns.DocumentComponentDescriptions + "guid", type.Id); } // Only write configurations that are actually used in this document foreach (var configuration in type.Configurations.Where(cf => document.Components.Any(cp => cp.Configuration == cf))) { typeXml.Add(new XElement(Ns.Document + "configuration", new XAttribute("name", configuration.Name), new XAttribute("implements", configuration.Implements))); } sourceXml.Add(typeXml); } componentSources.Add(sourceXml); } return(componentSources); }
public void Write(CircuitDocument document, Stream stream) { var xml = GenerateCorePropertiesXml(document); var writer = XmlWriter.Create(stream, new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true, IndentChars = "\t" }); xml.WriteTo(writer); writer.Flush(); }
private void NewDocument() { var viewModel = newDocumentViewModelProvider(); if (dialogService.ShowDialog("New Document", viewModel) != true) { return; } Document = new CircuitDocument { Size = new Size(viewModel.DocumentWidth, viewModel.DocumentHeight) }; }
public static bool Read(Stream stream, out IODocument circuitDocument, out DocumentLoadResult loadResult) { try { BinaryReader reader = new BinaryReader(stream); int magicNumber = reader.ReadInt32(); int formatVersion = reader.ReadInt32(); string appVersion = reader.ReadString(); CDDXContentEncoding contentFlags = (CDDXContentEncoding)reader.ReadInt32(); uint contentOffset = 0; if (formatVersion >= 2) { contentOffset = reader.ReadUInt32(); // offset to content } if (formatVersion >= 2) { stream.Seek(contentOffset, SeekOrigin.Begin); } CircuitDocument newDocument = new CircuitDocument(); if ((contentFlags & CDDXContentEncoding.Deflate) == CDDXContentEncoding.Deflate) { DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress); Xml.XmlReader xmlReader = new Xml.XmlReader(); bool result = xmlReader.Load(deflateStream); circuitDocument = xmlReader.Document; loadResult = xmlReader.LoadResult; loadResult.Format = "CDDX (Legacy 1.0)"; return(result); } else { Xml.XmlReader xmlReader = new Xml.XmlReader(); bool result = xmlReader.Load(stream); circuitDocument = xmlReader.Document; loadResult = xmlReader.LoadResult; loadResult.Format = "CDDX (Legacy 1.0)"; return(result); } } catch (Exception) { circuitDocument = null; loadResult = new DocumentLoadResult(); loadResult.Type = DocumentLoadResultType.FailIncorrectFormat; return(false); } }
public static bool Read(Stream stream, out IODocument circuitDocument, out DocumentLoadResult loadResult) { try { BinaryReader reader = new BinaryReader(stream); int magicNumber = reader.ReadInt32(); int formatVersion = reader.ReadInt32(); string appVersion = reader.ReadString(); CDDXContentEncoding contentFlags = (CDDXContentEncoding)reader.ReadInt32(); uint contentOffset = 0; if (formatVersion >= 2) contentOffset = reader.ReadUInt32(); // offset to content if (formatVersion >= 2) stream.Seek(contentOffset, SeekOrigin.Begin); CircuitDocument newDocument = new CircuitDocument(); if ((contentFlags & CDDXContentEncoding.Deflate) == CDDXContentEncoding.Deflate) { DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress); Xml.XmlReader xmlReader = new Xml.XmlReader(); bool result = xmlReader.Load(deflateStream); circuitDocument = xmlReader.Document; loadResult = xmlReader.LoadResult; loadResult.Format = "CDDX (Legacy 1.0)"; return result; } else { Xml.XmlReader xmlReader = new Xml.XmlReader(); bool result = xmlReader.Load(stream); circuitDocument = xmlReader.Document; loadResult = xmlReader.LoadResult; loadResult.Format = "CDDX (Legacy 1.0)"; return result; } } catch (Exception) { circuitDocument = null; loadResult = new DocumentLoadResult(); loadResult.Type = DocumentLoadResultType.FailIncorrectFormat; return false; } }
private XElement CreateDefinitions(CircuitDocument document, WriterContext context) { var componentSources = new XElement(Ns.Document + "definitions"); var componentTypes = document.Elements.Where(x => x is Component) .Cast <Component>() .Select(c => c.Type) .Distinct(); foreach (var source in componentTypes.GroupBy(x => x.Collection)) { var sourceXml = new XElement(Ns.Document + "src"); if (source.Key != null && source.Key != ComponentType.UnknownCollection) { sourceXml.SetAttributeValue("col", source.Key); } foreach (var type in source) { var typeXml = new XElement(Ns.Document + "add"); typeXml.SetAttributeValue("id", context.AssignId(type)); if (type.CollectionItem != null) { typeXml.SetAttributeValue("item", type.CollectionItem); } var tdComponentType = type as TypeDescriptionComponentType; if (tdComponentType != null) { typeXml.SetAttributeValue(Ns.DocumentComponentDescriptions + "guid", tdComponentType.Id); } sourceXml.Add(typeXml); } componentSources.Add(sourceXml); } return(componentSources); }
public IList <VisualisedConnection> PositionConnections(CircuitDocument document, LayoutOptions layoutOptions) { foreach (var wire in document.Wires().ToList()) { document.Elements.Remove(wire); document.Elements.Add(WireToComponent(wire)); } // Compute connections var connectionPoints = document.PositionalComponents().SelectMany(x => GetConnectionPoints(x, layoutOptions).Select(c => Tuple.Create(x, c))); var connectionsByLocation = connectionPoints.GroupBy(x => x.Item2.Location).Where(x => x.Any(c => c.Item2.IsEdge) && x.Count() > 1).ToList(); // Connect components foreach (var c in connectionsByLocation) { foreach (var c1 in c) { foreach (var c2 in c) { var connection1 = c1.Item1.Connections.GetConnection(c1.Item2.Connection, c1.Item1); var connection2 = c2.Item1.Connections.GetConnection(c2.Item2.Connection, c2.Item1); connection1.ConnectTo(connection2); } } } // Return the connections that the connectionVisualiser indicates should be rendered var points = connectionsByLocation .Select(x => new VisualisedConnection { Connection = x.Select(c => c.Item1.Connections[c.Item2.Connection].Connection).First(), Location = x.Key, Render = VisualiseConnection(x.Select(y => y.Item2).ToList()) }).ToList(); foreach (var wire in document.PositionalComponents().Where(x => x.Type == WireType).ToList()) { document.Elements.Remove(wire); document.Elements.Add(ComponentToWire(wire)); } return(points); }
public void WriteCircuit(CircuitDocument document, Stream stream) { // Cannot write directly to a file stream, so write to this and copy later using (var ms = new MemoryStream()) { // Create the package that contains the document files using (var package = Package.Open(ms, FileMode.Create)) { // Write the main document. This contains the connection and layout data. using (var mainDocStream = packageManager.CreateMainDocumentPart(package)) mainDocumentWriter.Write(document, mainDocStream); // Write the metadata. This contains document size, author, created time etc. // Write any additional resources } ms.WriteTo(stream); } }
public void Write(CircuitDocument document, Stream stream) { var context = new WriterContext(); var xml = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement(Ns.Document + "circuit", new XAttribute("version", Version), CreateMetadata(document, context), CreateDefinitions(document, context), CreateElements(document, context))); var writer = XmlWriter.Create(stream, new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true, IndentChars = "\t" }); xml.WriteTo(writer); writer.Flush(); }
public void RenderCircuit(CircuitDocument circuit, IDrawingContext drawingContext) { foreach (var component in circuit.PositionalComponents) { RenderComponent(component, drawingContext, ignoreOffset: false); } foreach (var wire in circuit.Wires) { RenderWire(wire, drawingContext); } var connections = connectionVisualiser.PositionConnections(circuit, new LayoutOptions() { GridSize = 10.0 }); foreach (var connection in connections.Where(x => x.Render).Select(x => x.Location)) { RenderConnection(connection, drawingContext); } }
/// <summary> /// Removes wires from the connections within a document, connecting components on either end of the wire. /// </summary> /// <param name="document">The document containing the connections to convert.</param> /// <returns>A dictionary containing all components and their associated connections in the format Name-ConnectionID.</returns> public static Dictionary<Component, Dictionary<string, string>> RemoveWires(CircuitDocument document) { // Remove wires foreach (Component wire in document.Components.Where(c => ComponentHelper.IsWire(c))) { // Get list of all connections for this wire var connections = wire.GetConnectedConnections(); // If no connections, skip if (connections.Count() == 0) continue; // Choose a centre to connect everything to var centre = connections.First().Centre; // For each connection, remove the wire itself foreach (var connection in connections.Where(conn => conn.Centre != centre)) { // This centre will be merged with 'centre' above var tempCentre = connection.Centre; // Disconnect this wire //connection.Disconnect(); // If no longer a centre, skip if (connection.Centre == null) continue; // Join 'tempCentre' to 'centre' foreach (var moveConnection in tempCentre.Connected) { moveConnection.SetCentre(centre); centre.Connected.Add(moveConnection); } } } // Join ConnectionCentre's for the same connection name on a component foreach (Component component in document.Components.Where(c => !ComponentHelper.IsWire(c))) { Dictionary<string, List<ConnectionCentre>> connectionNames = new Dictionary<string,List<ConnectionCentre>>(); foreach (var connection in component.GetConnectedConnections().Where(conn => conn.IsConnected)) { if (!connectionNames.ContainsKey(connection.Description.Name)) connectionNames.Add(connection.Description.Name, new List<ConnectionCentre>()); if (!connectionNames[connection.Description.Name].Contains(connection.Centre)) connectionNames[connection.Description.Name].Add(connection.Centre); } // Join all ConnectionCentre's with same name foreach (var connectionName in connectionNames) { // The centres will be merged with this one var centre = connectionName.Value.First(); foreach (var oldCentre in connectionName.Value.Skip(1)) { foreach (Connection moveConnection in oldCentre.Connected) { moveConnection.SetCentre(centre); centre.Connected.Add(moveConnection); } } } } // Assign an ID to each ConnectionCentre int connectionIdCounter = 0; var connectionIDs = new Dictionary<ConnectionCentre, string>(); foreach (Component component in document.Components.Where(c => !ComponentHelper.IsWire(c))) { foreach (var connection in component.GetConnectedConnections().Where(conn => conn.IsConnected)) { if (!connectionIDs.ContainsKey(connection.Centre)) connectionIDs.Add(connection.Centre, (connectionIdCounter++).ToString()); } } // Create return dictionary var returnDict = new Dictionary<Component, Dictionary<string, string>>(); // Create dictionary of connections for each component foreach (Component component in document.Components.Where(c => !ComponentHelper.IsWire(c))) { var connectionsDict = new Dictionary<string, string>(); foreach (var connection in component.GetConnectedConnections()) if (!connectionsDict.ContainsKey(connection.Description.Name)) connectionsDict.Add(connection.Description.Name, connectionIDs[connection.Centre]); returnDict.Add(component, connectionsDict); } // Restore normal connections foreach (Component component in document.Components) component.ResetConnections(); foreach (Component component in document.Components) component.ApplyConnections(document); return returnDict; }
public void ApplyConnections(CircuitDocument document) { foreach (Component component in document.Components) { if (component == this) continue; foreach (KeyValuePair<Point, Connection> connection in this.GetConnections()) { double thisX = this.Location.X + connection.Key.X; double thisY = this.Location.Y + connection.Key.Y; foreach (KeyValuePair<Point, Connection> connection2 in component.GetConnections()) { double otherX = component.Location.X + connection2.Key.X; double otherY = component.Location.Y + connection2.Key.Y; if (thisX == otherX && thisY == otherY && (!connection2.Value.IsConnected || !connection2.Value.ConnectedTo.Contains(connection.Value))) { if ((connection.Value.Flags & ConnectionFlags.Edge) == ConnectionFlags.Edge || (connection2.Value.Flags & ConnectionFlags.Edge) == ConnectionFlags.Edge) connection.Value.ConnectTo(connection2.Value); } } } } }
/// <summary> /// Removes wires from the connections within a document, connecting components on either end of the wire. /// </summary> /// <param name="document">The document containing the connections to convert.</param> /// <returns>A dictionary containing all components and their associated connections in the format Name-ConnectionID.</returns> public static Dictionary <Component, Dictionary <string, string> > RemoveWires(CircuitDocument document) { // Remove wires foreach (Component wire in document.Components.Where(c => ComponentHelper.IsWire(c))) { // Get list of all connections for this wire var connections = wire.GetConnectedConnections(); // If no connections, skip if (connections.Count() == 0) { continue; } // Choose a centre to connect everything to var centre = connections.First().Centre; // For each connection, remove the wire itself foreach (var connection in connections.Where(conn => conn.Centre != centre)) { // This centre will be merged with 'centre' above var tempCentre = connection.Centre; // Disconnect this wire //connection.Disconnect(); // If no longer a centre, skip if (connection.Centre == null) { continue; } // Join 'tempCentre' to 'centre' foreach (var moveConnection in tempCentre.Connected) { moveConnection.SetCentre(centre); centre.Connected.Add(moveConnection); } } } // Join ConnectionCentre's for the same connection name on a component foreach (Component component in document.Components.Where(c => !ComponentHelper.IsWire(c))) { Dictionary <string, List <ConnectionCentre> > connectionNames = new Dictionary <string, List <ConnectionCentre> >(); foreach (var connection in component.GetConnectedConnections().Where(conn => conn.IsConnected)) { if (!connectionNames.ContainsKey(connection.Description.Name)) { connectionNames.Add(connection.Description.Name, new List <ConnectionCentre>()); } if (!connectionNames[connection.Description.Name].Contains(connection.Centre)) { connectionNames[connection.Description.Name].Add(connection.Centre); } } // Join all ConnectionCentre's with same name foreach (var connectionName in connectionNames) { // The centres will be merged with this one var centre = connectionName.Value.First(); foreach (var oldCentre in connectionName.Value.Skip(1)) { foreach (Connection moveConnection in oldCentre.Connected) { moveConnection.SetCentre(centre); centre.Connected.Add(moveConnection); } } } } // Assign an ID to each ConnectionCentre int connectionIdCounter = 0; var connectionIDs = new Dictionary <ConnectionCentre, string>(); foreach (Component component in document.Components.Where(c => !ComponentHelper.IsWire(c))) { foreach (var connection in component.GetConnectedConnections().Where(conn => conn.IsConnected)) { if (!connectionIDs.ContainsKey(connection.Centre)) { connectionIDs.Add(connection.Centre, (connectionIdCounter++).ToString()); } } } // Create return dictionary var returnDict = new Dictionary <Component, Dictionary <string, string> >(); // Create dictionary of connections for each component foreach (Component component in document.Components.Where(c => !ComponentHelper.IsWire(c))) { var connectionsDict = new Dictionary <string, string>(); foreach (var connection in component.GetConnectedConnections()) { if (!connectionsDict.ContainsKey(connection.Description.Name)) { connectionsDict.Add(connection.Description.Name, connectionIDs[connection.Centre]); } } returnDict.Add(component, connectionsDict); } // Restore normal connections foreach (Component component in document.Components) { component.ResetConnections(); } foreach (Component component in document.Components) { component.ApplyConnections(document); } return(returnDict); }
public static T RenderPreview <T>(Func <Size, T> drawingContext, ComponentDescription desc, PreviewGenerationOptions options) where T : IDrawingContext { var componentType = new TypeDescriptionComponentType(desc.Metadata.GUID, ComponentType.UnknownCollection, desc.ComponentName); var component = new PositionalComponent(componentType); component.Layout.Location = new Point(options.Width / 2 - (options.Horizontal ? options.Size : 0), options.Height / 2 - (!options.Horizontal ? options.Size : 0)); component.Layout.Orientation = options.Horizontal ? Orientation.Horizontal : Orientation.Vertical; // Minimum size component.Layout.Size = Math.Max(desc.MinSize, options.Size); // Configuration var configurationDesc = desc.Metadata.Configurations.FirstOrDefault(x => x.Name == options.Configuration); if (configurationDesc != null) { foreach (var setter in configurationDesc.Setters) { component.Properties[setter.Key] = setter.Value; } } // Orientation FlagOptions flagOptions = desc.DetermineFlags(component); if ((flagOptions & FlagOptions.HorizontalOnly) == FlagOptions.HorizontalOnly && component.Layout.Orientation == Orientation.Vertical) { component.Layout.Orientation = Orientation.Horizontal; } else if ((flagOptions & FlagOptions.VerticalOnly) == FlagOptions.VerticalOnly && component.Layout.Orientation == Orientation.Horizontal) { component.Layout.Orientation = Orientation.Vertical; } // Flip if ((flagOptions & FlagOptions.FlipPrimary) == FlagOptions.FlipPrimary && (options.Flip & FlipState.Primary) == FlipState.Primary) { component.Layout.Flip |= FlipState.Primary; } if ((flagOptions & FlagOptions.FlipSecondary) == FlagOptions.FlipSecondary && (options.Flip & FlipState.Secondary) == FlipState.Secondary) { component.Layout.Flip |= FlipState.Secondary; } // Properties foreach (var property in options.Properties) { // Look up serialized name var propertyInfo = desc.Properties.FirstOrDefault(x => x.Name == property.Key); if (propertyInfo != null) { component.Properties[propertyInfo.SerializedName] = PropertyValue.Dynamic(property.Value); } } foreach (var property in options.RawProperties) { component.Properties[property.Key] = property.Value; } CircuitDocument document = new CircuitDocument(); document.Elements.Add(component); var lookup = new DictionaryComponentDescriptionLookup(); lookup.AddDescription(componentType, desc); var docRenderer = new CircuitRenderer(lookup); var buffer = new SkiaBufferedDrawingContext(); docRenderer.RenderCircuit(document, buffer); var bb = buffer.BoundingBox ?? new Rect(); T resultContext; IDrawingContext dc; Vector translationOffset = new Vector(0, 0); if (options.Crop) { resultContext = drawingContext(options.Crop ? bb.Size : new Size(options.Width * options.Scale, options.Height * options.Scale)); dc = new TranslationDrawingContext(new Vector(Math.Round(-bb.X), Math.Round(-bb.Y)), resultContext); } else if (options.Center) { resultContext = drawingContext(new Size(options.Width, options.Height)); var x = bb.X - options.Width / 2 + bb.Width / 2; var y = bb.Y - options.Height / 2 + bb.Height / 2; translationOffset = new Vector(Math.Round(-x), Math.Round(-y)); dc = new TranslationDrawingContext(translationOffset, resultContext); } else { resultContext = drawingContext(new Size(options.Width, options.Height)); dc = resultContext; } if (options.Grid && resultContext is SkiaDrawingContext gridSkiaContext) { RenderGrid(gridSkiaContext, options.Width, options.Height, translationOffset); } if (options.DebugLayout && resultContext is SkiaDrawingContext debugSkiaContext) { RenderDebugLayout(debugSkiaContext, component, desc, translationOffset); } docRenderer.RenderCircuit(document, dc); return(resultContext); }
public static T RenderPreview <T>(Func <Size, T> drawingContext, ComponentDescription desc, PreviewGenerationOptions options) where T : IDrawingContext { var componentType = new ComponentType(desc.Metadata.GUID, desc.ComponentName); foreach (var property in desc.Properties) { componentType.PropertyNames.Add(property.SerializedName); } var component = new PositionalComponent(componentType); component.Layout.Location = new Point(options.Width / 2 - (options.Horizontal ? options.Size : 0), options.Height / 2 - (!options.Horizontal ? options.Size : 0)); component.Layout.Orientation = options.Horizontal ? Orientation.Horizontal : Orientation.Vertical; // Minimum size component.Layout.Size = Math.Max(desc.MinSize, options.Size); // Configuration if (options.Configuration != null) { foreach (var setter in options.Configuration.Setters) { component.Properties[setter.Key] = setter.Value; } } // Orientation FlagOptions flagOptions = desc.DetermineFlags(component); if ((flagOptions & FlagOptions.HorizontalOnly) == FlagOptions.HorizontalOnly && component.Layout.Orientation == Orientation.Vertical) { component.Layout.Orientation = Orientation.Horizontal; component.Layout.Size = desc.MinSize; } else if ((flagOptions & FlagOptions.VerticalOnly) == FlagOptions.VerticalOnly && component.Layout.Orientation == Orientation.Horizontal) { component.Layout.Orientation = Orientation.Vertical; component.Layout.Size = desc.MinSize; } CircuitDocument document = new CircuitDocument(); document.Elements.Add(component); var lookup = new DictionaryComponentDescriptionLookup(); lookup.AddDescription(componentType, desc); var docRenderer = new CircuitRenderer(lookup); var buffer = new BufferedDrawingContext(); docRenderer.RenderCircuit(document, buffer); var bb = buffer.BoundingBox; T resultContext; IDrawingContext dc; if (options.Crop) { resultContext = drawingContext(options.Crop ? bb.Size : new Size(options.Width, options.Height)); dc = new TranslationDrawingContext(new Vector(Math.Round(-bb.X), Math.Round(-bb.Y)), resultContext); } else if (options.Center) { resultContext = drawingContext(new Size(options.Width, options.Height)); var x = bb.X - options.Width / 2 + bb.Width / 2; var y = bb.Y - options.Height / 2 + bb.Height / 2; dc = new TranslationDrawingContext(new Vector(Math.Round(-x), Math.Round(-y)), resultContext); } else { resultContext = drawingContext(new Size(options.Width, options.Height)); dc = resultContext; } docRenderer.RenderCircuit(document, dc); return(resultContext); }