AB4D Forum

Full Version: Automatic pan when mouse going outside zoompanel
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

I'm using zoom panel for viewing and designing some kind of floor plans. I need feature when drawing my elements (lines, rectangles, etc.) that view automatically move (pan) when mouse try to go out of viewbox. How I can do this?

Regards
This is an interesting question.

To move the content of ZoomPanel from code you can use many methods, but probably the easiest to use is TranslateNow - for example:

ZoomPanel1.TranslateNow(mouseMoveVector.X, mouseMoveVector.Y);


You can see a sample on how to handle mouse mouse events to manually move the content with TranslateNow method if you check the source of the ManualZoomPanelControl.cs file in the ZoomPanel samples.


But this is only the simple part of the answer.

Now comes the tricky part.
The problem is that it is hard to get mouse events when mouse goes out of your control - for example if you subscribe to MouseMove event on ZoomPanel, you will not get that event when mouse is not over ZoomPanel. If there is some border or some other control around ZoomPanel, then you can also subscribe there. But still if mouse will go outside your application you will not get mouse events.

A solution to this is to call CaptureMouse method on ZoomPanel (or any other element that you have subscribed to MouseMove) - from that point on all mouse events will go only to this control - even if mouse is over the edge of your application (you can release mouse capture with ReleaseMouseCapture) - this is also demonstrated in the ManualZoomPanelControl sample - but there it is used only when mouse button is pressed over ZoomPanel.

If you would call CaptureMouse without any button pressed, then all mouse event will get to your control and no other part of UI (including Windows controls and other applications) will not get any mouse event. So this can be a serious problem. But maybe you will be fine with that if you will use a special keyboard to turn this mode on and off.

Another approach (better in my opinion) is to subscribe to MouseMove event on ZoomPanel and then define an invisible area at the edge of the ZoomPanel - for example 50 outer pixels of the ZoomPanel - if user would enter this area with the mouse, you would call TranslateNow method. You can translate only slightly when user just enters this ares (for example is 45 pixels from the edge of ZoomPanel) and translate more when user is on the edge. But if user would exit the ZoomPanel, there will be no translation.

I hope that any of those solutions will work well for you.
Here is a simple example of how to achieve that:

Code:
           // When mouse button is pressed (we are drawing) and mouse goes outside ZoomPanel,
           // we want to move into the direction of the mouse
           var zoomPanelPosition = e.GetPosition(ZoomPanel1);
           double dx, dy;

            if (zoomPanelPosition.X < 0)
                dx = zoomPanelPosition.X; // left of ZoomPanel
            else if (zoomPanelPosition.X > ZoomPanel1.ActualWidth)
                dx = zoomPanelPosition.X - ZoomPanel1.ActualWidth; // Right of ZoomPanel
            else
                dx = 0; // inside ZoomPanel

            if (zoomPanelPosition.Y < 0)
                dy = zoomPanelPosition.Y; // Above of ZoomPanel
            else if (zoomPanelPosition.Y > ZoomPanel1.ActualHeight) 
                dy = zoomPanelPosition.Y - ZoomPanel1.ActualHeight; // Below of ZoomPanel
            else
                dy = 0; // inside ZoomPanel

           if (dx != 0 || dy != 0)
               ZoomPanel1.TranslateNow(-dx * 0.01, -dy * 0.01); // Reduce the speed of movement so that the user has more control

To see this in action, add the code to the PaintCanvas_MouseMove method in the UseCases/PainterSample.xaml.cs file in the ZoomPanel samples project.

Note that this only works when the CaptureMouse method is called (in PaintCanvas_MouseLeftButtonDown method) - this way the element can get mouse events when the mouse goes out of its borders and even out of the application. In this case, no other control will get mouse events.