|
|
@@ -1,6 +1,7 @@
|
|
|
using Avalonia;
|
|
|
using Avalonia.Controls;
|
|
|
using Avalonia.Input;
|
|
|
+using Avalonia.Interactivity;
|
|
|
using Avalonia.Markup.Xaml;
|
|
|
using Avalonia.Media;
|
|
|
using DynamicData.Binding;
|
|
|
@@ -34,15 +35,7 @@ public partial class DocumentViewer : UserControl
|
|
|
set => SetValue(DataProperty, value);
|
|
|
}
|
|
|
|
|
|
- private double ScaleFactor = 1.0;
|
|
|
- private double _originalScaleFactor = 1.0;
|
|
|
- private double _startScaleFactor = 1.0;
|
|
|
-
|
|
|
- // Center of the image.
|
|
|
- private Point ImageCenter = new();
|
|
|
private IImage? _image;
|
|
|
- private double ImageWidth => _image?.Size.Width ?? 0;
|
|
|
- private double ImageHeight => _image?.Size.Height ?? 0;
|
|
|
|
|
|
public DocumentViewer()
|
|
|
{
|
|
|
@@ -50,101 +43,15 @@ public partial class DocumentViewer : UserControl
|
|
|
|
|
|
this.GetPropertyChangedObservable(FileNameProperty).Subscribe(x => Update().ContinueWith(ContinueTask));
|
|
|
this.GetPropertyChangedObservable(DataProperty).Subscribe(x => Update().ContinueWith(ContinueTask));
|
|
|
-
|
|
|
- OuterCanvas.AddHandler(PanAndZoomGestureRecognizer.PanAndZoomEndedEvent, ImageContainer_PinchEnded);
|
|
|
- OuterCanvas.AddHandler(PanAndZoomGestureRecognizer.PanAndZoomEvent, ImageContainer_Pinch);
|
|
|
-
|
|
|
- OuterCanvas.PointerWheelChanged += OuterCanvas_PointerWheelChanged;
|
|
|
- }
|
|
|
-
|
|
|
- private const double _wheelSpeed = 0.1;
|
|
|
- private const double _panSpeed = 30;
|
|
|
-
|
|
|
- private void Pan(double x, double y)
|
|
|
- {
|
|
|
- ImageCenter += new Vector(x, y);
|
|
|
- UpdateCanvasPosition();
|
|
|
- }
|
|
|
-
|
|
|
- private void OuterCanvas_PointerWheelChanged(object? sender, PointerWheelEventArgs e)
|
|
|
- {
|
|
|
- if (e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
|
|
- {
|
|
|
- var pos = e.GetPosition(OuterCanvas);
|
|
|
- var wheelSpeed = _wheelSpeed;
|
|
|
- Zoom(pos, pos, e.Delta.Y > 0 ? ScaleFactor * (1 + e.Delta.Y * wheelSpeed) : ScaleFactor / (1 + (-e.Delta.Y) * wheelSpeed));
|
|
|
- }
|
|
|
- else if(e.KeyModifiers.HasFlag(KeyModifiers.Shift))
|
|
|
- {
|
|
|
- Pan(e.Delta.Y * _panSpeed, e.Delta.X * _panSpeed);
|
|
|
- }
|
|
|
- else
|
|
|
+
|
|
|
+ Image.GetPropertyChangedObservable(Image.SourceProperty).Subscribe(x =>
|
|
|
{
|
|
|
- Pan(e.Delta.X * _panSpeed, e.Delta.Y * _panSpeed);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void ImageContainer_Pinch(object? sender, PanAndZoomEventArgs e)
|
|
|
- {
|
|
|
- Zoom(e.ScaleOrigin - e.Pan, e.ScaleOrigin, _originalScaleFactor * e.Scale);
|
|
|
- }
|
|
|
-
|
|
|
- private void ImageContainer_PinchEnded(object? sender, PanAndZoomEndedEventArgs e)
|
|
|
- {
|
|
|
- _originalScaleFactor = ScaleFactor;
|
|
|
- }
|
|
|
-
|
|
|
- private void Zoom(Point originalOrigin, Point newOrigin, double newScaleFactor)
|
|
|
- {
|
|
|
- // Convert Scale Origin to image coordinates (relative to center).
|
|
|
- // Work out where this position will move to under the new scaling.
|
|
|
- // Adjust so that these are the same.
|
|
|
-
|
|
|
- var pos = originalOrigin - ImageCenter;
|
|
|
- var contentMPos = pos / ScaleFactor;
|
|
|
-
|
|
|
- ScaleFactor = Math.Max(_startScaleFactor, newScaleFactor);
|
|
|
-
|
|
|
- var scaledPos = ImageCenter + contentMPos * ScaleFactor;
|
|
|
- var offset = scaledPos - newOrigin;
|
|
|
-
|
|
|
- ImageCenter -= offset;
|
|
|
-
|
|
|
- UpdateCanvasPosition();
|
|
|
- }
|
|
|
-
|
|
|
- private void PositionImage()
|
|
|
- {
|
|
|
- if (ImageWidth == 0 || ImageHeight == 0) return;
|
|
|
-
|
|
|
- var canvasWidth = OuterCanvas.Bounds.Width;
|
|
|
- var canvasHeight = OuterCanvas.Bounds.Height;
|
|
|
-
|
|
|
- var scaleFactor = Math.Min(canvasWidth / ImageWidth, canvasHeight / ImageHeight);
|
|
|
- ScaleFactor = scaleFactor;
|
|
|
- _originalScaleFactor = ScaleFactor;
|
|
|
- _startScaleFactor = ScaleFactor;
|
|
|
-
|
|
|
- ImageCenter = new Point(
|
|
|
- OuterCanvas.Bounds.Width / 2,
|
|
|
- OuterCanvas.Bounds.Height / 2);
|
|
|
-
|
|
|
- UpdateCanvasPosition();
|
|
|
- }
|
|
|
-
|
|
|
- private void UpdateCanvasPosition()
|
|
|
- {
|
|
|
- var imageWidth = ImageWidth * ScaleFactor;
|
|
|
- var imageHeight = ImageHeight * ScaleFactor;
|
|
|
-
|
|
|
- Image.Width = imageWidth;
|
|
|
- Image.Height = imageHeight;
|
|
|
-
|
|
|
- Canvas.SetLeft(Image, ImageCenter.X - imageWidth / 2);
|
|
|
- Canvas.SetTop(Image, ImageCenter.Y - imageHeight / 2);
|
|
|
-
|
|
|
- // OuterCanvas.Width = ImageWidth;
|
|
|
- // OuterCanvas.Height = ImageHeight;
|
|
|
+ if (Image.Source is not null)
|
|
|
+ {
|
|
|
+ Image.Width = Image.Source.Size.Width;
|
|
|
+ Image.Height = Image.Source.Size.Height;
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
private void ContinueTask(Task task)
|
|
|
@@ -172,7 +79,7 @@ public partial class DocumentViewer : UserControl
|
|
|
{
|
|
|
_image = ByteArrayToImageSourceConverter.Instance.Convert(bitmap);
|
|
|
Image.Source = _image;
|
|
|
- PositionImage();
|
|
|
+ // PositionImage();
|
|
|
Image.IsVisible = true;
|
|
|
NoImage.IsVisible = false;
|
|
|
return;
|