From 0a2d3f2dd8b51fb2993c7299bef6b673c89099be Mon Sep 17 00:00:00 2001 From: Wouter Date: Mon, 31 Aug 2020 23:05:35 +0200 Subject: [PATCH] Added ZoomFactor property to networkviewmodel. Fixes #81. --- NodeNetwork/ViewModels/NetworkViewModel.cs | 22 +++++++++- NodeNetwork/Views/Controls/DragCanvas.cs | 49 +++++++++++++++++----- NodeNetwork/Views/NetworkView.xaml.cs | 5 +++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/NodeNetwork/ViewModels/NetworkViewModel.cs b/NodeNetwork/ViewModels/NetworkViewModel.cs index a311b5a..e86a24b 100644 --- a/NodeNetwork/ViewModels/NetworkViewModel.cs +++ b/NodeNetwork/ViewModels/NetworkViewModel.cs @@ -148,7 +148,27 @@ public bool IsReadOnly /// public CutLineViewModel CutLine { get; } = new CutLineViewModel(); #endregion - + + #region ZoomFactor + /// + /// Scale of the view. Larger means more zoomed in. Default value is 1. Must be greater than zero. + /// + public double ZoomFactor + { + get => _zoomFactor; + set + { + if (value <= 0) + { + throw new ArgumentException("ZoomFactor must be greater than zero"); + } + this.RaiseAndSetIfChanged(ref _zoomFactor, value); + } + } + + private double _zoomFactor = 1; + #endregion + #region SelectionRectangle /// /// The viewmodel for the selection rectangle used in this network view. diff --git a/NodeNetwork/Views/Controls/DragCanvas.cs b/NodeNetwork/Views/Controls/DragCanvas.cs index 0bc2e07..f7e3c80 100644 --- a/NodeNetwork/Views/Controls/DragCanvas.cs +++ b/NodeNetwork/Views/Controls/DragCanvas.cs @@ -157,14 +157,32 @@ private void ApplyDragToChildren(DragMoveEventArgs drag) #endregion #region Zoom - public delegate void ZoomEvent(object source, ZoomEventArgs args); - public event ZoomEvent Zoom; + public event EventHandler Zoom; private int _wheelOffset = 6; private const int MinWheelOffset = 1; private const int MaxWheelOffset = 15; - - private ScaleTransform _curScaleTransform = new ScaleTransform(1.0, 1.0); + + #region ZoomFactor + public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register(nameof(ZoomFactor), + typeof(double), typeof(DragCanvas), new PropertyMetadata(1d, OnZoomFactorPropChanged)); + + public double ZoomFactor + { + get => (double)GetValue(ZoomFactorProperty); + set => SetValue(ZoomFactorProperty, value); + } + private bool isUpdatingZoomFactor; + #endregion + + private static void OnZoomFactorPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + DragCanvas dc = (DragCanvas)d; + if(!dc.isUpdatingZoomFactor) + { + dc.SetZoomImpl(new Point(dc.ActualWidth / 2, dc.ActualHeight / 2), (double)e.OldValue, (double)e.NewValue, null); + } + } private Rect ZoomView(Rect curView, double curZoom, double newZoom, Point relZoomPoint) //curView in content space, relZoomPoint is relative to view space { @@ -199,9 +217,21 @@ protected override void OnMouseWheel(MouseWheelEventArgs e) _wheelOffset = MaxWheelOffset; } - double oldScale = _curScaleTransform.ScaleX; + Point zoomCenter = e.GetPosition(this); double newScale = Math.Log(1 + ((_wheelOffset) / 10d)) * 2d; + SetZoom(zoomCenter, newScale, e); + } + + public void SetZoom(Point zoomCenter, double newScale, MouseEventArgs parentEvent) + { + SetZoomImpl(zoomCenter, ZoomFactor, newScale, parentEvent); + isUpdatingZoomFactor = true; + ZoomFactor = newScale; + isUpdatingZoomFactor = false; + } + private void SetZoomImpl(Point zoomCenter, double oldScale, double newScale, MouseEventArgs parentEvent) + { //Calculate current viewing window onto the content Point topLeftContentSpace = TranslatePoint(new Point(0, 0), Children[0]); Point bottomRightContentSpace = TranslatePoint(new Point(ActualWidth, ActualHeight), Children[0]); @@ -212,11 +242,10 @@ protected override void OnMouseWheel(MouseWheelEventArgs e) }; //Mouse position as a fraction of the view size - Point viewSpaceMousePos = e.GetPosition(this); Point relZoomPoint = new Point { - X = viewSpaceMousePos.X / this.ActualWidth, - Y = viewSpaceMousePos.Y / this.ActualHeight + X = zoomCenter.X / this.ActualWidth, + Y = zoomCenter.Y / this.ActualHeight }; //Calculate new viewing window @@ -232,12 +261,10 @@ protected override void OnMouseWheel(MouseWheelEventArgs e) ScaleY = newScale }; - var zoomEvent = new ZoomEventArgs(e, _curScaleTransform, newScaleTransform, newOffset); + var zoomEvent = new ZoomEventArgs(parentEvent, new ScaleTransform(oldScale, oldScale), newScaleTransform, newOffset); Zoom?.Invoke(this, zoomEvent); ApplyZoomToChildren(zoomEvent); - - _curScaleTransform = newScaleTransform; } private void ApplyZoomToChildren(ZoomEventArgs e) diff --git a/NodeNetwork/Views/NetworkView.xaml.cs b/NodeNetwork/Views/NetworkView.xaml.cs index 31c4524..8b82f28 100644 --- a/NodeNetwork/Views/NetworkView.xaml.cs +++ b/NodeNetwork/Views/NetworkView.xaml.cs @@ -257,6 +257,11 @@ private void SetupCutLine() private void SetupViewportBinding() { + this.WhenActivated(d => + { + this.Bind(ViewModel, vm => vm.ZoomFactor, v => v.dragCanvas.ZoomFactor); + }); + Binding binding = new Binding { Source = this,