Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/QtNodes/internal/BasicGraphicsScene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include <tuple>
#include <unordered_map>


class QUndoStack;

namespace QtNodes {
Expand Down Expand Up @@ -112,6 +111,8 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene
*/
virtual QMenu *createSceneMenu(QPointF const scenePos);

QMenu *createZoomMenu(QPointF const scenePos);

Q_SIGNALS:
void modified(BasicGraphicsScene *);
void nodeMoved(NodeId const nodeId, QPointF const &newLocation);
Expand All @@ -125,6 +126,9 @@ class NODE_EDITOR_PUBLIC BasicGraphicsScene : public QGraphicsScene

/// Signal allows showing custom context menu upon clicking a node.
void nodeContextMenu(NodeId const nodeId, QPointF const pos);
/// Signals to call Graphics View's zoomFit methods
void zoomFitAllClicked();
void zoomFitSelectedClicked();

private:
/**
Expand Down
4 changes: 4 additions & 0 deletions include/QtNodes/internal/GraphicsView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public Q_SLOTS:

virtual void onPasteObjects();

void zoomFitAll();

void zoomFitSelected();

Q_SIGNALS:
void scaleChanged(double scale);

Expand Down
6 changes: 6 additions & 0 deletions include/QtNodes/internal/NodeDelegateModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ class NODE_EDITOR_PUBLIC NodeDelegateModel

virtual bool resizable() const { return false; }

bool zoomFitMenu() const { return _zoomFitMenu; }

void setZoomFitMenu(bool state) { _zoomFitMenu = state; }

public Q_SLOTS:
virtual void inputConnectionCreated(ConnectionId const &) {}
virtual void inputConnectionDeleted(ConnectionId const &) {}
Expand Down Expand Up @@ -188,6 +192,8 @@ public Q_SLOTS:
NodeValidationState _nodeValidationState;

NodeProcessingStatus _processingStatus{NodeProcessingStatus::NoStatus};

bool _zoomFitMenu{false};
};

} // namespace QtNodes
Expand Down
68 changes: 68 additions & 0 deletions src/BasicGraphicsScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

#include <QUndoStack>

#include <QHeaderView>
#include <QLineEdit>
#include <QTreeWidget>
#include <QWidgetAction>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QGraphicsSceneMoveEvent>

Expand Down Expand Up @@ -203,6 +207,70 @@ QMenu *BasicGraphicsScene::createSceneMenu(QPointF const scenePos)
return nullptr;
}

QMenu *BasicGraphicsScene::createZoomMenu(QPointF const scenePos)
{
Q_UNUSED(scenePos);

QMenu *menu = new QMenu();

auto *txtBox = new QLineEdit(menu);
txtBox->setPlaceholderText(QStringLiteral("Filter"));
txtBox->setClearButtonEnabled(true);

auto *txtBoxAction = new QWidgetAction(menu);
txtBoxAction->setDefaultWidget(txtBox);
menu->addAction(txtBoxAction);

QTreeWidget *treeView = new QTreeWidget(menu);
treeView->header()->close();

treeView->setMaximumHeight(100);
treeView->setMaximumWidth(150);

auto *treeViewAction = new QWidgetAction(menu);
treeViewAction->setDefaultWidget(treeView);
menu->addAction(treeViewAction);

auto freezeItem = new QTreeWidgetItem(treeView);
freezeItem->setText(0, "Zoom Fit All");

auto unfreezeItem = new QTreeWidgetItem(treeView);
unfreezeItem->setText(0, "Zoom Fit Selected");

treeView->expandAll();

connect(treeView, &QTreeWidget::itemClicked, [this, menu](QTreeWidgetItem *item, int) {
if (item->text(0) == "Zoom Fit All") {
Q_EMIT zoomFitAllClicked();

menu->close();
return;
}
if (item->text(0) == "Zoom Fit Selected") {
Q_EMIT zoomFitSelectedClicked();

menu->close();
return;
}
});

// Filter
connect(txtBox, &QLineEdit::textChanged, [treeView](const QString &text) {
QTreeWidgetItemIterator it(treeView);
while (*it) {
auto modelName = (*it)->text(0);
const bool match = (modelName.contains(text, Qt::CaseInsensitive));
(*it)->setHidden(!match);
++it;
}
});

txtBox->setFocus();
menu->setAttribute(Qt::WA_DeleteOnClose);

return menu;
}

void BasicGraphicsScene::traverseGraphAndPopulateGraphicsObjects()
{
auto allNodeIds = _graphModel.allNodeIds();
Expand Down
70 changes: 56 additions & 14 deletions src/GraphicsView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "BasicGraphicsScene.hpp"
#include "ConnectionGraphicsObject.hpp"
#include "DataFlowGraphModel.hpp"
#include "NodeGraphicsObject.hpp"
#include "StyleCollection.hpp"
#include "UndoCommands.hpp"
Expand All @@ -23,6 +24,7 @@
#include <cmath>

using QtNodes::BasicGraphicsScene;
using QtNodes::DataFlowGraphModel;
using QtNodes::GraphicsView;

GraphicsView::GraphicsView(QWidget *parent)
Expand Down Expand Up @@ -75,8 +77,7 @@ QAction *GraphicsView::deleteSelectionAction() const
void GraphicsView::setScene(BasicGraphicsScene *scene)
{
QGraphicsView::setScene(scene);
if (!scene)
{
if (!scene) {
// Clear actions.
delete _clearSelectionAction;
delete _deleteSelectionAction;
Expand Down Expand Up @@ -162,6 +163,13 @@ void GraphicsView::setScene(BasicGraphicsScene *scene)
auto redoAction = scene->undoStack().createRedoAction(this, tr("&Redo"));
redoAction->setShortcuts(QKeySequence::Redo);
addAction(redoAction);

/// Connections to context menu funcionality
connect(scene, &BasicGraphicsScene::zoomFitAllClicked, this, &GraphicsView::zoomFitAll);
connect(scene,
&BasicGraphicsScene::zoomFitSelectedClicked,
this,
&GraphicsView::zoomFitSelected);
}

void GraphicsView::centerScene()
Expand All @@ -181,20 +189,30 @@ void GraphicsView::centerScene()

void GraphicsView::contextMenuEvent(QContextMenuEvent *event)
{
if (itemAt(event->pos())) {
QGraphicsView::contextMenuEvent(event);
return;
}
QGraphicsView::contextMenuEvent(event);
QMenu *menu = nullptr;

if (!nodeScene()) return;
bool isZoomFitMenu;

auto const scenePos = mapToScene(event->pos());
if (auto *dfModel = dynamic_cast<DataFlowGraphModel *>(&nodeScene()->graphModel())) {
if (auto n = qgraphicsitem_cast<NodeGraphicsObject *>(itemAt(event->pos()))) {
if (auto *delegate = dfModel->delegateModel<NodeDelegateModel>(n->nodeId())) {
isZoomFitMenu = delegate->zoomFitMenu();
}
}
}

QMenu *menu = nodeScene()->createSceneMenu(scenePos);
if (itemAt(event->pos()) && isZoomFitMenu) {
menu = nodeScene()->createZoomMenu(mapToScene(event->pos()));
} else if (!itemAt(event->pos())) {
menu = nodeScene()->createSceneMenu(mapToScene(event->pos()));
}

if (menu) {
menu->exec(event->globalPos());
}

return;
}

void GraphicsView::wheelEvent(QWheelEvent *event)
Expand Down Expand Up @@ -291,14 +309,16 @@ void GraphicsView::setupScale(double scale)

void GraphicsView::onDeleteSelectedObjects()
{
if (!nodeScene()) return;
if (!nodeScene())
return;

nodeScene()->undoStack().push(new DeleteCommand(nodeScene()));
}

void GraphicsView::onDuplicateSelectedObjects()
{
if (!nodeScene()) return;
if (!nodeScene())
return;

QPointF const pastePosition = scenePastePosition();

Expand All @@ -308,14 +328,16 @@ void GraphicsView::onDuplicateSelectedObjects()

void GraphicsView::onCopySelectedObjects()
{
if (!nodeScene()) return;
if (!nodeScene())
return;

nodeScene()->undoStack().push(new CopyCommand(nodeScene()));
}

void GraphicsView::onPasteObjects()
{
if (!nodeScene()) return;
if (!nodeScene())
return;

QPointF const pastePosition = scenePastePosition();
nodeScene()->undoStack().push(new PasteCommand(nodeScene(), pastePosition));
Expand Down Expand Up @@ -360,7 +382,8 @@ void GraphicsView::mouseMoveEvent(QMouseEvent *event)
{
QGraphicsView::mouseMoveEvent(event);

if (!scene()) return;
if (!scene())
return;

if (scene()->mouseGrabberItem() == nullptr && event->buttons() == Qt::LeftButton) {
// Make sure shift is not being pressed
Expand Down Expand Up @@ -434,3 +457,22 @@ QPointF GraphicsView::scenePastePosition()

return mapToScene(origin);
}

void GraphicsView::zoomFitAll()
{
fitInView(scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
}

void GraphicsView::zoomFitSelected()
{
if (scene()->selectedItems().count() > 0) {
QRectF unitedBoundingRect{};

for (QGraphicsItem *item : scene()->selectedItems()) {
unitedBoundingRect = unitedBoundingRect.united(
item->mapRectToScene(item->boundingRect()));
}

fitInView(unitedBoundingRect, Qt::KeepAspectRatio);
}
}
Loading