Esempio n. 1
0
        public Rect GetIconRect(int gridSize)
        {
            if (_iconRect == default || _gridSizeIconRect != gridSize)
            {
                var objRect = CalculateScreenRect(gridSize);
                if (_lastScreenRectForIcon != objRect)
                {
                    // draw icon 2x2 grid cells large
                    var minSize = Math.Min(Size.Width, Size.Height);
                    //minSize = minSize == 1 ? minSize : Math.Floor(NthRoot(minSize, Constants.IconSizeFactor) + 1);
                    var iconSize = _coordinateHelper.GridToScreen(new Size(minSize, minSize), gridSize);
                    iconSize = minSize == 1 ? iconSize : new Size(MathHelper.NthRoot(iconSize.Width, Constants.IconSizeFactor), MathHelper.NthRoot(iconSize.Height, Constants.IconSizeFactor));

                    // center icon within the object
                    var iconPos = objRect.TopLeft;
                    iconPos.X += (objRect.Width / 2) - (iconSize.Width / 2);
                    iconPos.Y += (objRect.Height / 2) - (iconSize.Height / 2);

                    _iconRect = new Rect(iconPos, iconSize);

                    _gridSizeIconRect      = gridSize;
                    _lastScreenRectForIcon = objRect;
                }
            }

            return(_iconRect);
        }
Esempio n. 2
0
        /// <summary>
        /// Asynchronously renders the current layout to file.
        /// </summary>
        /// <param name="filename">filename of the output image</param>
        /// <param name="border">normalization value used prior to exporting</param>
        /// <param name="exportZoom">indicates whether the current zoom level should be applied, if false the default zoom is used</param>
        /// <param name="exportSelection">indicates whether selection and influence highlights should be rendered</param>
        private void RenderToFile(string filename, int border, bool exportZoom, bool exportSelection, bool renderStatistics)
        {
            if (annoCanvas.PlacedObjects.Count == 0)
            {
                return;
            }

            // copy all objects
            var allObjects = annoCanvas.PlacedObjects.Select(_ => new AnnoObject(_)).Cast <AnnoObject>().ToList();
            // copy selected objects
            // note: should be references to the correct copied objects from allObjects
            var selectedObjects = annoCanvas.SelectedObjects.Select(_ => new AnnoObject(_)).ToList();

            Debug.WriteLine($"UI thread: {Thread.CurrentThread.ManagedThreadId} ({Thread.CurrentThread.Name})");
            void renderThread()
            {
                Debug.WriteLine($"Render thread: {Thread.CurrentThread.ManagedThreadId} ({Thread.CurrentThread.Name})");

                Stopwatch sw = new Stopwatch();

                sw.Start();

                var icons = new Dictionary <string, IconImage>(StringComparer.OrdinalIgnoreCase);

                foreach (var curIcon in annoCanvas.Icons)
                {
                    icons.Add(curIcon.Key, new IconImage(curIcon.Value.Name, curIcon.Value.Localizations, curIcon.Value.IconPath));
                }

                // initialize output canvas
                var target = new AnnoCanvas(annoCanvas.BuildingPresets, icons)
                {
                    PlacedObjects = allObjects,
                    RenderGrid    = annoCanvas.RenderGrid,
                    RenderIcon    = annoCanvas.RenderIcon,
                    RenderLabel   = annoCanvas.RenderLabel
                };

                sw.Stop();
                Debug.WriteLine($"creating canvas took: {sw.ElapsedMilliseconds}ms");

                // normalize layout
                target.Normalize(border);
                // set zoom level
                if (exportZoom)
                {
                    target.GridSize = annoCanvas.GridSize;
                }
                // set selection
                if (exportSelection)
                {
                    target.SelectedObjects.AddRange(selectedObjects);
                }

                // calculate output size
                var width  = _coordinateHelper.GridToScreen(target.PlacedObjects.Max(_ => _.Position.X + _.Size.Width) + border, target.GridSize);      //if +1 then there are weird black lines next to the statistics view
                var height = _coordinateHelper.GridToScreen(target.PlacedObjects.Max(_ => _.Position.Y + _.Size.Height) + border, target.GridSize) + 1; //+1 for black grid line at bottom

                if (renderStatistics)
                {
                    var exportStatisticsView = new StatisticsView
                    {
                        Margin = new Thickness(5, 0, 0, 0)
                    };
                    exportStatisticsView.statisticsViewModel.UpdateStatistics(target.PlacedObjects, target.SelectedObjects, target.BuildingPresets);
                    exportStatisticsView.statisticsViewModel.CopyLocalization(_mainViewModel.StatisticsViewModel);
                    exportStatisticsView.statisticsViewModel.ShowBuildingList = _mainViewModel.StatisticsViewModel.ShowBuildingList;

                    target.StatisticsPanel.Children.Add(exportStatisticsView);

                    //according to https://stackoverflow.com/a/25507450
                    // and https://stackoverflow.com/a/1320666
                    exportStatisticsView.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                    //exportStatisticsView.Arrange(new Rect(new Point(0, 0), exportStatisticsView.DesiredSize));

                    if (exportStatisticsView.DesiredSize.Height > height)
                    {
                        height = exportStatisticsView.DesiredSize.Height + target.LinePenThickness + border;
                    }

                    width += exportStatisticsView.DesiredSize.Width + target.LinePenThickness;
                }

                target.Width  = width;
                target.Height = height;
                target.UpdateLayout();

                // apply size
                var outputSize = new Size(width, height);

                target.Measure(outputSize);
                target.Arrange(new Rect(outputSize));

                // render canvas to file
                DataIO.RenderToFile(target, filename);
            }

            var thread = new Thread(renderThread);

            thread.IsBackground = true;
            thread.Name         = "exportImage";
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join(TimeSpan.FromSeconds(10));
        }