Add zooming and panning to wxDC
Posted: Tue Apr 21, 2020 2:32 am
I intend to add zooming and panning to a wxDC a la Google Maps. I have no compilation problems or runtime problems, but I need some help on the math I should implement. I am handling EVT_MOUSEWHEEL and EVT_MOTION right now:
I suspect the mouse move event could be changed to do panning. In my drawing code, I do this:
The canvas itself is in a sizer with wxSHAPED and the wxBitmap here has the same aspect ratio as the canvas. It is the bitmap I want to implement google maps style navigation on. The scale variable is self explanatory, bigger than one means closer in on the image, smaller than one but above zero means farther away from the image. The zoomPoint is the point where the user's mouse is when they use the scrollwheel. As an aside, how could I make the scaling constant, so it doesn't take more scrollwheel revolutions to zoom in when very zoomed in? Thank you so much for your help or pointers!
Code: Select all
void DrawingCanvas::OnMousewheel(wxMouseEvent& event) {
int ticks = event.GetWheelRotation() / event.GetWheelDelta();
zoomScale += (double)ticks / 20;
if(zoomScale < 0.01) {
zoomScale = 0.01;
}
zoomPoint = event.GetPosition();
Refresh();
}
void DrawingCanvas::OnMouseMove(wxMouseEvent& event) {
if(event.Dragging()) {
zoomPoint = event.GetPosition();
Refresh();
}
}
Code: Select all
void DrawingCanvasBitmap::draw(wxDC& dc) {
if(bitmap != NULL) {
int width;
int height;
GetSize(&width, &height);
// Scale for width and height are the same
double scale = (double)width / bitmap->GetWidth();
// https://forums.wxwidgets.org/viewtopic.php?t=21080
scale *= zoomScale;
dc.SetUserScale(scale, scale);
if(zoomPoint != wxDefaultPosition) {
wxPoint adjustedZoomPoint;
// TODO fix this crap
adjustedZoomPoint.x = dc.DeviceToLogicalX(zoomPoint.x);
adjustedZoomPoint.y = dc.DeviceToLogicalY(zoomPoint.y);
wxPoint middlePoint = zoomPoint - adjustedZoomPoint;
dc.SetDeviceOrigin(middlePoint.x, middlePoint.y);
}
dc.DrawBitmap(*bitmap, 0, 0, false);
}
}