ConnectionLine.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using Avalonia;
  2. using Avalonia.Controls;
  3. using Avalonia.Media;
  4. namespace PixiEditor.AvaloniaUI.Views.Nodes;
  5. public class ConnectionLine : Control
  6. {
  7. private Pen pen = new() { LineCap = PenLineCap.Round };
  8. public static readonly StyledProperty<LinearGradientBrush> ColorProperty = AvaloniaProperty.Register<ConnectionLine, LinearGradientBrush>("Color");
  9. public static readonly StyledProperty<double> ThicknessProperty = AvaloniaProperty.Register<ConnectionLine, double>("Thickness");
  10. public static readonly StyledProperty<Point> StartPointProperty = AvaloniaProperty.Register<ConnectionLine, Point>("StartPoint");
  11. public static readonly StyledProperty<Point> EndPointProperty = AvaloniaProperty.Register<ConnectionLine, Point>("EndPoint");
  12. public LinearGradientBrush LineBrush
  13. {
  14. get { return GetValue(ColorProperty); }
  15. set { SetValue(ColorProperty, value); }
  16. }
  17. public double Thickness
  18. {
  19. get { return (double)GetValue(ThicknessProperty); }
  20. set { SetValue(ThicknessProperty, value); }
  21. }
  22. public Point StartPoint
  23. {
  24. get { return (Point)GetValue(StartPointProperty); }
  25. set { SetValue(StartPointProperty, value); }
  26. }
  27. public Point EndPoint
  28. {
  29. get { return (Point)GetValue(EndPointProperty); }
  30. set { SetValue(EndPointProperty, value); }
  31. }
  32. static ConnectionLine()
  33. {
  34. AffectsRender<ConnectionLine>(ColorProperty, ThicknessProperty, StartPointProperty, EndPointProperty);
  35. }
  36. public override void Render(DrawingContext context)
  37. {
  38. var p1 = new Point(StartPoint.X, StartPoint.Y);
  39. var p2 = new Point(EndPoint.X, EndPoint.Y);
  40. // curved line
  41. var controlPoint = new Point((p1.X + p2.X) / 2, p1.Y);
  42. var controlPoint2 = new Point((p1.X + p2.X) / 2, p2.Y);
  43. if (p1.X < p2.X)
  44. {
  45. p1 = new Point(p1.X - 5, p1.Y);
  46. p2 = new Point(p2.X + 5, p2.Y);
  47. controlPoint2 = new Point(p2.X, (p1.Y + p2.Y) / 2);
  48. controlPoint = new Point(p1.X, (p1.Y + p2.Y) / 2);
  49. }
  50. var geometry = new StreamGeometry();
  51. using var ctx = geometry.Open();
  52. ctx.BeginFigure(p1, false);
  53. ctx.CubicBezierTo(controlPoint, controlPoint2, p2);
  54. LineBrush.StartPoint = new RelativePoint(p1.X, p1.Y, RelativeUnit.Absolute);
  55. LineBrush.EndPoint = new RelativePoint(p2.X, p2.Y, RelativeUnit.Absolute);
  56. pen.Brush = LineBrush;
  57. pen.Thickness = Thickness;
  58. context.DrawGeometry(LineBrush, pen, geometry);
  59. }
  60. }