Exemple #1
0
        protected override void OnMouseWheel(MouseWheelEventArgs args)
        {
            base.OnMouseWheel(args);

            // If there is a mouse op in progress, forward the event
            var op = MouseOperations.Active;

            if (op != null && !op.Cancelled)
            {
                op.MouseWheel(args);
                if (args.Handled)
                {
                    return;
                }
            }

            var location  = args.GetPosition(this);
            var along_ray = Options.MouseCentredZoom || Keyboard.Modifiers.HasFlag(ModifierKeys.Alt);
            var chart_pt  = ClientToChart(location);
            var hit       = HitTestZoneCS(location, Keyboard.Modifiers, args.ToMouseBtns());

            // Batch mouse wheel events into 100ms groups
            var defer_nav_checkpoint = DeferNavCheckpoints();

            Dispatcher_.BeginInvokeDelayed(() =>
            {
                Util.Dispose(ref defer_nav_checkpoint !);
                SaveNavCheckpoint();
            }, TimeSpan.FromMilliseconds(100));

            var scale = 0.001f;

            if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
            {
                scale *= 0.1f;
            }
            if (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt))
            {
                scale *= 0.01f;
            }
            var delta = Math_.Clamp(args.Delta * scale, -0.999f, 0.999f);
            var chg   = (string?)null;

            // If zooming is allowed on both axes, translate the camera
            if (hit.Zone == EZone.Chart && XAxis.AllowZoom && YAxis.AllowZoom)
            {
                // Translate the camera along a ray through 'point'
                var loc = Gui_.MapPoint(this, Scene, location);
                Scene.Window.MouseNavigateZ(loc.ToPointF(), args.ToMouseBtns(Keyboard.Modifiers), args.Delta, along_ray);
                chg = nameof(SetRangeFromCamera);
            }

            // Otherwise, zoom on the allowed axis only
            else if (hit.Zone == EZone.XAxis || (hit.Zone == EZone.Chart && !YAxis.AllowZoom))
            {
                if (hit.ModifierKeys.HasFlag(ModifierKeys.Control) && XAxis.AllowScroll)
                {
                    // Scroll the XAxis
                    XAxis.Shift(XAxis.Span * delta);
                    chg = nameof(SetCameraFromRange);
                }
                else if (!hit.ModifierKeys.HasFlag(ModifierKeys.Control) && XAxis.AllowZoom)
                {
                    // Change the aspect ratio by zooming on the XAxis
                    var x    = along_ray ? chart_pt.X : XAxis.Centre;
                    var left = (XAxis.Min - x) * (1f - delta);
                    var rite = (XAxis.Max - x) * (1f - delta);
                    XAxis.Set(x + left, x + rite);
                    if (Options.LockAspect != null)
                    {
                        YAxis.Span *= (1f - delta);
                    }

                    chg = nameof(SetCameraFromRange);
                }
            }
            else if (hit.Zone == EZone.YAxis || (hit.Zone == EZone.Chart && !XAxis.AllowZoom))
            {
                if (hit.ModifierKeys.HasFlag(ModifierKeys.Control) && YAxis.AllowScroll)
                {
                    // Scroll the YAxis
                    YAxis.Shift(YAxis.Span * delta);
                    chg = nameof(SetCameraFromRange);
                }
                else if (!hit.ModifierKeys.HasFlag(ModifierKeys.Control) && YAxis.AllowZoom)
                {
                    // Change the aspect ratio by zooming on the YAxis
                    var y    = along_ray ? chart_pt.Y : YAxis.Centre;
                    var left = (YAxis.Min - y) * (1f - delta);
                    var rite = (YAxis.Max - y) * (1f - delta);
                    YAxis.Set(y + left, y + rite);
                    if (Options.LockAspect != null)
                    {
                        XAxis.Span *= (1f - delta);
                    }

                    chg = nameof(SetCameraFromRange);
                }
            }

            switch (chg)
            {
            // Update the axes from the camera position
            case nameof(SetRangeFromCamera):
                SetRangeFromCamera();
                NotifyPropertyChanged(nameof(ValueAtPointer));
                Invalidate();
                break;

            // Set the camera position from the new axis ranges
            case nameof(SetCameraFromRange):
                SetCameraFromRange();
                NotifyPropertyChanged(nameof(ValueAtPointer));
                Invalidate();
                break;
            }
        }