| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- 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 : IImageEditorStateObject
- {
- 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;
- private ImageEditorState _state = new(1.0);
- 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 SetState(ImageEditorState state)
- {
- _state = state;
- 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 thumbSize = 30;
- if(Thumb is not null)
- {
- Thumb.RenderTransform = new TransformGroup
- {
- Children = [
- new RotateTransform(Math.Atan2(mainVec.Y, mainVec.X) * 180 / Math.PI),
- new ScaleTransform(1 / _state.ScaleFactor, 1 / _state.ScaleFactor)
- ]
- };
- Thumb.BorderThickness = new(1);
- Thumb.Width = thumbSize;
- Thumb.Height = thumbSize;
- var thumbPos = p1 + offset + mainVec * length / 2;
- Canvas.SetLeft(Thumb, thumbPos.X - thumbSize / 2);
- Canvas.SetTop(Thumb, thumbPos.Y - thumbSize / 2);
- }
- }
- 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);
- var thumbSize = 30;
- if(Thumb is null && _active && length > 0)
- {
- Thumb = new();
- Thumb.Cursor = new(StandardCursorType.SizeAll);
- Thumb.DragDelta += Thumb_DragDelta;
- Thumb.ZIndex = 1;
- Control.Children.Add(Thumb);
- }
- if(Thumb is not null)
- {
- Thumb.RenderTransform = new TransformGroup
- {
- Children = [
- new RotateTransform(Math.Atan2(mainVec.Y, mainVec.X) * 180 / Math.PI),
- new ScaleTransform(1 / _state.ScaleFactor, 1 / _state.ScaleFactor)
- ]
- };
- Thumb.BorderThickness = new(1);
- Thumb.Width = thumbSize;
- Thumb.Height = thumbSize;
- var thumbPos = p1 + offset + mainVec * length / 2;
- Canvas.SetLeft(Thumb, thumbPos.X - thumbSize / 2);
- Canvas.SetTop(Thumb, thumbPos.Y - thumbSize / 2);
- }
- }
- 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()) / _state.ScaleFactor;
- Offset += v;
- Update();
- }
- public void SetActive(bool active)
- {
- _active = active;
- if(Thumb is not null)
- {
- Control.Children.Remove(Thumb);
- Thumb = null;
- }
- }
- }
|