PreviewerControl.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System.Collections.ObjectModel;
  2. using Avalonia;
  3. using Avalonia.Controls;
  4. using Avalonia.Input;
  5. using Avalonia.Media;
  6. using Avalonia.Threading;
  7. namespace QuestPDF.Previewer
  8. {
  9. class PreviewerControl : Control
  10. {
  11. private InteractiveCanvas InteractiveCanvas { get; set; } = new();
  12. public static readonly StyledProperty<float> CurrentScrollProperty = AvaloniaProperty.Register<PreviewerControl, float>(nameof(CurrentScroll));
  13. public float CurrentScroll
  14. {
  15. get => GetValue(CurrentScrollProperty);
  16. set => SetValue(CurrentScrollProperty, value);
  17. }
  18. public static readonly StyledProperty<float> ScrollViewportSizeProperty = AvaloniaProperty.Register<PreviewerControl, float>(nameof(ScrollViewportSize));
  19. public float ScrollViewportSize
  20. {
  21. get => GetValue(ScrollViewportSizeProperty);
  22. set => SetValue(ScrollViewportSizeProperty, value);
  23. }
  24. public PreviewerControl()
  25. {
  26. CommunicationService.Instance.OnDocumentUpdated += document =>
  27. {
  28. InteractiveCanvas.SetNewDocumentStructure(document);
  29. Dispatcher.UIThread.InvokeAsync(InvalidateVisual).GetTask();
  30. };
  31. CommunicationService.Instance.OnPageSnapshotsRequested += InteractiveCanvas.GetMissingSnapshots;
  32. CommunicationService.Instance.OnPageSnapshotsProvided += snapshots =>
  33. {
  34. InteractiveCanvas.AddSnapshots(snapshots);
  35. Dispatcher.UIThread.InvokeAsync(InvalidateVisual).GetTask();
  36. };
  37. CurrentScrollProperty.Changed.Subscribe(x =>
  38. {
  39. InteractiveCanvas.ScrollPercentY = x.NewValue.Value;
  40. Dispatcher.UIThread.InvokeAsync(InvalidateVisual).GetTask();
  41. });
  42. ClipToBounds = true;
  43. }
  44. protected override void OnPointerWheelChanged(PointerWheelEventArgs e)
  45. {
  46. base.OnPointerWheelChanged(e);
  47. if ((e.KeyModifiers & KeyModifiers.Control) != 0)
  48. {
  49. var scaleFactor = 1 + e.Delta.Y / 10f;
  50. var point = new Point(Bounds.Center.X, Bounds.Top) - e.GetPosition(this);
  51. InteractiveCanvas.ZoomToPoint((float)point.X, -(float)point.Y, (float)scaleFactor);
  52. }
  53. if (e.KeyModifiers == KeyModifiers.None)
  54. {
  55. var translation = (float)e.Delta.Y * 25;
  56. InteractiveCanvas.TranslateWithCurrentScale(0, -translation);
  57. }
  58. InvalidateVisual();
  59. }
  60. private bool IsMousePressed { get; set; }
  61. private Vector MousePosition { get; set; }
  62. protected override void OnPointerMoved(PointerEventArgs e)
  63. {
  64. base.OnPointerMoved(e);
  65. if (IsMousePressed)
  66. {
  67. var currentPosition = e.GetPosition(this);
  68. var translation = currentPosition - MousePosition;
  69. InteractiveCanvas.TranslateWithCurrentScale((float)translation.X, -(float)translation.Y);
  70. InvalidateVisual();
  71. }
  72. MousePosition = e.GetPosition(this);
  73. }
  74. protected override void OnPointerPressed(PointerPressedEventArgs e)
  75. {
  76. base.OnPointerPressed(e);
  77. IsMousePressed = true;
  78. }
  79. protected override void OnPointerReleased(PointerReleasedEventArgs e)
  80. {
  81. base.OnPointerReleased(e);
  82. IsMousePressed = false;
  83. }
  84. public override void Render(DrawingContext context)
  85. {
  86. CurrentScroll = InteractiveCanvas.ScrollPercentY;
  87. ScrollViewportSize = InteractiveCanvas.ScrollViewportSizeY;
  88. InteractiveCanvas.RenderingScale = (float)VisualRoot.RenderScaling;
  89. InteractiveCanvas.Bounds = new Rect(0, 0, Bounds.Width, Bounds.Height);
  90. context.Custom(InteractiveCanvas);
  91. base.Render(context);
  92. }
  93. }
  94. }