QGraphicsView Zooming in and out under mouse position using mouse wheel finally
works like i want. --HG-- branch : develop
This commit is contained in:
parent
8506afc056
commit
6cd674ec0f
|
@ -55,11 +55,20 @@ GraphicsViewZoom::GraphicsViewZoom(QGraphicsView* view)
|
||||||
void GraphicsViewZoom::gentle_zoom(double factor)
|
void GraphicsViewZoom::gentle_zoom(double factor)
|
||||||
{
|
{
|
||||||
_view->scale(factor, factor);
|
_view->scale(factor, factor);
|
||||||
|
if (factor < 1)
|
||||||
|
{
|
||||||
|
// Because QGraphicsView centers the picture when it's smaller than the view. And QGraphicsView's scrolls
|
||||||
|
// boundaries don't allow to put any picture point at any viewport position we will provide fictive scene size.
|
||||||
|
// Temporary and bigger than view, scene size will help position an image under cursor.
|
||||||
|
FictiveSceneRect(_view->scene(), _view);
|
||||||
|
}
|
||||||
_view->centerOn(target_scene_pos);
|
_view->centerOn(target_scene_pos);
|
||||||
QPointF delta_viewport_pos = target_viewport_pos - QPointF(_view->viewport()->width() / 2.0,
|
QPointF delta_viewport_pos = target_viewport_pos - QPointF(_view->viewport()->width() / 2.0,
|
||||||
_view->viewport()->height() / 2.0);
|
_view->viewport()->height() / 2.0);
|
||||||
QPointF viewport_center = _view->mapFromScene(target_scene_pos) - delta_viewport_pos;
|
QPointF viewport_center = _view->mapFromScene(target_scene_pos) - delta_viewport_pos;
|
||||||
_view->centerOn(_view->mapToScene(viewport_center.toPoint()));
|
_view->centerOn(_view->mapToScene(viewport_center.toPoint()));
|
||||||
|
// In the end we just set correct scene size
|
||||||
|
VMainGraphicsView::NewSceneRect(_view->scene(), _view);
|
||||||
emit zoomed();
|
emit zoomed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,12 +121,12 @@ void GraphicsViewZoom::animFinished()
|
||||||
* If don't do that we will zoom using old value cursor position on scene. It is not what we expect.
|
* If don't do that we will zoom using old value cursor position on scene. It is not what we expect.
|
||||||
* Almoust the same we do in method GraphicsViewZoom::eventFilter.
|
* Almoust the same we do in method GraphicsViewZoom::eventFilter.
|
||||||
*/
|
*/
|
||||||
QPoint pos = _view->mapFromGlobal(QCursor::pos());
|
const QPoint pos = _view->mapFromGlobal(QCursor::pos());
|
||||||
QPointF delta = target_scene_pos - _view->mapToScene(pos);
|
const QPointF delta = target_scene_pos - _view->mapToScene(pos);
|
||||||
if (qAbs(delta.x()) > 5 || qAbs(delta.y()) > 5)
|
if (qAbs(delta.x()) > 5 || qAbs(delta.y()) > 5)
|
||||||
{
|
{
|
||||||
target_viewport_pos = pos;
|
target_viewport_pos = pos;
|
||||||
target_scene_pos = _view->mapToScene(pos);
|
target_scene_pos = _view->mapToScene(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +182,39 @@ bool GraphicsViewZoom::eventFilter(QObject *object, QEvent *event)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void GraphicsViewZoom::FictiveSceneRect(QGraphicsScene *sc, QGraphicsView *view)
|
||||||
|
{
|
||||||
|
SCASSERT(sc != nullptr);
|
||||||
|
SCASSERT(view != nullptr);
|
||||||
|
|
||||||
|
//Calculate view rect
|
||||||
|
//to receive the currently visible area, map the widgets bounds to the scene
|
||||||
|
const QPointF a = view->mapToScene(0, 0 );
|
||||||
|
const QPointF b = view->mapToScene(view->viewport()->width(), view->viewport()->height());
|
||||||
|
QRectF viewRect = QRectF( a, b );
|
||||||
|
|
||||||
|
//Calculate scene rect
|
||||||
|
const QRectF sceneRect = sc->sceneRect();
|
||||||
|
|
||||||
|
if (not sceneRect.contains(viewRect))
|
||||||
|
{//Scene less than view
|
||||||
|
//Scale view
|
||||||
|
QLineF topLeftRay(viewRect.center(), viewRect.topLeft());
|
||||||
|
topLeftRay.setLength(topLeftRay.length()*2);
|
||||||
|
|
||||||
|
QLineF bottomRightRay(viewRect.center(), viewRect.bottomRight());
|
||||||
|
bottomRightRay.setLength(bottomRightRay.length()*2);
|
||||||
|
|
||||||
|
viewRect = QRectF(topLeftRay.p2(), bottomRightRay.p2());
|
||||||
|
|
||||||
|
//Unite two rects
|
||||||
|
const QRectF newRect = sceneRect.united(viewRect);
|
||||||
|
|
||||||
|
sc->setSceneRect(newRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* @brief VMainGraphicsView constructor.
|
* @brief VMainGraphicsView constructor.
|
||||||
|
|
|
@ -36,11 +36,6 @@
|
||||||
* This class adds ability to zoom QGraphicsView using mouse wheel. The point under cursor
|
* This class adds ability to zoom QGraphicsView using mouse wheel. The point under cursor
|
||||||
* remains motionless while it's possible.
|
* remains motionless while it's possible.
|
||||||
*
|
*
|
||||||
* Note that it becomes not possible when the scene's
|
|
||||||
* size is not large enough comparing to the viewport size. QGraphicsView centers the picture
|
|
||||||
* when it's smaller than the view. And QGraphicsView's scrolls boundaries don't allow to
|
|
||||||
* put any picture point at any viewport position.
|
|
||||||
*
|
|
||||||
* When the user starts scrolling, this class remembers original scene position and
|
* When the user starts scrolling, this class remembers original scene position and
|
||||||
* keeps it until scrolling is completed. It's better than getting original scene position at
|
* keeps it until scrolling is completed. It's better than getting original scene position at
|
||||||
* each scrolling step because that approach leads to position errors due to before-mentioned
|
* each scrolling step because that approach leads to position errors due to before-mentioned
|
||||||
|
@ -79,18 +74,18 @@ public slots:
|
||||||
void scrollingTime(qreal x);
|
void scrollingTime(qreal x);
|
||||||
void animFinished();
|
void animFinished();
|
||||||
private:
|
private:
|
||||||
|
Q_DISABLE_COPY(GraphicsViewZoom)
|
||||||
QGraphicsView* _view;
|
QGraphicsView* _view;
|
||||||
Qt::KeyboardModifiers _modifiers;
|
Qt::KeyboardModifiers _modifiers;
|
||||||
double _zoom_factor_base;
|
double _zoom_factor_base;
|
||||||
QPointF target_scene_pos;
|
QPointF target_scene_pos;
|
||||||
QPointF target_viewport_pos;
|
QPointF target_viewport_pos;
|
||||||
QTimeLine *anim;
|
QTimeLine *anim;
|
||||||
|
|
||||||
bool eventFilter(QObject* object, QEvent* event);
|
|
||||||
private:
|
|
||||||
Q_DISABLE_COPY(GraphicsViewZoom)
|
|
||||||
/** @brief _numScheduledScalings keep number scheduled scalings. */
|
/** @brief _numScheduledScalings keep number scheduled scalings. */
|
||||||
qint32 _numScheduledScalings;
|
qint32 _numScheduledScalings;
|
||||||
|
|
||||||
|
virtual bool eventFilter(QObject* object, QEvent* event) Q_DECL_OVERRIDE;
|
||||||
|
void FictiveSceneRect(QGraphicsScene *sc, QGraphicsView *view);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user