using FieldVisualizer.Entities.ColorMaps; using FieldVisualizer.InfraStructures.Exceptions; using FieldVisualizer.InfraStructures.Strings; using FieldVisualizer.Services.ColorServices; using FieldVisualizer.Windows.UserControls; using StructureHelperCommon.Services; using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; namespace FieldVisualizer.Entities.Values.Primitives { internal class AddPrimitivesToCanvasLogic { private const int zoomFactor = 1000; private IMathRoundLogic roundLogic = new SmartRoundLogic() { DigitQuant = 3 }; public Canvas WorkPlaneCanvas { get; set; } public IValueRange ValueRange { get; set; } public IColorMap ColorMap { get; set; } public IEnumerable ValueColorRanges { get; set; } public double DX { get; set; } public double DY { get; set; } public void ProcessPrimitives(IEnumerable valuePrimitives) { foreach (var primitive in valuePrimitives) { if (primitive is IRectanglePrimitive rectanglePrimitive) { Rectangle rectangle = ProcessRectanglePrimitive(rectanglePrimitive); WorkPlaneCanvas.Children.Add(rectangle); } else if (primitive is ICirclePrimitive circlePrimitive) { Ellipse ellipse = ProcessCirclePrimitive(circlePrimitive); WorkPlaneCanvas.Children.Add(ellipse); } else if (primitive is ITrianglePrimitive triangle) { Path path = ProcessTrianglePrimitive(triangle); WorkPlaneCanvas.Children.Add(path); } else { throw new FieldVisulizerException(ErrorStrings.PrimitiveTypeIsUnknown); } } } private Path ProcessTrianglePrimitive(ITrianglePrimitive triangle) { // Create the PathFigure using triangle vertices. var figure = new PathFigure { StartPoint = new Point(triangle.Point1.X * zoomFactor, -triangle.Point1.Y * zoomFactor), IsClosed = true, IsFilled = true }; // Add the remaining vertices as LineSegments var segments = new PathSegmentCollection { new LineSegment(new Point(triangle.Point2.X * zoomFactor, - triangle.Point2.Y * zoomFactor), true), new LineSegment(new Point(triangle.Point3.X * zoomFactor, - triangle.Point3.Y * zoomFactor), true) // Closing is handled by IsClosed = true, so we don't need to add a segment back to Point1 }; figure.Segments = segments; // Create geometry and path var geometry = new PathGeometry(); geometry.Figures.Add(figure); var path = new Path { Data = geometry, }; ProcessShape(path, triangle, 0, 0, false); path.MouseLeftButtonDown += OnPathClicked; return path; } private Rectangle ProcessRectanglePrimitive(IRectanglePrimitive rectanglePrimitive) { Rectangle rectangle = new Rectangle { Height = rectanglePrimitive.Height * zoomFactor, Width = rectanglePrimitive.Width * zoomFactor }; double addX = rectanglePrimitive.Width / 2 * zoomFactor; double addY = rectanglePrimitive.Height / 2 * zoomFactor; ProcessShape(rectangle, rectanglePrimitive, addX, addY, true); rectangle.MouseLeftButtonDown += OnRectangleClicked; return rectangle; } private Ellipse ProcessCirclePrimitive(ICirclePrimitive circlePrimitive) { Ellipse ellipse = new Ellipse { Height = circlePrimitive.Diameter * zoomFactor, Width = circlePrimitive.Diameter * zoomFactor }; double addX = circlePrimitive.Diameter / 2 * zoomFactor; double addY = circlePrimitive.Diameter / 2 * zoomFactor; ProcessShape(ellipse, circlePrimitive, addX, addY, true); ellipse.MouseLeftButtonDown += OnEllipseClicked; return ellipse; } private void ProcessShape(Shape shape, IValuePrimitive valuePrimitive, double addX, double addY, bool addCenter) { SolidColorBrush brush = new SolidColorBrush(); brush.Color = ColorOperations.GetColorByValue(ValueRange, ColorMap, valuePrimitive.Value); foreach (var valueRange in ValueColorRanges) { if (valuePrimitive.Value >= valueRange.ExactValues.BottomValue & valuePrimitive.Value <= valueRange.ExactValues.TopValue & (!valueRange.IsActive)) { brush.Color = Colors.Gray; } } shape.ToolTip = roundLogic.RoundValue(valuePrimitive.Value); shape.Tag = valuePrimitive; shape.Fill = brush; shape.StrokeThickness = 0.0; double addLeft = -addX - DX * zoomFactor; double addTop = -addY + DY * zoomFactor; if (addCenter == true) { addLeft += valuePrimitive.CenterX * zoomFactor; addTop -= valuePrimitive.CenterY * zoomFactor; } Canvas.SetLeft(shape, addLeft); Canvas.SetTop(shape, addTop); } private void OnRectangleClicked(object sender, MouseButtonEventArgs e) { if (sender is not Rectangle rectangle) return; if (rectangle.Tag is not IRectanglePrimitive primitive) return; AddLabel(primitive); e.Handled = true; } private void OnEllipseClicked(object sender, MouseButtonEventArgs e) { if (sender is not Ellipse ellipse) return; if (ellipse.Tag is not ICirclePrimitive primitive) return; AddLabel(primitive); e.Handled = true; } private void AddLabel(IValuePrimitive primitive) { var value = roundLogic.RoundValue(primitive.Value); var label = new ValueLabelControl() { Value = Convert.ToString(value), Scale = WorkPlaneCanvas.Height / 600, X = (primitive.CenterX - DX) * zoomFactor, Y = (- primitive.CenterY + DY) * zoomFactor, }; WorkPlaneCanvas.Children.Add(label); } private void OnPathClicked(object sender, MouseButtonEventArgs e) { if (sender is not Path path) return; if (path.Tag is not ITrianglePrimitive primitive) return; AddLabel(primitive); e.Handled = true; } } }