Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2edfb0b
Updates fork from upstream
tatatupi Jun 20, 2025
988ce45
wip: adds NodeValidationState info to NodeDelegateModel
tatatupi Jun 22, 2025
1c84750
makes the nodeObject red in case of invalid state and adds a tooltip …
tatatupi Jun 22, 2025
3007c23
adds warning state and adapts calculator example
tatatupi Jun 22, 2025
129d414
adds validation icon and adapts calculation example
tatatupi Jun 22, 2025
e0b0c4a
core improvements to develop node processing status
g-abilio Jul 14, 2025
e002f5b
first commit on the creation of a processing status example
g-abilio Jul 15, 2025
985b638
fixes nodeprocessingstatus cast
tatatupi Jul 15, 2025
3f55e35
creation of random gen example, and fix of icon color
g-abilio Jul 16, 2025
50c6bec
Connect delegate UI update signal
tatatupi Jul 17, 2025
1c09ecf
fix random number node dynamic
g-abilio Jul 17, 2025
50ce760
Merge pull request #5 from fabns-nano/codex/add-signal-for-ui-updates…
g-abilio Jul 17, 2025
f2c120f
clean up test code in multiplication node
g-abilio Jul 17, 2025
965eb15
Add per-node background color API
hudsonmiranda291 Jul 22, 2025
545c018
Updates fork from upstream
Gabrielnmds Aug 5, 2025
c34e6e3
adds version to Catch2 due to compatibility issues
tatatupi Aug 6, 2025
97d48d5
Merge branch 'paceholder:master' into master
tatatupi Sep 2, 2025
89ac7f2
Merge branch 'master' of https://github.com/paceholder/nodeeditor
tatatupi Sep 5, 2025
37c3bf8
solves conflict
tatatupi Sep 10, 2025
b23ecc3
revert unnecessary changes in multiplication model
tatatupi Sep 10, 2025
0a35f76
revert unnecessary changes
tatatupi Sep 10, 2025
a9be092
solve icon size and refactor NodeProcessingStatus code
g-abilio Sep 11, 2025
5530b72
update and merge new code
g-abilio Sep 11, 2025
03e311a
remove duplicate code
g-abilio Sep 11, 2025
a87ceb2
add space to better organize processing status in node display
g-abilio Sep 15, 2025
ae3715b
remove processing value default value
g-abilio Sep 19, 2025
eedc666
fix bugs in node processing status
g-abilio Sep 19, 2025
1298605
add Q_DECLARE_METATYPE to solve linux build problems
g-abilio Sep 24, 2025
47d948f
declaring metatype in the correct place
g-abilio Sep 24, 2025
21b55ac
Merge pull request #6 from fabns-nano/node_processing_status
g-abilio Oct 20, 2025
4f1b23c
fix undocommands module inclusion
g-abilio Dec 3, 2025
87e219b
solve conflicts
g-abilio Dec 3, 2025
dea439b
Merge pull request #7 from fabns-nano/codex/expose-setbackgroundcolor…
g-abilio Dec 3, 2025
cc81264
Adds node nickname functionality (#11)
g-abilio Dec 11, 2025
83426c7
Merge branch 'master' of https://github.com/paceholder/nodeeditor int…
Gabrielnmds Dec 17, 2025
422cdd5
adds zoomFitAll and zoomFitSelected methods
Gabrielnmds Aug 5, 2025
9fdc3e8
refactor(zoom fit): minor code fixes
Gabrielnmds Dec 15, 2025
f2473e7
refactor(zoom fit): fixes code conflicts
Gabrielnmds Dec 17, 2025
bc1b6cb
Refactor(node editor): solve conflicts
Gabrielnmds Dec 17, 2025
2b3ac01
fix uninitialized variable and remove return
g-abilio Jan 7, 2026
891b702
remove bad coupling
g-abilio Jan 7, 2026
8d6c26b
refactoring to simpler code
g-abilio Jan 12, 2026
e828567
solve conflicts
g-abilio Jan 14, 2026
02b3969
Revert "solve conflicts"
g-abilio Jan 15, 2026
5d1d07b
remove example implementation of zoom fit feature
g-abilio Jan 15, 2026
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