Fixed: #1301 Smooth Panning and Zooming.

--HG--
branch : gsoc2011-worldeditorqt
This commit is contained in:
dnk-88 2011-08-08 21:57:28 +03:00
parent a1a207cf6a
commit e7118b3996
3 changed files with 149 additions and 24 deletions

View file

@ -267,8 +267,8 @@ int LandscapeEditorWindow::createLandscape(const QString &fileName)
return -1; return -1;
} }
ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id); ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
m_ui.graphicsView->centerOn(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(), m_ui.graphicsView->setCenter(QPointF(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(),
abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize()); abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize()));
QListWidgetItem *item; QListWidgetItem *item;
if (fileName.isEmpty()) if (fileName.isEmpty())

View file

@ -33,8 +33,7 @@ namespace LandscapeEditor
LandscapeView::LandscapeView(QWidget *parent) LandscapeView::LandscapeView(QWidget *parent)
: QGraphicsView(parent), : QGraphicsView(parent),
m_visibleGrid(true), m_visibleGrid(true),
m_visibleText(true), m_visibleText(false)
m_moveMouse(false)
{ {
//setDragMode(ScrollHandDrag); //setDragMode(ScrollHandDrag);
setTransformationAnchor(AnchorUnderMouse); setTransformationAnchor(AnchorUnderMouse);
@ -45,6 +44,9 @@ LandscapeView::LandscapeView(QWidget *parent)
m_cellSize = 160; m_cellSize = 160;
m_numSteps = 0; m_numSteps = 0;
m_maxSteps = 20; m_maxSteps = 20;
//A modified version of centerOn(), handles special cases
setCenter(QPointF(500.0, 500.0));
} }
LandscapeView::~LandscapeView() LandscapeView::~LandscapeView()
@ -70,25 +72,54 @@ void LandscapeView::setVisibleText(bool visible)
void LandscapeView::wheelEvent(QWheelEvent *event) void LandscapeView::wheelEvent(QWheelEvent *event)
{ {
double numDegrees = event->delta() / 8.0; /* double numDegrees = event->delta() / 8.0;
double numSteps = numDegrees / 15.0; double numSteps = numDegrees / 15.0;
double factor = std::pow(1.125, numSteps); double factor = std::pow(1.125, numSteps);
if (factor > 1.0) 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 //Zoom in
if (m_numSteps > m_maxSteps) scale(scaleFactor, scaleFactor);
return;
++m_numSteps;
} }
else else
{ {
// check min scale view //Zooming out
if (m_numSteps < -m_maxSteps) scale(1.0 / scaleFactor, 1.0 / scaleFactor);
return;
--m_numSteps;
} }
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) void LandscapeView::mousePressEvent(QMouseEvent *event)
@ -96,24 +127,108 @@ void LandscapeView::mousePressEvent(QMouseEvent *event)
QGraphicsView::mousePressEvent(event); QGraphicsView::mousePressEvent(event);
if (event->button() != Qt::MiddleButton) if (event->button() != Qt::MiddleButton)
return; return;
m_moveMouse = true;
QApplication::setOverrideCursor(Qt::ClosedHandCursor); //For panning the view
m_lastPanPoint = event->pos();
setCursor(Qt::ClosedHandCursor);
} }
void LandscapeView::mouseMoveEvent(QMouseEvent *event) void LandscapeView::mouseMoveEvent(QMouseEvent *event)
{ {
if (m_moveMouse) if(!m_lastPanPoint.isNull())
translate(0.001, 0.001); {
//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); QGraphicsView::mouseMoveEvent(event);
} }
void LandscapeView::mouseReleaseEvent(QMouseEvent *event) void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
{ {
m_lastPanPoint = QPoint();
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
m_moveMouse = false;
QGraphicsView::mouseReleaseEvent(event); 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 &centerPoint)
{
//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) void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect)
{ {
QGraphicsView::drawForeground(painter, rect); QGraphicsView::drawForeground(painter, rect);

View file

@ -35,6 +35,10 @@ public:
LandscapeView(QWidget *parent = 0); LandscapeView(QWidget *parent = 0);
virtual ~LandscapeView(); virtual ~LandscapeView();
//Set the current centerpoint in the
void setCenter(const QPointF &centerPoint);
QPointF getCenter() const;
bool isVisibleGrid() const; bool isVisibleGrid() const;
public Q_SLOTS: public Q_SLOTS:
@ -48,6 +52,7 @@ protected:
virtual void mouseMoveEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void drawForeground(QPainter *painter, const QRectF &rect); virtual void drawForeground(QPainter *painter, const QRectF &rect);
virtual void resizeEvent(QResizeEvent *event);
void drawGrid(QPainter *painter, const QRectF &rect); void drawGrid(QPainter *painter, const QRectF &rect);
void drawZoneNames(QPainter *painter, const QRectF &rect); void drawZoneNames(QPainter *painter, const QRectF &rect);
@ -56,7 +61,12 @@ private:
bool m_visibleGrid, m_visibleText; bool m_visibleGrid, m_visibleText;
int m_numSteps, m_maxSteps; int m_numSteps, m_maxSteps;
int m_cellSize; 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 */ }; /* class LandscapeView */
} /* namespace LandscapeEditor */ } /* namespace LandscapeEditor */