From 9e150f2bfbb1759988b3b0216c0b4d6c310d1ce1 Mon Sep 17 00:00:00 2001 From: Sven Eberhardt Date: Sat, 8 Oct 2016 19:04:09 -0400 Subject: [PATCH] Viewport zoom towards center and fix scrolling --- src/editor/C4ConsoleQtViewport.cpp | 13 ++++++++++--- src/editor/C4ConsoleQtViewport.h | 1 + src/game/C4Viewport.cpp | 19 +++++++++++++++---- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/editor/C4ConsoleQtViewport.cpp b/src/editor/C4ConsoleQtViewport.cpp index 0ad868375..e7beccf3b 100644 --- a/src/editor/C4ConsoleQtViewport.cpp +++ b/src/editor/C4ConsoleQtViewport.cpp @@ -279,6 +279,8 @@ void C4ConsoleQtViewportView::wheelEvent(QWheelEvent *event) cvp->ScrollView(x, y); } } + // Event has been handled - do not forward to scroll bars + event->accept(); } void C4ConsoleQtViewportView::focusInEvent(QFocusEvent * event) @@ -422,7 +424,7 @@ void C4ConsoleQtViewportView::paintGL() C4ConsoleQtViewportScrollArea::C4ConsoleQtViewportScrollArea(class C4ConsoleQtViewportDockWidget *dock) - : QAbstractScrollArea(dock), dock(dock), cvp(dock->cvp->cvp) + : QAbstractScrollArea(dock), dock(dock), cvp(dock->cvp->cvp), is_updating_scrollbars(0) { cvp->scrollarea = this; // No scroll bars by default. Neutral viewports will toggle this. @@ -432,8 +434,11 @@ C4ConsoleQtViewportScrollArea::C4ConsoleQtViewportScrollArea(class C4ConsoleQtVi void C4ConsoleQtViewportScrollArea::scrollContentsBy(int dx, int dy) { // Just use the absolute position in any case. - cvp->SetViewX(horizontalScrollBar()->value()); - cvp->SetViewY(verticalScrollBar()->value()); + if (!is_updating_scrollbars) + { + cvp->SetViewX(horizontalScrollBar()->value()); + cvp->SetViewY(verticalScrollBar()->value()); + } } bool C4ConsoleQtViewportScrollArea::viewportEvent(QEvent *e) @@ -451,6 +456,7 @@ void C4ConsoleQtViewportScrollArea::setupViewport(QWidget *viewport) void C4ConsoleQtViewportScrollArea::ScrollBarsByViewPosition() { + ++is_updating_scrollbars; // Do not shift view just from updating scroll bars int x = viewport()->width() / cvp->GetZoom(); horizontalScrollBar()->setRange(0, ::Landscape.GetWidth() - x); horizontalScrollBar()->setPageStep(x); @@ -460,6 +466,7 @@ void C4ConsoleQtViewportScrollArea::ScrollBarsByViewPosition() verticalScrollBar()->setRange(0, ::Landscape.GetHeight() - y); verticalScrollBar()->setPageStep(y); verticalScrollBar()->setValue(cvp->GetViewY()); + --is_updating_scrollbars; } void C4ConsoleQtViewportScrollArea::setScrollBarVisibility(bool visible) diff --git a/src/editor/C4ConsoleQtViewport.h b/src/editor/C4ConsoleQtViewport.h index b7d0f0b7a..c0cb4df94 100644 --- a/src/editor/C4ConsoleQtViewport.h +++ b/src/editor/C4ConsoleQtViewport.h @@ -65,6 +65,7 @@ class C4ConsoleQtViewportScrollArea : public QAbstractScrollArea class C4ConsoleQtViewportDockWidget *dock; class C4Viewport *cvp; + int32_t is_updating_scrollbars; protected: void scrollContentsBy(int dx, int dy) override; diff --git a/src/game/C4Viewport.cpp b/src/game/C4Viewport.cpp index 548798ae7..67bd83f7d 100644 --- a/src/game/C4Viewport.cpp +++ b/src/game/C4Viewport.cpp @@ -516,10 +516,21 @@ void C4Viewport::AdjustZoomAndPosition() if (Zoom == 0) Zoom = ZoomTarget; - if (Zoom < ZoomTarget) - Zoom = std::min(Zoom * ZoomAdjustFactor, ZoomTarget); - if (Zoom > ZoomTarget) - Zoom = std::max(Zoom / ZoomAdjustFactor, ZoomTarget); + else + { + // Remember old viewport center + float view_mid_x = this->viewX + float(this->ViewWdt) / Zoom / 2.0f; + float view_mid_y = this->viewY + float(this->ViewHgt) / Zoom / 2.0f; + + if (Zoom < ZoomTarget) + Zoom = std::min(Zoom * ZoomAdjustFactor, ZoomTarget); + if (Zoom > ZoomTarget) + Zoom = std::max(Zoom / ZoomAdjustFactor, ZoomTarget); + + // Restore new viewport center + this->viewX = view_mid_x - float(this->ViewWdt) / Zoom / 2.0f; + this->viewY = view_mid_y - float(this->ViewHgt) / Zoom / 2.0f; + } } // Adjust position AdjustPosition(false);