PreviewerControl.cs 3.9 KB

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