diff --git a/src/lib_gui/CMakeLists.txt b/src/lib_gui/CMakeLists.txt index 68b63dbe..2ad184dd 100644 --- a/src/lib_gui/CMakeLists.txt +++ b/src/lib_gui/CMakeLists.txt @@ -38,6 +38,8 @@ add_files( qt/graphics/QtAngledLineItem.h qt/graphics/QtCountCircleItem.cpp qt/graphics/QtCountCircleItem.h + qt/graphics/QtGraphicsView.cpp + qt/graphics/QtGraphicsView.h qt/graphics/QtRoundedRectItem.cpp qt/graphics/QtRoundedRectItem.h qt/graphics/QtStraightLineItem.cpp diff --git a/src/lib_gui/qt/graphics/QtGraphicsView.cpp b/src/lib_gui/qt/graphics/QtGraphicsView.cpp new file mode 100644 index 00000000..9f7457f4 --- /dev/null +++ b/src/lib_gui/qt/graphics/QtGraphicsView.cpp @@ -0,0 +1,139 @@ +#include "qt/graphics/QtGraphicsView.h" + +#include +#include +#include + +QtGraphicsView::QtGraphicsView(QWidget* parent) + : QGraphicsView(parent) + , m_zoomFactor(1.0f) + , m_appZoomFactor(1.0f) +{ + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); +} + +float QtGraphicsView::getZoomFactor() const +{ + return m_appZoomFactor; +} + +void QtGraphicsView::setAppZoomFactor(float appZoomFactor) +{ + m_appZoomFactor = appZoomFactor; + updateTransform(); +} + +qreal QtGraphicsView::zoom() const +{ + return m_zoomFactor; +} + +void QtGraphicsView::setZoom(qreal zoom) +{ + m_zoomFactor = zoom; + updateTransform(); +} + +void QtGraphicsView::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && !itemAt(event->pos())) + { + m_last = event->pos(); + } + + QGraphicsView::mousePressEvent(event); +} + +void QtGraphicsView::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && !itemAt(event->pos()) && event->pos() == m_last) + { + emit emptySpaceClicked(); + } + + QGraphicsView::mouseReleaseEvent(event); + viewport()->setCursor(Qt::ArrowCursor); +} + +void QtGraphicsView::keyPressEvent(QKeyEvent* event) +{ + float delta = 150; + float x = 0.0f; + float y = 0.0f; + + if (event->key() == Qt::Key_W) + { + if (event->modifiers() == Qt::ShiftModifier) + { + updateZoom(true); + return; + } + + y -= delta; + } + else if (event->key() == Qt::Key_A) + { + x -= delta; + } + else if (event->key() == Qt::Key_S) + { + if (event->modifiers() == Qt::ShiftModifier) + { + updateZoom(false); + return; + } + + y += delta; + } + else if (event->key() == Qt::Key_D) + { + x += delta; + } + else + { + return; + } + + if (x != 0) + { + QPropertyAnimation* anim = new QPropertyAnimation(horizontalScrollBar(), "value"); + anim->setDuration(100); + anim->setStartValue(horizontalScrollBar()->value()); + anim->setEndValue(horizontalScrollBar()->value() + x); + anim->start(); + } + if (y != 0) + { + QPropertyAnimation* anim = new QPropertyAnimation(verticalScrollBar(), "value"); + anim->setDuration(100); + anim->setStartValue(verticalScrollBar()->value()); + anim->setEndValue(verticalScrollBar()->value() + y); + anim->start(); + } +} + +void QtGraphicsView::wheelEvent(QWheelEvent* event) +{ + if (event->modifiers() == Qt::ShiftModifier && event->delta() != 0.0f) + { + updateZoom(event->delta() > 0.0f); + return; + } + + QGraphicsView::wheelEvent(event); +} + +void QtGraphicsView::updateTransform() +{ + float zoomFactor = m_appZoomFactor * m_zoomFactor; + setTransform(QTransform(zoomFactor, 0, 0, zoomFactor, 0, 0)); +} + +void QtGraphicsView::updateZoom(bool in) +{ + QPropertyAnimation* anim = new QPropertyAnimation(this, "zoom"); + anim->setDuration(100); + anim->setStartValue(m_zoomFactor); + anim->setEndValue(m_zoomFactor * (1.0f + 0.3 * (in ? 1 : -1))); + anim->start(); +} diff --git a/src/lib_gui/qt/graphics/QtGraphicsView.h b/src/lib_gui/qt/graphics/QtGraphicsView.h new file mode 100644 index 00000000..b99a378f --- /dev/null +++ b/src/lib_gui/qt/graphics/QtGraphicsView.h @@ -0,0 +1,40 @@ +#ifndef QT_GRAPHICS_VIEW_H +#define QT_GRAPHICS_VIEW_H + +#include + +class QtGraphicsView + : public QGraphicsView +{ + Q_OBJECT + Q_PROPERTY(qreal zoom READ zoom WRITE setZoom) + +public: + QtGraphicsView(QWidget* parent); + + float getZoomFactor() const; + void setAppZoomFactor(float appZoomFactor); + + qreal zoom() const; + void setZoom(qreal zoom); + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent* event); + void wheelEvent(QWheelEvent* event); + +signals: + void emptySpaceClicked(); + +private: + void updateTransform(); + void updateZoom(bool in); + + QPoint m_last; + + float m_zoomFactor; + float m_appZoomFactor; +}; + +#endif // QT_GRAPHICS_VIEW_H diff --git a/src/lib_gui/qt/view/QtGraphView.cpp b/src/lib_gui/qt/view/QtGraphView.cpp index da2bd02c..35dc4c17 100644 --- a/src/lib_gui/qt/view/QtGraphView.cpp +++ b/src/lib_gui/qt/view/QtGraphView.cpp @@ -18,6 +18,7 @@ #include "qt/utility/utilityQt.h" +#include "qt/graphics/QtGraphicsView.h" #include "qt/view/QtViewWidgetWrapper.h" #include "qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.h" #include "qt/view/graphElements/nodeComponents/QtGraphNodeComponentMoveable.h" @@ -28,33 +29,6 @@ #include "qt/view/graphElements/QtGraphNodeExpandToggle.h" #include "settings/ColorScheme.h" -QtGraphicsView::QtGraphicsView(QWidget* parent) - : QGraphicsView(parent) -{ -} - -void QtGraphicsView::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton && !itemAt(event->pos())) - { - m_last = event->pos(); - } - - QGraphicsView::mousePressEvent(event); -} - -void QtGraphicsView::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton && !itemAt(event->pos()) && event->pos() == m_last) - { - emit emptySpaceClicked(); - } - - QGraphicsView::mouseReleaseEvent(event); - viewport()->setCursor(Qt::ArrowCursor); -} - - QtGraphView::QtGraphView(ViewLayout* viewLayout) : GraphView(viewLayout) , m_rebuildGraphFunctor( @@ -86,7 +60,7 @@ void QtGraphView::initView() widget->setLayout(layout); QGraphicsScene* scene = new QGraphicsScene(widget); - QGraphicsView* view = new QtGraphicsView(widget); + QtGraphicsView* view = new QtGraphicsView(widget); view->setScene(scene); view->setDragMode(QGraphicsView::ScrollHandDrag); view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); @@ -125,9 +99,9 @@ void QtGraphView::resizeView() Vec2i QtGraphView::getViewSize() const { - QGraphicsView* view = getView(); + QtGraphicsView* view = getView(); - float zoomFactor = GraphViewStyle::getZoomFactor(); + float zoomFactor = view->getZoomFactor(); return Vec2i(view->width() / zoomFactor - 80, view->height() / zoomFactor - 80); } @@ -203,11 +177,11 @@ void QtGraphView::switchToNewGraphData() } } -QGraphicsView* QtGraphView::getView() const +QtGraphicsView* QtGraphView::getView() const { QWidget* widget = QtViewWidgetWrapper::getWidgetOfView(this); - QGraphicsView* view = widget->findChild(""); + QtGraphicsView* view = widget->findChild(""); if (!view) { @@ -299,8 +273,7 @@ void QtGraphView::doRefreshView() std::string css = utility::getStyleSheet(ResourcePaths::getGuiPath() + "graph_view/graph_view.css"); getView()->setStyleSheet(css.c_str()); - float zoomFactor = GraphViewStyle::getZoomFactor(); - getView()->setTransform(QTransform(zoomFactor, 0, 0, zoomFactor, 0, 0)); + getView()->setAppZoomFactor(GraphViewStyle::getZoomFactor()); } std::shared_ptr QtGraphView::findNodeRecursive(const std::list>& nodes, Id tokenId) diff --git a/src/lib_gui/qt/view/QtGraphView.h b/src/lib_gui/qt/view/QtGraphView.h index ebdd7eaa..dc41a0f1 100644 --- a/src/lib_gui/qt/view/QtGraphView.h +++ b/src/lib_gui/qt/view/QtGraphView.h @@ -13,26 +13,9 @@ struct DummyNode; class QMouseEvent; class QSequentialAnimationGroup; class QtGraphEdge; +class QtGraphicsView; class QtGraphNode; -class QtGraphicsView - : public QGraphicsView -{ - Q_OBJECT - -public: - QtGraphicsView(QWidget* parent); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - -signals: - void emptySpaceClicked(); - -private: - QPoint m_last; -}; - - class QtGraphView : public QObject , public GraphView @@ -66,7 +49,7 @@ private slots: private: void switchToNewGraphData(); - QGraphicsView* getView() const; + QtGraphicsView* getView() const; void doRebuildGraph(std::shared_ptr graph, const std::vector& nodes, const std::vector& edges); void doClear();