Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        public static int Run(Options options)
        {
            var loggerFactory = new LoggerFactory();

            if (!options.Silent)
            {
                loggerFactory.AddProvider(new BasicConsoleLogger(options.Verbose ? LogLevel.Debug : LogLevel.Information));
            }

            var logger = loggerFactory.CreateLogger(typeof(ComponentApp));

            if (!options.Input.Any())
            {
                logger.LogError("At least one input file must be specified.");
                return(1);
            }

            var  generators        = new Dictionary <IOutputGenerator, string>();
            var  outputGenerators  = new OutputGeneratorRepository(options.Renderer);
            bool outputIsDirectory = Directory.Exists(options.Output);

            if (options.Output != null && !outputIsDirectory)
            {
                if (outputGenerators.TryGetGeneratorByFileExtension(Path.GetExtension(options.Output), out var generator))
                {
                    // Use the generator implied by the file extension
                    generators.Add(generator, options.Output);
                }
                else if (options.Formats?.Any() != true)
                {
                    logger.LogError("Unable to infer format from output file extension." + Environment.NewLine +
                                    "Specify a known file extension or specify explicitly using --format");
                    return(1);
                }
                else
                {
                    logger.LogInformation("Unable to infer format from output file extension. Using formats only.");
                }
            }

            if (options.Formats?.Any() == true)
            {
                foreach (var format in options.Formats)
                {
                    if (outputGenerators.TryGetGeneratorByFormat(format, out var generator))
                    {
                        generators.Add(generator, outputIsDirectory ? options.Output : null);
                    }
                    else
                    {
                        logger.LogError($"Unknown format: {format}");
                        return(1);
                    }
                }
            }

            var previewOptions = new PreviewGenerationOptions
            {
                Center        = true,
                Crop          = options.Autosize,
                Width         = options.Width,
                Height        = options.Height,
                Configuration = options.Configuration,
                DebugLayout   = options.DebugLayout,
                Grid          = options.Grid,
                Scale         = options.Scale,
                Properties    = new Dictionary <string, string>(),
            };

            if (options.RenderPropertiesPath != null && File.Exists(options.RenderPropertiesPath))
            {
                logger.LogDebug($"Applying render properties from '{options.RenderPropertiesPath}'");
                PreviewGenerationOptionsReader.Read(options.RenderPropertiesPath, previewOptions);
            }

            IComponentDescriptionLookup componentDescriptionLookup;
            var descriptionLookupLoggerFactory = options.Verbose ? loggerFactory : (ILoggerFactory)NullLoggerFactory.Instance;

            if (options.ComponentsDirectory != null)
            {
                componentDescriptionLookup = new DirectoryComponentDescriptionLookup(descriptionLookupLoggerFactory, options.ComponentsDirectory, true);
            }
            else
            {
                componentDescriptionLookup = new DictionaryComponentDescriptionLookup();
            }

            var resourceProvider = ResourceProviderFactory.Create(loggerFactory.CreateLogger(typeof(ResourceProviderFactory)), options.Resources?.ToArray() ?? new string[0]);
            var outputRunner     = new OutputRunner(loggerFactory.CreateLogger <OutputRunner>(), resourceProvider);
            var compileRunner    = new ComponentDescriptionRunner(loggerFactory.CreateLogger <ComponentDescriptionRunner>(), outputRunner);
            var configurationDefinitionRunner = new ConfigurationDefinitionRunner(loggerFactory.CreateLogger <ConfigurationDefinitionRunner>(), componentDescriptionLookup, outputRunner);
            var results = new List <IManifestEntry>();

            var inputs = new List <string>();

            if (File.Exists(options.Input))
            {
                logger.LogDebug("Input is a file.");
                inputs.Add(options.Input);
            }
            else if (Directory.Exists(options.Input))
            {
                logger.LogDebug("Input is a directory.");
                foreach (var generator in generators)
                {
                    if (generator.Value != null && !Directory.Exists(generator.Value))
                    {
                        logger.LogError("Outputs must be directories when the input is a directory.");
                        return(1);
                    }
                }

                foreach (var file in Directory.GetFiles(options.Input, "*.xml",
                                                        options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                {
                    inputs.Add(file);
                }

                foreach (var file in Directory.GetFiles(options.Input, "*.yaml",
                                                        options.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                {
                    inputs.Add(file);
                }
            }
            else
            {
                logger.LogError($"Input is not a valid file or directory: {options.Input}");
                return(1);
            }

            foreach (var file in inputs.OrderBy(x => x))
            {
                logger.LogDebug($"Starting '{file}'");

                IManifestEntry result;

                switch (Path.GetExtension(file))
                {
                case ".xml":
                    result = compileRunner.CompileOne(file, previewOptions, options.AllConfigurations, generators);
                    break;

                case ".yaml":
                    result = configurationDefinitionRunner.CompileOne(file, previewOptions, generators);
                    break;

                default:
                    throw new NotSupportedException($"File type '{Path.GetExtension(file)}' not supported.");
                }

                if (result == null)
                {
                    return(2);
                }

                results.Add(result);

                logger.LogDebug($"Finshed '{file}'");
            }

            if (options.Manifest != null)
            {
                using (var manifestFs = File.Open(options.Manifest, FileMode.Create))
                {
                    logger.LogInformation($"Writing manifest to {options.Manifest}");
                    ManifestWriter.WriteManifest(results, manifestFs);
                }
            }

            return(0);
        }