| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 | using Avalonia;using Avalonia.Controls;using Avalonia.Controls.Primitives;using Avalonia.Controls.Shapes;using Avalonia.Input;using Avalonia.Media;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Xml;namespace InABox.Avalonia.Components.ImageEditing;internal class DimensionObject : IImageEditorObject{    public IBrush? PrimaryBrush { get; set; }    public Point Point1 { get; set; }    public Point Point2 { get; set; }    public double LineThickness { get; set; }    public string Text { get; set; } = "";    public double Offset { get; set; } = 10;    public bool Complete { get; set; } = false;    private Canvas Control = new();    private Thumb? Thumb;    private bool _active = true;    public Control GetControl() => Control;    private Vector GetMainVec()    {        var p1 = new Vector(Point1.X, Point1.Y);        var p2 = new Vector(Point2.X, Point2.Y);        var mainVec = p2 - p1;        var length = mainVec.Length;        if(length == 0)        {            mainVec = new Vector(0, 0);        }        else        {            mainVec /= length;        }        return mainVec;    }    private Vector GetPerpVec()    {        var mainVec = GetMainVec();        return new Vector(mainVec.Y, -mainVec.X);    }    public void Update()    {        Control.Children.RemoveAll(Control.Children.Where(x => !(x is Thumb)));        Point Point(Vector v) => new(v.X, v.Y);        var p1 = new Vector(Point1.X, Point1.Y);        var p2 = new Vector(Point2.X, Point2.Y);        var mainVec = p2 - p1;        var length = mainVec.Length;        if(length == 0)        {            mainVec = new Vector(0, 0);        }        else        {            mainVec /= length;        }        var perpVec = new Vector(mainVec.Y, -mainVec.X);        var arrowLength = LineThickness * 2;        var offset = perpVec * Offset;        var mainLines = new List<Line>()        {            new()            {                StartPoint = Point(p1 + offset),                EndPoint = Point(p2 + offset),                StrokeLineCap = PenLineCap.Round            },            new()            {                StartPoint = Point(p1 + offset),                EndPoint = Point(p1 + mainVec * arrowLength + perpVec * arrowLength + offset),                StrokeLineCap = PenLineCap.Square            },            new()            {                StartPoint = Point(p1 + offset),                EndPoint = Point(p1 + mainVec * arrowLength - perpVec * arrowLength + offset),                StrokeLineCap = PenLineCap.Square            },            new()            {                StartPoint = Point(p2 + offset),                EndPoint = Point(p2 - mainVec * arrowLength + perpVec * arrowLength + offset),                StrokeLineCap = PenLineCap.Square            },            new()            {                StartPoint = Point(p2 + offset),                EndPoint = Point(p2 - mainVec * arrowLength - perpVec * arrowLength + offset),                StrokeLineCap = PenLineCap.Square            }        };        var dotLines = new List<Line>()        {            new()            {                StartPoint = Point(p1),                EndPoint = Point(p1 + offset)            },            new()            {                StartPoint = Point(p2),                EndPoint = Point(p2 + offset)            },        };        foreach (var line in dotLines)        {            line.StrokeThickness = LineThickness;            line.Stroke = PrimaryBrush;            line.StrokeDashArray = [2, 2];            Control.Children.Add(line);        }        foreach (var line in mainLines)        {            line.StrokeThickness = LineThickness;            line.Stroke = PrimaryBrush;            Control.Children.Add(line);        }        var textHeight = 20;        var text = new TextBlock        {            Text = Text,            FontSize = textHeight,            TextAlignment = TextAlignment.Center,            Width = length,            Foreground = PrimaryBrush        };        text.RenderTransform = new RotateTransform(Math.Atan2(mainVec.Y, mainVec.X) * 180 / Math.PI);        var textPos = p1 + offset + mainVec * length / 2 + perpVec * (textHeight / 2 + 5);        Canvas.SetLeft(text, textPos.X - length / 2);        Canvas.SetTop(text, textPos.Y - textHeight / 2);        Control.Children.Add(text);        if(Thumb is null && _active && length > 0)        {            Thumb = new();            Thumb.Width = 10;            Thumb.Height = 10;            Thumb.Cursor = new(StandardCursorType.SizeAll);            Thumb.DragDelta += Thumb_DragDelta;            Thumb.ZIndex = 1;            Control.Children.Add(Thumb);        }        if(Thumb is not null)        {            Thumb.RenderTransform = new RotateTransform(Math.Atan2(mainVec.Y, mainVec.X) * 180 / Math.PI);            var thumbPos = p1 + offset + mainVec * length / 2;            Canvas.SetLeft(Thumb, thumbPos.X - 5);            Canvas.SetTop(Thumb, thumbPos.Y - 5);        }    }    private Vector Rotate(Vector v, double angle)    {        angle = Math.Atan2(v.Y, v.X) + angle;        var length = v.Length;        return new Vector(            length * Math.Cos(angle),            length * Math.Sin(angle));    }    private void Thumb_DragDelta(object? sender, VectorEventArgs e)    {        var main = GetMainVec();        var v = Vector.Dot(Rotate(e.Vector, Math.Atan2(main.Y, main.X)), GetPerpVec());        Offset += v;        Update();    }    public void SetActive(bool active)    {        _active = active;        if(Thumb is not null)        {            Control.Children.Remove(Thumb);            Thumb = null;        }    }}
 |