fix bugs within scale and rotate

This commit is contained in:
Gary Wang 2019-10-02 16:04:50 +08:00
parent ad879f8f8b
commit f47ee03ce3
3 changed files with 74 additions and 10 deletions

View File

@ -84,6 +84,48 @@ void GraphicsView::setScene(GraphicsScene *scene)
return QGraphicsView::setScene(scene); return QGraphicsView::setScene(scene);
} }
qreal GraphicsView::scaleFactor() const
{
int angle = static_cast<int>(m_rotateAngle);
if (angle == 0 || angle == 180) {
return qAbs(transform().m11());
} else {
return qAbs(transform().m12());
}
}
void GraphicsView::resetTransform()
{
m_scaleFactor = 1;
m_rotateAngle = 0;
QGraphicsView::resetTransform();
}
void GraphicsView::zoomView(qreal scaleFactor)
{
m_scaleFactor *= scaleFactor;
reapplyViewTransform();
}
void GraphicsView::resetScale()
{
m_scaleFactor = 1;
reapplyViewTransform();
}
void GraphicsView::rotateView(qreal rotateAngel)
{
m_rotateAngle += rotateAngel;
m_rotateAngle = static_cast<int>(m_rotateAngle) % 360;
reapplyViewTransform();
}
void GraphicsView::fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRadioMode)
{
QGraphicsView::fitInView(rect, aspectRadioMode);
m_scaleFactor = scaleFactor();
}
void GraphicsView::checkAndDoFitInView() void GraphicsView::checkAndDoFitInView()
{ {
if (!isThingSmallerThanWindowWith(transform())) { if (!isThingSmallerThanWindowWith(transform())) {
@ -132,16 +174,18 @@ void GraphicsView::wheelEvent(QWheelEvent *event)
{ {
m_enableFitInView = false; m_enableFitInView = false;
if (event->delta() > 0) { if (event->delta() > 0) {
scale(1.25, 1.25); zoomView(1.25);
} else { } else {
scale(0.8, 0.8); zoomView(0.8);
} }
} }
void GraphicsView::resizeEvent(QResizeEvent *event) void GraphicsView::resizeEvent(QResizeEvent *event)
{ {
if (m_enableFitInView) { if (m_enableFitInView) {
if (isThingSmallerThanWindowWith(QTransform()) && transform().m11() >= 1) { QTransform tf;
tf.rotate(m_rotateAngle);
if (isThingSmallerThanWindowWith(tf) && scaleFactor() >= 1) {
// no longer need to do fitInView() // no longer need to do fitInView()
// but we leave the m_enableFitInView value unchanged in case // but we leave the m_enableFitInView value unchanged in case
// user resize down the window again. // user resize down the window again.
@ -197,7 +241,7 @@ void GraphicsView::dropEvent(QDropEvent *event)
} }
bool GraphicsView::isThingSmallerThanWindowWith(const QTransform &transform) const bool GraphicsView::isThingSmallerThanWindowWith(const QTransform &transform) const
{qDebug() << sceneRect(); {
return rect().size().expandedTo(transform.mapRect(sceneRect()).size().toSize()) return rect().size().expandedTo(transform.mapRect(sceneRect()).size().toSize())
== rect().size(); == rect().size();
} }
@ -238,3 +282,10 @@ void GraphicsView::setCheckerboardEnabled(bool enabled)
setBackgroundBrush(Qt::transparent); setBackgroundBrush(Qt::transparent);
} }
} }
void GraphicsView::reapplyViewTransform()
{
QGraphicsView::resetTransform();
scale(m_scaleFactor, m_scaleFactor);
rotate(m_rotateAngle);
}

View File

@ -20,6 +20,14 @@ public:
GraphicsScene * scene() const; GraphicsScene * scene() const;
void setScene(GraphicsScene *scene); void setScene(GraphicsScene *scene);
qreal scaleFactor() const;
void resetTransform();
void zoomView(qreal scaleFactor);
void resetScale();
void rotateView(qreal rotateAngel);
void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRadioMode = Qt::IgnoreAspectRatio);
void checkAndDoFitInView(); void checkAndDoFitInView();
public slots: public slots:
@ -40,8 +48,12 @@ private:
bool shouldIgnoreMousePressMoveEvent(const QMouseEvent *event) const; bool shouldIgnoreMousePressMoveEvent(const QMouseEvent *event) const;
void setCheckerboardEnabled(bool enabled); void setCheckerboardEnabled(bool enabled);
void reapplyViewTransform();
bool m_enableFitInView = false; bool m_enableFitInView = false;
bool m_checkerboardEnabled = false; bool m_checkerboardEnabled = false;
qreal m_scaleFactor = 1;
qreal m_rotateAngle = 0;
}; };
#endif // GRAPHICSVIEW_H #endif // GRAPHICSVIEW_H

View File

@ -59,16 +59,17 @@ MainWindow::MainWindow(QWidget *parent) :
m_bottomButtonGroup = new BottomButtonGroup(this); m_bottomButtonGroup = new BottomButtonGroup(this);
connect(m_bottomButtonGroup, &BottomButtonGroup::resetToOriginalBtnClicked, connect(m_bottomButtonGroup, &BottomButtonGroup::resetToOriginalBtnClicked,
this, [ = ](){ m_graphicsView->resetTransform(); }); this, [ = ](){ m_graphicsView->resetScale(); });
connect(m_bottomButtonGroup, &BottomButtonGroup::zoomInBtnClicked, connect(m_bottomButtonGroup, &BottomButtonGroup::zoomInBtnClicked,
this, [ = ](){ m_graphicsView->scale(1.25, 1.25); }); this, [ = ](){ m_graphicsView->zoomView(1.25); });
connect(m_bottomButtonGroup, &BottomButtonGroup::zoomOutBtnClicked, connect(m_bottomButtonGroup, &BottomButtonGroup::zoomOutBtnClicked,
this, [ = ](){ m_graphicsView->scale(0.75, 0.75); }); this, [ = ](){ m_graphicsView->zoomView(0.75); });
connect(m_bottomButtonGroup, &BottomButtonGroup::toggleCheckerboardBtnClicked, connect(m_bottomButtonGroup, &BottomButtonGroup::toggleCheckerboardBtnClicked,
this, [ = ](){ m_graphicsView->toggleCheckerboard(); }); this, [ = ](){ m_graphicsView->toggleCheckerboard(); });
connect(m_bottomButtonGroup, &BottomButtonGroup::rotateRightBtnClicked, connect(m_bottomButtonGroup, &BottomButtonGroup::rotateRightBtnClicked,
this, [ = ](){ this, [ = ](){
m_graphicsView->rotate(90); m_graphicsView->resetScale();
m_graphicsView->rotateView(90);
m_graphicsView->checkAndDoFitInView(); m_graphicsView->checkAndDoFitInView();
}); });
@ -87,7 +88,7 @@ void MainWindow::showUrls(const QList<QUrl> &urls)
void MainWindow::adjustWindowSizeBySceneRect() void MainWindow::adjustWindowSizeBySceneRect()
{ {
if (m_graphicsView->transform().m11() < 1) { if (m_graphicsView->scaleFactor() < 1) {
// if it scaled down by the resize policy: // if it scaled down by the resize policy:
QSize screenSize = qApp->screenAt(QCursor::pos())->availableSize(); QSize screenSize = qApp->screenAt(QCursor::pos())->availableSize();
QSize sceneSize = m_graphicsView->sceneRect().toRect().size(); QSize sceneSize = m_graphicsView->sceneRect().toRect().size();
@ -120,7 +121,7 @@ void MainWindow::mousePressEvent(QMouseEvent *event)
m_clickedOnWindow = true; m_clickedOnWindow = true;
m_oldMousePos = event->pos(); m_oldMousePos = event->pos();
qDebug() << m_oldMousePos << m_graphicsView->transform().m11() qDebug() << m_oldMousePos << m_graphicsView->transform().m11()
<< m_graphicsView->transform().m22() << m_graphicsView->matrix().m11(); << m_graphicsView->transform().m22() << m_graphicsView->matrix().m12();
event->accept(); event->accept();
} }