Files
StructureHelper/FieldVisualizer/Entities/Values/Primitives/AddPrimitivesToCanvasLogic.cs
Evgeny Redikultsev f937b9f373 Change field viewer
2025-12-13 20:13:45 +05:00

185 lines
7.0 KiB
C#

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<IValueColorRange> ValueColorRanges { get; set; }
public double DX { get; set; }
public double DY { get; set; }
public void ProcessPrimitives(IEnumerable<IValuePrimitive> 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;
}
}
}