123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- #include "GraphicsView.hpp"
- #include "BasicGraphicsScene.hpp"
- #include "ConnectionGraphicsObject.hpp"
- #include "NodeGraphicsObject.hpp"
- #include "StyleCollection.hpp"
- #include "UndoCommands.hpp"
- #include <QtWidgets/QGraphicsScene>
- #include <QtGui/QBrush>
- #include <QtGui/QPen>
- #include <QtWidgets/QMenu>
- #include <QtCore/QDebug>
- #include <QtCore/QPointF>
- #include <QtCore/QRectF>
- #include <QtOpenGL>
- #include <QtWidgets>
- #include <cmath>
- #include <iostream>
- using QtNodes::BasicGraphicsScene;
- using QtNodes::GraphicsView;
- GraphicsView::GraphicsView(QWidget *parent)
- : QGraphicsView(parent),
- _clearSelectionAction(Q_NULLPTR),
- _deleteSelectionAction(Q_NULLPTR),
- _duplicateSelectionAction(Q_NULLPTR),
- _copySelectionAction(Q_NULLPTR),
- _pasteAction(Q_NULLPTR)
- {
- setDragMode(QGraphicsView::ScrollHandDrag);
- setRenderHint(QPainter::Antialiasing);
- auto const &flowViewStyle = StyleCollection::flowViewStyle();
- setBackgroundBrush(flowViewStyle.BackgroundColor);
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
- setCacheMode(QGraphicsView::CacheBackground);
- setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
- setScaleRange(0.3, 2);
- // Sets the scene rect to its maximum possible ranges to avoid autu scene range
- // re-calculation when expanding the all QGraphicsItems common rect.
- int maxSize = 32767;
- setSceneRect(-maxSize, -maxSize, (maxSize * 2), (maxSize * 2));
- }
- GraphicsView::GraphicsView(BasicGraphicsScene *scene, QWidget *parent) : GraphicsView(parent)
- {
- setScene(scene);
- }
- QAction *GraphicsView::clearSelectionAction() const
- {
- return _clearSelectionAction;
- }
- QAction *GraphicsView::deleteSelectionAction() const
- {
- return _deleteSelectionAction;
- }
- void GraphicsView::setScene(BasicGraphicsScene *scene)
- {
- QGraphicsView::setScene(scene);
- {
- // setup actions
- delete _clearSelectionAction;
- _clearSelectionAction = new QAction(QStringLiteral("Clear Selection"), this);
- _clearSelectionAction->setShortcut(Qt::Key_Escape);
- connect(_clearSelectionAction, &QAction::triggered, scene, &QGraphicsScene::clearSelection);
- addAction(_clearSelectionAction);
- }
- {
- delete _deleteSelectionAction;
- _deleteSelectionAction = new QAction(QStringLiteral("Delete Selection"), this);
- _deleteSelectionAction->setShortcutContext(Qt::ShortcutContext::WidgetShortcut);
- _deleteSelectionAction->setShortcut(QKeySequence(QKeySequence::Delete));
- connect(_deleteSelectionAction, &QAction::triggered, this, &GraphicsView::onDeleteSelectedObjects);
- addAction(_deleteSelectionAction);
- }
- {
- delete _duplicateSelectionAction;
- _duplicateSelectionAction = new QAction(QStringLiteral("Duplicate Selection"), this);
- _duplicateSelectionAction->setShortcutContext(Qt::ShortcutContext::WidgetShortcut);
- _duplicateSelectionAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D));
- connect(_duplicateSelectionAction, &QAction::triggered, this, &GraphicsView::onDuplicateSelectedObjects);
- addAction(_duplicateSelectionAction);
- }
- {
- delete _copySelectionAction;
- _copySelectionAction = new QAction(QStringLiteral("Copy Selection"), this);
- _copySelectionAction->setShortcutContext(Qt::ShortcutContext::WidgetShortcut);
- _copySelectionAction->setShortcut(QKeySequence(QKeySequence::Copy));
- connect(_copySelectionAction, &QAction::triggered, this, &GraphicsView::onCopySelectedObjects);
- addAction(_copySelectionAction);
- }
- {
- delete _pasteAction;
- _pasteAction = new QAction(QStringLiteral("Copy Selection"), this);
- _pasteAction->setShortcutContext(Qt::ShortcutContext::WidgetShortcut);
- _pasteAction->setShortcut(QKeySequence(QKeySequence::Paste));
- connect(_pasteAction, &QAction::triggered, this, &GraphicsView::onPasteObjects);
- addAction(_pasteAction);
- }
- auto undoAction = scene->undoStack().createUndoAction(this, tr("&Undo"));
- undoAction->setShortcuts(QKeySequence::Undo);
- addAction(undoAction);
- auto redoAction = scene->undoStack().createRedoAction(this, tr("&Redo"));
- redoAction->setShortcuts(QKeySequence::Redo);
- addAction(redoAction);
- }
- void GraphicsView::centerScene()
- {
- if (scene()) {
- scene()->setSceneRect(QRectF());
- QRectF sceneRect = scene()->sceneRect();
- if (sceneRect.width() > this->rect().width() || sceneRect.height() > this->rect().height()) {
- fitInView(sceneRect, Qt::KeepAspectRatio);
- }
- centerOn(sceneRect.center());
- }
- }
- void GraphicsView::contextMenuEvent(QContextMenuEvent *event)
- {
- if (itemAt(event->pos())) {
- QGraphicsView::contextMenuEvent(event);
- return;
- }
- auto const scenePos = mapToScene(event->pos());
- QMenu *menu = nodeScene()->createSceneMenu(scenePos);
- if (menu) {
- menu->exec(event->globalPos());
- }
- }
- void GraphicsView::wheelEvent(QWheelEvent *event)
- {
- QPoint delta = event->angleDelta();
- if (delta.y() == 0) {
- event->ignore();
- return;
- }
- double const d = delta.y() / std::abs(delta.y());
- if (d > 0.0)
- scaleUp();
- else
- scaleDown();
- }
- double GraphicsView::getScale() const
- {
- return transform().m11();
- }
- void GraphicsView::setScaleRange(double minimum, double maximum)
- {
- if (maximum < minimum)
- std::swap(minimum, maximum);
- minimum = std::max(0.0, minimum);
- maximum = std::max(0.0, maximum);
- _scaleRange = { minimum, maximum };
- setupScale(transform().m11());
- }
- void GraphicsView::setScaleRange(ScaleRange range)
- {
- setScaleRange(range.minimum, range.maximum);
- }
- void GraphicsView::scaleUp()
- {
- double const step = 1.2;
- double const factor = std::pow(step, 1.0);
- if (_scaleRange.maximum > 0) {
- QTransform t = transform();
- t.scale(factor, factor);
- if (t.m11() >= _scaleRange.maximum) {
- setupScale(t.m11());
- return;
- }
- }
- scale(factor, factor);
- Q_EMIT scaleChanged(transform().m11());
- }
- void GraphicsView::scaleDown()
- {
- double const step = 1.2;
- double const factor = std::pow(step, -1.0);
- if (_scaleRange.minimum > 0) {
- QTransform t = transform();
- t.scale(factor, factor);
- if (t.m11() <= _scaleRange.minimum) {
- setupScale(t.m11());
- return;
- }
- }
- scale(factor, factor);
- Q_EMIT scaleChanged(transform().m11());
- }
- void GraphicsView::setupScale(double scale)
- {
- scale = std::max(_scaleRange.minimum, std::min(_scaleRange.maximum, scale));
- if (scale <= 0)
- return;
- if (scale == transform().m11())
- return;
- QTransform matrix;
- matrix.scale(scale, scale);
- setTransform(matrix, false);
- Q_EMIT scaleChanged(scale);
- }
- void GraphicsView::onDeleteSelectedObjects()
- {
- // nodeScene()->undoStack().push(new DeleteCommand(nodeScene()));
- }
- void GraphicsView::onDuplicateSelectedObjects()
- {
- QPointF const pastePosition = scenePastePosition();
- nodeScene()->undoStack().push(new CopyCommand(nodeScene()));
- nodeScene()->undoStack().push(new PasteCommand(nodeScene(), pastePosition));
- }
- void GraphicsView::onCopySelectedObjects()
- {
- nodeScene()->undoStack().push(new CopyCommand(nodeScene()));
- }
- void GraphicsView::onPasteObjects()
- {
- QPointF const pastePosition = scenePastePosition();
- nodeScene()->undoStack().push(new PasteCommand(nodeScene(), pastePosition));
- }
- void GraphicsView::keyPressEvent(QKeyEvent *event)
- {
- switch (event->key()) {
- case Qt::Key_Shift:
- setDragMode(QGraphicsView::RubberBandDrag);
- break;
- default:
- break;
- }
- QGraphicsView::keyPressEvent(event);
- }
- void GraphicsView::keyReleaseEvent(QKeyEvent *event)
- {
- switch (event->key()) {
- case Qt::Key_Shift:
- setDragMode(QGraphicsView::ScrollHandDrag);
- break;
- default:
- break;
- }
- QGraphicsView::keyReleaseEvent(event);
- }
- void GraphicsView::mousePressEvent(QMouseEvent *event)
- {
- QGraphicsView::mousePressEvent(event);
- if (event->button() == Qt::LeftButton) {
- _clickPos = mapToScene(event->pos());
- }
- }
- void GraphicsView::mouseMoveEvent(QMouseEvent *event)
- {
- QGraphicsView::mouseMoveEvent(event);
- if (scene()->mouseGrabberItem() == nullptr && event->buttons() == Qt::LeftButton) {
- // Make sure shift is not being pressed
- if ((event->modifiers() & Qt::ShiftModifier) == 0) {
- QPointF difference = _clickPos - mapToScene(event->pos());
- setSceneRect(sceneRect().translated(difference.x(), difference.y()));
- }
- }
- }
- void GraphicsView::drawBackground(QPainter *painter, const QRectF &r)
- {
- QGraphicsView::drawBackground(painter, r);
- auto drawGrid = [&](double gridStep) {
- QRect windowRect = rect();
- QPointF tl = mapToScene(windowRect.topLeft());
- QPointF br = mapToScene(windowRect.bottomRight());
- double left = std::floor(tl.x() / gridStep - 0.5);
- double right = std::floor(br.x() / gridStep + 1.0);
- double bottom = std::floor(tl.y() / gridStep - 0.5);
- double top = std::floor(br.y() / gridStep + 1.0);
- // vertical lines
- for (int xi = int(left); xi <= int(right); ++xi) {
- QLineF line(xi * gridStep, bottom * gridStep, xi * gridStep, top * gridStep);
- painter->drawLine(line);
- }
- // horizontal lines
- for (int yi = int(bottom); yi <= int(top); ++yi) {
- QLineF line(left * gridStep, yi * gridStep, right * gridStep, yi * gridStep);
- painter->drawLine(line);
- }
- };
- auto const &flowViewStyle = StyleCollection::flowViewStyle();
- QPen pfine(flowViewStyle.FineGridColor, 1.0);
- painter->setPen(pfine);
- drawGrid(15);
- QPen p(flowViewStyle.CoarseGridColor, 1.0);
- painter->setPen(p);
- drawGrid(150);
- }
- void GraphicsView::showEvent(QShowEvent *event)
- {
- QGraphicsView::showEvent(event);
- centerScene();
- }
- BasicGraphicsScene *GraphicsView::nodeScene()
- {
- return dynamic_cast<BasicGraphicsScene *>(scene());
- }
- QPointF GraphicsView::scenePastePosition()
- {
- QPoint origin = mapFromGlobal(QCursor::pos());
- QRect const viewRect = rect();
- if (!viewRect.contains(origin))
- origin = viewRect.center();
- return mapToScene(origin);
- }
|