diff --git a/Wabbajack/Views/ManifestView.xaml b/Wabbajack/Views/ManifestView.xaml index e2c9860d..d391f82f 100644 --- a/Wabbajack/Views/ManifestView.xaml +++ b/Wabbajack/Views/ManifestView.xaml @@ -7,7 +7,8 @@ xmlns:reactiveUi="http://reactiveui.net" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> - + + - + @@ -57,4 +58,6 @@ + + diff --git a/Wabbajack/Views/ManifestView.xaml.cs b/Wabbajack/Views/ManifestView.xaml.cs index 22ac66ac..646d7ec5 100644 --- a/Wabbajack/Views/ManifestView.xaml.cs +++ b/Wabbajack/Views/ManifestView.xaml.cs @@ -1,8 +1,13 @@ using System; using System.Diagnostics; using System.Reactive.Disposables; +using System.Windows; +using System.Windows.Controls; using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; using System.Windows.Navigation; +using System.Windows.Shapes; using ReactiveUI; using Wabbajack.Lib; @@ -55,5 +60,76 @@ namespace Wabbajack e.Handled = true; } + + //solution from https://stackoverflow.com/questions/5426232/how-can-i-make-wpf-scrollviewer-middle-click-scroll/5446307#5446307 + + private bool _isMoving; //False - ignore mouse movements and don't scroll + private bool _isDeferredMovingStarted; //True - Mouse down -> Mouse up without moving -> Move; False - Mouse down -> Move + private Point? _startPosition; + private const double Slowdown = 10; //smaller = faster + + private void ScrollViewer_MouseDown(object sender, MouseButtonEventArgs e) + { + if (_isMoving) + CancelScrolling(); + else if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Pressed) + { + if (_isMoving) return; + + _isMoving = true; + _startPosition = e.GetPosition(sender as IInputElement); + _isDeferredMovingStarted = true; + + AddScrollSign(e.GetPosition(TopLayer).X, e.GetPosition(TopLayer).Y); + } + } + + private void ScrollViewer_MouseUp(object sender, MouseButtonEventArgs e) + { + if(e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Released && _isDeferredMovingStarted != true) + CancelScrolling(); + } + + private void ScrollViewer_MouseMove(object sender, MouseEventArgs e) + { + if (!_isMoving || !(sender is ScrollViewer sv)) + return; + + _isDeferredMovingStarted = false; + + var currentPosition = e.GetPosition(sv); + if (_startPosition == null) + return; + + var offset = currentPosition - _startPosition.Value; + offset.Y /= Slowdown; + offset.X /= Slowdown; + + sv.ScrollToVerticalOffset(sv.VerticalOffset + offset.Y); + sv.ScrollToHorizontalOffset(sv.HorizontalOffset + offset.X); + } + + private void CancelScrolling() + { + _isMoving = false; + _startPosition = null; + _isDeferredMovingStarted = false; + RemoveScrollSign(); + } + + private void AddScrollSign(double x, double y) + { + const double size = 50.0; + var icon = new Ellipse { Stroke = Brushes.Red, StrokeThickness = 2.0, Width = 20, Height = 20 }; + + TopLayer.Children.Add(icon); + Canvas.SetLeft(icon, x - size / 2); + Canvas.SetTop(icon, y - size / 2); + } + + private void RemoveScrollSign() + { + TopLayer.Children.Clear(); + } } }