using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; using Azaion.Common.DTO; using Label = System.Windows.Controls.Label; namespace Azaion.Common.Controls; public class DetectionControl : Border { private readonly Action _resizeStart; private const double RESIZE_RECT_SIZE = 9; private readonly Grid _grid; private readonly TextBlock _classNameLabel; private readonly Label _probabilityLabel; public TimeSpan Time { get; set; } private DetectionClass _detectionClass = null!; public DetectionClass DetectionClass { get => _detectionClass; set { _grid.Background = value.ColorBrush; _probabilityLabel.Background = value.ColorBrush; _classNameLabel.Text = value.Name; _detectionClass = value; } } private readonly Rectangle _selectionFrame; private bool _isSelected; public bool IsSelected { get => _isSelected; set { _selectionFrame.Visibility = value ? Visibility.Visible : Visibility.Collapsed; _isSelected = value; } } public DetectionControl(DetectionClass detectionClass, TimeSpan time, Action resizeStart, double? probability = null) { Time = time; _resizeStart = resizeStart; _classNameLabel = new TextBlock { Text = detectionClass.Name, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top, Margin = new Thickness(0, 15, 0, 0), FontSize = 14, Cursor = Cursors.SizeAll }; _probabilityLabel = new Label { Content = probability.HasValue ? $"{probability.Value*100:F0}%" : string.Empty, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Top, Margin = new Thickness(0, -32, 0, 0), FontSize = 16, Visibility = Visibility.Visible }; _selectionFrame = new Rectangle { HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch, Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 2, Visibility = Visibility.Collapsed }; _grid = new Grid { HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch, Children = { _selectionFrame, _classNameLabel, AddRect("rLT", HorizontalAlignment.Left, VerticalAlignment.Top, Cursors.SizeNWSE), AddRect("rCT", HorizontalAlignment.Center, VerticalAlignment.Top, Cursors.SizeNS), AddRect("rRT", HorizontalAlignment.Right, VerticalAlignment.Top, Cursors.SizeNESW), AddRect("rLC", HorizontalAlignment.Left, VerticalAlignment.Center, Cursors.SizeWE), AddRect("rRC", HorizontalAlignment.Right, VerticalAlignment.Center, Cursors.SizeWE), AddRect("rLB", HorizontalAlignment.Left, VerticalAlignment.Bottom, Cursors.SizeNESW), AddRect("rCB", HorizontalAlignment.Center, VerticalAlignment.Bottom, Cursors.SizeNS), AddRect("rRB", HorizontalAlignment.Right, VerticalAlignment.Bottom, Cursors.SizeNWSE) } }; if (probability.HasValue) _grid.Children.Add(_probabilityLabel); Child = _grid; Cursor = Cursors.SizeAll; DetectionClass = detectionClass; } //small corners private Rectangle AddRect(string name, HorizontalAlignment ha, VerticalAlignment va, Cursor crs) { var rect = new Rectangle() // small rectangles at the corners and sides { HorizontalAlignment = ha, VerticalAlignment = va, Width = RESIZE_RECT_SIZE, Height = RESIZE_RECT_SIZE, Stroke = new SolidColorBrush(Color.FromArgb(230, 40, 40, 40)), // small rectangles color Fill = new SolidColorBrush(Color.FromArgb(1, 255, 255, 255)), Cursor = crs, Name = name, }; rect.MouseDown += (sender, args) => _resizeStart(sender, args); return rect; } public YoloLabel GetLabel(Size canvasSize, Size? videoSize = null) { var label = new CanvasLabel(DetectionClass.Id, Canvas.GetLeft(this), Canvas.GetTop(this), Width, Height); return new YoloLabel(label, canvasSize, videoSize); } }