Dispenser/DispenserUI/Views/Controls/ROISelector.cs

167 lines
4.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
};
}
}