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)
|
||||
{
|
||||
_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);
|
||||
QPointF delta_viewport_pos = target_viewport_pos - QPointF(_view->viewport()->width() / 2.0,
|
||||
_view->viewport()->height() / 2.0);
|
||||
QPointF viewport_center = _view->mapFromScene(target_scene_pos) - delta_viewport_pos;
|
||||
_view->centerOn(_view->mapToScene(viewport_center.toPoint()));
|
||||
// In the end we just set correct scene size
|
||||
VMainGraphicsView::NewSceneRect(_view->scene(), _view);
|
||||
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.
|
||||
* Almoust the same we do in method GraphicsViewZoom::eventFilter.
|
||||
*/
|
||||
QPoint pos = _view->mapFromGlobal(QCursor::pos());
|
||||
QPointF delta = target_scene_pos - _view->mapToScene(pos);
|
||||
const QPoint pos = _view->mapFromGlobal(QCursor::pos());
|
||||
const QPointF delta = target_scene_pos - _view->mapToScene(pos);
|
||||
if (qAbs(delta.x()) > 5 || qAbs(delta.y()) > 5)
|
||||
{
|
||||
target_viewport_pos = pos;
|
||||
target_scene_pos = _view->mapToScene(pos);
|
||||
target_viewport_pos = pos;
|
||||
target_scene_pos = _view->mapToScene(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,6 +182,39 @@ bool GraphicsViewZoom::eventFilter(QObject *object, QEvent *event)
|
|||
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.
|
||||
|
|
|
@ -36,11 +36,6 @@
|
|||
* This class adds ability to zoom QGraphicsView using mouse wheel. The point under cursor
|
||||
* 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
|
||||
* 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
|
||||
|
@ -79,18 +74,18 @@ public slots:
|
|||
void scrollingTime(qreal x);
|
||||
void animFinished();
|
||||
private:
|
||||
Q_DISABLE_COPY(GraphicsViewZoom)
|
||||
QGraphicsView* _view;
|
||||
Qt::KeyboardModifiers _modifiers;
|
||||
double _zoom_factor_base;
|
||||
QPointF target_scene_pos;
|
||||
QPointF target_viewport_pos;
|
||||
QTimeLine *anim;
|
||||
|
||||
bool eventFilter(QObject* object, QEvent* event);
|
||||
private:
|
||||
Q_DISABLE_COPY(GraphicsViewZoom)
|
||||
/** @brief _numScheduledScalings keep number scheduled scalings. */
|
||||
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