251 lines
9.7 KiB
C#
251 lines
9.7 KiB
C#
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using System.Windows.Shapes;
|
|
|
|
namespace CtrEditor.ObjetosSim.UserControls
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for CircularSegment.xaml
|
|
/// </summary>
|
|
public partial class CircularSegment : UserControl
|
|
{
|
|
public double Angle
|
|
{
|
|
get { return (double)GetValue(AngleProperty); }
|
|
set { SetValue(AngleProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty AngleProperty =
|
|
DependencyProperty.Register("Angle", typeof(double), typeof(CircularSegment), new PropertyMetadata(0.0));
|
|
|
|
public double OuterRadius
|
|
{
|
|
get { return (double)GetValue(OuterRadiusProperty); }
|
|
set { SetValue(OuterRadiusProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty OuterRadiusProperty =
|
|
DependencyProperty.Register("OuterRadius", typeof(double), typeof(CircularSegment), new PropertyMetadata(100.0, OnPropertyChanged));
|
|
|
|
public double InnerRadius
|
|
{
|
|
get { return (double)GetValue(InnerRadiusProperty); }
|
|
set { SetValue(InnerRadiusProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty InnerRadiusProperty =
|
|
DependencyProperty.Register("InnerRadius", typeof(double), typeof(CircularSegment), new PropertyMetadata(80.0, OnPropertyChanged));
|
|
|
|
public double StartAngle
|
|
{
|
|
get { return (double)GetValue(StartAngleProperty); }
|
|
set { SetValue(StartAngleProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty StartAngleProperty =
|
|
DependencyProperty.Register("StartAngle", typeof(double), typeof(CircularSegment), new PropertyMetadata(0.0, OnPropertyChanged));
|
|
|
|
public double EndAngle
|
|
{
|
|
get { return (double)GetValue(EndAngleProperty); }
|
|
set { SetValue(EndAngleProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty EndAngleProperty =
|
|
DependencyProperty.Register("EndAngle", typeof(double), typeof(CircularSegment), new PropertyMetadata(90.0, OnPropertyChanged));
|
|
|
|
// Nuevas propiedades para las guías
|
|
public bool ShowGuides
|
|
{
|
|
get { return (bool)GetValue(ShowGuidesProperty); }
|
|
set { SetValue(ShowGuidesProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty ShowGuidesProperty =
|
|
DependencyProperty.Register("ShowGuides", typeof(bool), typeof(CircularSegment), new PropertyMetadata(false, OnPropertyChanged));
|
|
|
|
public double GuideDistance
|
|
{
|
|
get { return (double)GetValue(GuideDistanceProperty); }
|
|
set { SetValue(GuideDistanceProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty GuideDistanceProperty =
|
|
DependencyProperty.Register("GuideDistance", typeof(double), typeof(CircularSegment), new PropertyMetadata(5.0, OnPropertyChanged));
|
|
|
|
public double GuideThickness
|
|
{
|
|
get { return (double)GetValue(GuideThicknessProperty); }
|
|
set { SetValue(GuideThicknessProperty, value); }
|
|
}
|
|
|
|
public static readonly DependencyProperty GuideThicknessProperty =
|
|
DependencyProperty.Register("GuideThickness", typeof(double), typeof(CircularSegment), new PropertyMetadata(2.0, OnPropertyChanged));
|
|
|
|
public static readonly DependencyProperty GuideStrokeProperty =
|
|
DependencyProperty.Register("GuideStroke", typeof(Brush), typeof(CircularSegment), new PropertyMetadata(new SolidColorBrush(Colors.DarkBlue), OnGuidePropertyChanged));
|
|
|
|
public Brush GuideStroke
|
|
{
|
|
get { return (Brush)GetValue(GuideStrokeProperty); }
|
|
set { SetValue(GuideStrokeProperty, value); }
|
|
}
|
|
|
|
public CircularSegment()
|
|
{
|
|
InitializeComponent();
|
|
this.Loaded += CircularSegment_Loaded;
|
|
}
|
|
|
|
private void CircularSegment_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("CircularSegment_Loaded called");
|
|
DrawSegment();
|
|
}
|
|
|
|
// Propiedad pública para acceder al Path desde código externo
|
|
public System.Windows.Shapes.Path TransportePath => path;
|
|
|
|
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
(d as CircularSegment)?.DrawSegment();
|
|
}
|
|
|
|
private static void OnGuidePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
(d as CircularSegment)?.DrawSegment();
|
|
}
|
|
|
|
private void DrawSegment()
|
|
{
|
|
System.Diagnostics.Debug.WriteLine($"DrawSegment called - ShowGuides: {ShowGuides}");
|
|
|
|
if (OuterRadius <= 0 || InnerRadius <= 0 || StartAngle == EndAngle)
|
|
return;
|
|
|
|
// Limpiar canvas existente - mantener solo el path principal
|
|
for (int i = mainCanvas.Children.Count - 1; i >= 0; i--)
|
|
{
|
|
if (mainCanvas.Children[i] != path)
|
|
{
|
|
mainCanvas.Children.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
DrawMainSegment();
|
|
|
|
if (ShowGuides)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("About to call DrawGuides()");
|
|
DrawGuides();
|
|
}
|
|
}
|
|
|
|
private void DrawMainSegment()
|
|
{
|
|
PathGeometry geometry = new PathGeometry();
|
|
PathFigure figure = new PathFigure();
|
|
|
|
// Calcula el centro del Canvas (suponemos que el Canvas es lo suficientemente grande)
|
|
Point center = new Point(OuterRadius, OuterRadius);
|
|
|
|
// Calcular los puntos de inicio y fin del arco externo
|
|
Point startPoint = new Point(center.X + Math.Cos(StartAngle * Math.PI / 180) * OuterRadius,
|
|
center.Y + Math.Sin(StartAngle * Math.PI / 180) * OuterRadius);
|
|
Point endPoint = new Point(center.X + Math.Cos(EndAngle * Math.PI / 180) * OuterRadius,
|
|
center.Y + Math.Sin(EndAngle * Math.PI / 180) * OuterRadius);
|
|
|
|
// Crear arco externo
|
|
bool largeArc = Math.Abs(EndAngle - StartAngle) > 180.0;
|
|
figure.StartPoint = startPoint;
|
|
figure.Segments.Add(new ArcSegment(endPoint, new Size(OuterRadius, OuterRadius), 0, largeArc, SweepDirection.Clockwise, true));
|
|
|
|
// Crear línea hacia el arco interno
|
|
figure.Segments.Add(new LineSegment(new Point(center.X + Math.Cos(EndAngle * Math.PI / 180) * InnerRadius,
|
|
center.Y + Math.Sin(EndAngle * Math.PI / 180) * InnerRadius), true));
|
|
|
|
// Crear arco interno
|
|
startPoint = new Point(center.X + Math.Cos(StartAngle * Math.PI / 180) * InnerRadius,
|
|
center.Y + Math.Sin(StartAngle * Math.PI / 180) * InnerRadius);
|
|
figure.Segments.Add(new ArcSegment(startPoint, new Size(InnerRadius, InnerRadius), 0, largeArc, SweepDirection.Counterclockwise, true));
|
|
|
|
// Cerrar la figura
|
|
figure.IsClosed = true;
|
|
geometry.Figures.Add(figure);
|
|
path.Data = geometry;
|
|
}
|
|
|
|
private void DrawGuides()
|
|
{
|
|
Point center = new Point(OuterRadius, OuterRadius);
|
|
|
|
// Calcular radios de las guías
|
|
double outerGuideRadius = OuterRadius + GuideDistance;
|
|
double innerGuideRadius = InnerRadius - GuideDistance;
|
|
|
|
System.Diagnostics.Debug.WriteLine($"DrawGuides - Creating guides with radii: Outer={outerGuideRadius}, Inner={innerGuideRadius}");
|
|
|
|
// Asegurar que el radio interior no sea negativo
|
|
if (innerGuideRadius < 1.0)
|
|
innerGuideRadius = 1.0;
|
|
|
|
// Crear guía exterior
|
|
CreateGuideArc(center, outerGuideRadius, "OuterGuide");
|
|
|
|
// Crear guía interior solo si el radio es válido
|
|
if (innerGuideRadius > 1.0)
|
|
{
|
|
CreateGuideArc(center, innerGuideRadius, "InnerGuide");
|
|
}
|
|
}
|
|
|
|
private void CreateGuideArc(Point center, double radius, string name)
|
|
{
|
|
var guidePath = new System.Windows.Shapes.Path
|
|
{
|
|
Name = name,
|
|
Stroke = GuideStroke,
|
|
StrokeThickness = GuideThickness,
|
|
Fill = null
|
|
};
|
|
|
|
// Crear geometría del arco
|
|
double radiansStart = StartAngle * Math.PI / 180.0;
|
|
double radiansEnd = EndAngle * Math.PI / 180.0;
|
|
|
|
Point startPoint = new Point(
|
|
center.X + radius * Math.Cos(radiansStart),
|
|
center.Y + radius * Math.Sin(radiansStart)
|
|
);
|
|
|
|
Point endPoint = new Point(
|
|
center.X + radius * Math.Cos(radiansEnd),
|
|
center.Y + radius * Math.Sin(radiansEnd)
|
|
);
|
|
|
|
// Crear el arco usando ArcSegment
|
|
var pathGeometry = new PathGeometry();
|
|
var pathFigure = new PathFigure
|
|
{
|
|
StartPoint = startPoint
|
|
};
|
|
|
|
var arcSegment = new ArcSegment
|
|
{
|
|
Point = endPoint,
|
|
Size = new Size(radius, radius),
|
|
SweepDirection = SweepDirection.Clockwise,
|
|
IsLargeArc = Math.Abs(EndAngle - StartAngle) > 180
|
|
};
|
|
|
|
pathFigure.Segments.Add(arcSegment);
|
|
pathGeometry.Figures.Add(pathFigure);
|
|
guidePath.Data = pathGeometry;
|
|
|
|
System.Diagnostics.Debug.WriteLine($"Adding guide {name} to canvas");
|
|
mainCanvas.Children.Add(guidePath);
|
|
}
|
|
}
|
|
}
|