AB4D Forum
Click-thru with Drag Pan enabled after drag detected - Printable Version

+- AB4D Forum (https://forum.ab4d.com)
+-- Forum: Products Forums (https://forum.ab4d.com/forumdisplay.php?fid=4)
+--- Forum: ZoomPanel (https://forum.ab4d.com/forumdisplay.php?fid=8)
+--- Thread: Click-thru with Drag Pan enabled after drag detected (/showthread.php?tid=3971)



Click-thru with Drag Pan enabled after drag detected - jaredthirsk - 04-06-2016

Hi,

I am trying out the ZoomPanel and trying to replicate something I have created using WPF ScrollViewer:

1. Left click inside the scrollable area to click controls on a Canvas inside the ScrollViewer.
2. Press and hold left mouse button to drag. Mouse events are not passed to controls inside the ScrollViewer.

Is it possible to do this in ZoomPanel? I have tried setting ZoomMode
to ZoomOut, which allows me to left click things inside the ZoomPanel. I then do drag detection while the mouse button is pressed. If it moves so many pixels,
I set ZoomMode to Move, and the cursor changes but it doesn't actually start dragging anything. Perhaps there is a private StartDragPan method in there somewhere?

Thanks,
-Jared


RE: Click-thru with Drag Pan enabled after drag detected - abenedik - 04-07-2016

This is a very interesting question.

The following code can be used to subscribe to mouse events and manually zoom and pan the content of ZoomPanel (this also allows using Click events):

Code:
private bool _isMouseDown;
        private bool _isTranslating;

        private Point _lastMousePosition;

        public ManualZoomPanelControl()
        {
            InitializeComponent();

            // Disable all zooming and panning of ZoomPanel
            // We will do that with
            ZoomPanel1.ZoomMode = Controls.ZoomPanel.ZoomModeType.None;

            ZoomPanel1.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
            {
                // Start with storing the current mouse position
                _lastMousePosition = e.GetPosition(ZoomPanel1);
                _isMouseDown = true;
            };

            ZoomPanel1.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e)
            {
                if (!_isMouseDown)
                    return; // This can happen is user pressed mouse down on some other control and released the button on ZoomPanel

                _isMouseDown = false;

                if (_isTranslating)
                {
                    // If we were translating, stop translating and release mouse capture
                    _isTranslating = false;
                    ZoomPanel1.ReleaseMouseCapture();
                }
                else
                {
                    // If we were not translating then this is a Click (a MouseLeftButtonDown was hit before - _isMouseDown was true)
                    OnClick(e);
                }
            };

            ZoomPanel1.MouseMove += delegate(object sender, MouseEventArgs e)
            {
                if (e.LeftButton != MouseButtonState.Pressed) // Skip this code if mouse button is not pressed
                {
                    _isMouseDown = false;
                    return;
                }

                var currentMousePosition = e.GetPosition(ZoomPanel1);

                // Get a vector from the previous mouse position to the current mouse position
                var mouseMoveVector = currentMousePosition - _lastMousePosition;

                // IF we are not translating and the mouse has moved for more than 1 pixel,
                // then we start translating
                if (!_isTranslating && mouseMoveVector.LengthSquared > 1)
                {
                    _isTranslating = true;

                    // Capture mouse so that we get mouse events also in cases when mouse leaves our application
                    ZoomPanel1.CaptureMouse();
                }

                if (_isTranslating)
                {
                    // Call TranslateNow that translates the content of ZoomPanel for the x and y difference
                    ZoomPanel1.TranslateNow(mouseMoveVector.X, mouseMoveVector.Y);

                    // Save the current position
                    _lastMousePosition = currentMousePosition;
                }
            };

            // Manually handle Mouse Wheel zoom in and out
            ZoomPanel1.MouseWheel += delegate(object sender, MouseWheelEventArgs e)
            {
                double zoomFactor;

                if (e.Delta > 0)
                    zoomFactor = ZoomPanel1.MouseWheelZoomFactor; // Zoom in
                else
                    zoomFactor = 1 / ZoomPanel1.MouseWheelZoomFactor; // Zoom out


                // If IsZoomPositionPreserved is true then we zoom in and out into the current mouse position
                if (ZoomPanel1.IsZoomPositionPreserved)
                {
                    var currentMousePosition = e.GetPosition(ZoomPanel1);
                    ZoomPanel1.ZoomAtMousePosition(zoomFactor, currentMousePosition);
                }
                else
                {
                    // Just zoom in or out into the center of the ZoomPanel's content
                    ZoomPanel1.ZoomForFactor(zoomFactor);
                }
            };
        }

        private void OnClick(MouseEventArgs e)
        {
            var currentMousePosition = e.GetPosition(ZoomPanel1);

            MessageBox.Show(string.Format("Mouse clicked at:\r\n{0:0}", currentMousePosition));
        }

The code will be part of the samples in the next version of ZoomPanel.