From e7118b39969c8d56f3c9c4dcfed0598d1f50a0a8 Mon Sep 17 00:00:00 2001 From: dnk-88 Date: Mon, 8 Aug 2011 21:57:28 +0300 Subject: [PATCH] Fixed: #1301 Smooth Panning and Zooming. --HG-- branch : gsoc2011-worldeditorqt --- .../landscape_editor_window.cpp | 4 +- .../landscape_editor/landscape_view.cpp | 157 +++++++++++++++--- .../plugins/landscape_editor/landscape_view.h | 12 +- 3 files changed, 149 insertions(+), 24 deletions(-) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp index a97dcf380..b3110a0e5 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_editor_window.cpp @@ -267,8 +267,8 @@ int LandscapeEditorWindow::createLandscape(const QString &fileName) return -1; } ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id); - m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(), - abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize()); + m_ui.graphicsView->setCenter(QPointF(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(), + abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize())); QListWidgetItem *item; if (fileName.isEmpty()) diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp index c254fd65d..cad51d7cc 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.cpp @@ -33,8 +33,7 @@ namespace LandscapeEditor LandscapeView::LandscapeView(QWidget *parent) : QGraphicsView(parent), m_visibleGrid(true), - m_visibleText(true), - m_moveMouse(false) + m_visibleText(false) { //setDragMode(ScrollHandDrag); setTransformationAnchor(AnchorUnderMouse); @@ -45,6 +44,9 @@ LandscapeView::LandscapeView(QWidget *parent) m_cellSize = 160; m_numSteps = 0; m_maxSteps = 20; + + //A modified version of centerOn(), handles special cases + setCenter(QPointF(500.0, 500.0)); } LandscapeView::~LandscapeView() @@ -70,25 +72,54 @@ void LandscapeView::setVisibleText(bool visible) void LandscapeView::wheelEvent(QWheelEvent *event) { - double numDegrees = event->delta() / 8.0; - double numSteps = numDegrees / 15.0; - double factor = std::pow(1.125, numSteps); - if (factor > 1.0) + /* double numDegrees = event->delta() / 8.0; + double numSteps = numDegrees / 15.0; + double factor = std::pow(1.125, numSteps); + if (factor > 1.0) + { + // check max scale view + if (m_numSteps > m_maxSteps) + return; + ++m_numSteps; + } + else + { + // check min scale view + if (m_numSteps < -m_maxSteps) + return; + --m_numSteps; + } + scale(factor, factor); + QGraphicsView::wheelEvent(event);*/ + + //Get the position of the mouse before scaling, in scene coords + QPointF pointBeforeScale(mapToScene(event->pos())); + + //Get the original screen centerpoint + QPointF screenCenter = getCenter(); //CurrentCenterPoint; //(visRect.center()); + + //Scale the view ie. do the zoom + double scaleFactor = 1.15; //How fast we zoom + if(event->delta() > 0) { - // check max scale view - if (m_numSteps > m_maxSteps) - return; - ++m_numSteps; + //Zoom in + scale(scaleFactor, scaleFactor); } else { - // check min scale view - if (m_numSteps < -m_maxSteps) - return; - --m_numSteps; + //Zooming out + scale(1.0 / scaleFactor, 1.0 / scaleFactor); } - scale(factor, factor); - QGraphicsView::wheelEvent(event); + + //Get the position after scaling, in scene coords + QPointF pointAfterScale(mapToScene(event->pos())); + + //Get the offset of how the screen moved + QPointF offset = pointBeforeScale - pointAfterScale; + + //Adjust to the new center for correct zooming + QPointF newCenter = screenCenter + offset; + setCenter(newCenter); } void LandscapeView::mousePressEvent(QMouseEvent *event) @@ -96,24 +127,108 @@ void LandscapeView::mousePressEvent(QMouseEvent *event) QGraphicsView::mousePressEvent(event); if (event->button() != Qt::MiddleButton) return; - m_moveMouse = true; - QApplication::setOverrideCursor(Qt::ClosedHandCursor); + + //For panning the view + m_lastPanPoint = event->pos(); + setCursor(Qt::ClosedHandCursor); } void LandscapeView::mouseMoveEvent(QMouseEvent *event) { - if (m_moveMouse) - translate(0.001, 0.001); + if(!m_lastPanPoint.isNull()) + { + //Get how much we panned + QPointF delta = mapToScene(m_lastPanPoint) - mapToScene(event->pos()); + m_lastPanPoint = event->pos(); + + //Update the center ie. do the pan + setCenter(getCenter() + delta); + } + QGraphicsView::mouseMoveEvent(event); } void LandscapeView::mouseReleaseEvent(QMouseEvent *event) { + m_lastPanPoint = QPoint(); QApplication::restoreOverrideCursor(); - m_moveMouse = false; QGraphicsView::mouseReleaseEvent(event); } +void LandscapeView::resizeEvent(QResizeEvent *event) +{ + //Get the rectangle of the visible area in scene coords + QRectF visibleArea = mapToScene(rect()).boundingRect(); + setCenter(visibleArea.center()); + + //Call the subclass resize so the scrollbars are updated correctly + QGraphicsView::resizeEvent(event); +} + +void LandscapeView::setCenter(const QPointF ¢erPoint) +{ + //Get the rectangle of the visible area in scene coords + QRectF visibleArea = mapToScene(rect()).boundingRect(); + + //Get the scene area + QRectF sceneBounds = sceneRect(); + + double boundX = visibleArea.width() / 2.0; + double boundY = visibleArea.height() / 2.0; + double boundWidth = sceneBounds.width() - 2.0 * boundX; + double boundHeight = sceneBounds.height() - 2.0 * boundY; + + //The max boundary that the centerPoint can be to + QRectF bounds(boundX, boundY, boundWidth, boundHeight); + + if(bounds.contains(centerPoint)) + { + //We are within the bounds + m_currentCenterPoint = centerPoint; + } + else + { + //We need to clamp or use the center of the screen + if(visibleArea.contains(sceneBounds)) + { + //Use the center of scene ie. we can see the whole scene + m_currentCenterPoint = sceneBounds.center(); + } + else + { + m_currentCenterPoint = centerPoint; + + //We need to clamp the center. The centerPoint is too large + if (centerPoint.x() > bounds.x() + bounds.width()) + { + m_currentCenterPoint.setX(bounds.x() + bounds.width()); + } + else if(centerPoint.x() < bounds.x()) + { + m_currentCenterPoint.setX(bounds.x()); + } + + if(centerPoint.y() > bounds.y() + bounds.height()) + { + m_currentCenterPoint.setY(bounds.y() + bounds.height()); + } + else if(centerPoint.y() < bounds.y()) + { + m_currentCenterPoint.setY(bounds.y()); + } + + } + } + + //Update the scrollbars + centerOn(m_currentCenterPoint); +} + +QPointF LandscapeView::getCenter() const +{ + return m_currentCenterPoint; +} + void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect) { QGraphicsView::drawForeground(painter, rect); diff --git a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h index 20e7ee1bc..607afe60f 100644 --- a/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h +++ b/code/nel/tools/3d/object_viewer_qt/src/plugins/landscape_editor/landscape_view.h @@ -35,6 +35,10 @@ public: LandscapeView(QWidget *parent = 0); virtual ~LandscapeView(); + //Set the current centerpoint in the + void setCenter(const QPointF ¢erPoint); + QPointF getCenter() const; + bool isVisibleGrid() const; public Q_SLOTS: @@ -48,6 +52,7 @@ protected: virtual void mouseMoveEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void drawForeground(QPainter *painter, const QRectF &rect); + virtual void resizeEvent(QResizeEvent *event); void drawGrid(QPainter *painter, const QRectF &rect); void drawZoneNames(QPainter *painter, const QRectF &rect); @@ -56,7 +61,12 @@ private: bool m_visibleGrid, m_visibleText; int m_numSteps, m_maxSteps; int m_cellSize; - bool m_moveMouse; + + //Holds the current centerpoint for the view, used for panning and zooming + QPointF m_currentCenterPoint; + + //From panning the view + QPoint m_lastPanPoint; }; /* class LandscapeView */ } /* namespace LandscapeEditor */