Dispenser/DispenserUI/Views/Controls/ROISelector.cs

167 lines
4.8 KiB
C#
Raw Normal View History

2024-08-16 07:20:09 +00:00
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Input;
using Avalonia.Media;
namespace DispenserUI.Views.Controls;
public class ROISelector : Canvas
{
public static readonly StyledProperty<Point> ROICenterProperty =
AvaloniaProperty.Register<ROISelector, Point>(nameof(ROICenter));
private Path centerPath;
private EllipseGeometry circle;
private Point circleCenter;
private Path circlePath;
private Point currentPoint;
private bool isDragging;
private bool isMouseDragged;
private bool isDrawingComplete;
private bool isPositionChangeable;
private bool isRadiusChangeable;
public Point ROICenter
{
get => GetValue(ROICenterProperty);
set => SetValue(ROICenterProperty, value);
}
public ROISelector()
{
this.GetObservable(ROICenterProperty).Subscribe(val =>
{
DrawROI();
});
}
private double Get2PointsDistance(Point firstPoint, Point secondPoint)
{
return Math.Pow(Math.Pow(secondPoint.X - firstPoint.X, 2) + Math.Pow(secondPoint.Y - firstPoint.Y, 2), 0.5);
}
public new void OnPointerPressed(PointerPressedEventArgs e)
{
var pointerPoint = e.GetCurrentPoint(this);
//鼠标左键按下
if (pointerPoint.Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonPressed)
{
isDragging = true; //开启拖动
//未绘制ROI区域可以开始绘制
if (isDrawingComplete == false)
{
circleCenter = e.GetPosition(this);
}
//已经绘制ROI区域可以修改区域
else
{
currentPoint = e.GetPosition(this);
var distance = Get2PointsDistance(currentPoint, circleCenter);
//点击圆内位置,移动圆位置
if (distance < circle.RadiusX)
isPositionChangeable = true;
//点击圆外30像素以内位置改变圆半径
else if (distance > circle.RadiusX && distance < circle.RadiusX + 30) isRadiusChangeable = true;
}
}
e.Handled = false;
}
public new void OnPointerReleased(PointerReleasedEventArgs e)
{
var pointerPoint = e.GetCurrentPoint(this);
// 鼠标左键释放:结束绘制
if (pointerPoint.Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonReleased)
{
isDragging = false; //结束拖动
if (isMouseDragged == true)
{
isDrawingComplete = true; //绘制完成
isMouseDragged = false;
}
isRadiusChangeable = false;
isPositionChangeable = false;
}
//鼠标右键释放:确定数据,清除图像
else if (pointerPoint.Properties.PointerUpdateKind == PointerUpdateKind.RightButtonReleased)
{
isPositionChangeable = false;
isRadiusChangeable = false;
isDrawingComplete = false;
Children.Remove(circlePath);
ROICenter = new Point(circleCenter.X, circleCenter.Y);
}
e.Handled = false;
}
public new void OnPointerMoved(PointerEventArgs e)
{
if (isDragging == false) return;
isMouseDragged = true;
currentPoint = e.GetPosition(this);
DrawROI();
e.Handled = false;
}
private void DrawROI()
{
Children.Remove(circlePath);
Children.Remove(centerPath);
//绘制ROI
if (isDrawingComplete == false)
{
var radius = Get2PointsDistance(currentPoint, circleCenter);
DrawCircle(circleCenter, radius);
}
else if (isPositionChangeable)
{
var radius = circle.RadiusX;
circleCenter = currentPoint;
DrawCircle(circleCenter, radius);
}
else if (isRadiusChangeable)
{
var radius = Get2PointsDistance(currentPoint, circleCenter);
DrawCircle(circleCenter, radius);
}
Children.Add(circlePath);
Children.Add(centerPath);
}
private void DrawCircle(Point center, double radius)
{
circle = new EllipseGeometry
{
Center = center,
RadiusX = radius,
RadiusY = radius
};
circlePath = new Path
{
Data = circle,
Stroke = Brushes.Orange,
StrokeThickness = 2
};
var centerPoint = new EllipseGeometry
{
Center = center,
RadiusX = 2,
RadiusY = 2,
};
centerPath = new Path
{
Data = centerPoint,
Stroke = Brushes.Orange,
Fill = Brushes.Orange,
StrokeThickness = 2
};
}
}