PeriDyno 1.2.1
Loading...
Searching...
No Matches
QtNodeFlowView.cpp
Go to the documentation of this file.
1#include "QtNodeFlowView.h"
2
3#include <QtWidgets>
4
5#include "nodes/QFlowScene"
6
7namespace Qt
8{
10 : QtFlowView(parent)
11 {
12 }
13
14 QtNodeFlowView::QtNodeFlowView(QtFlowScene *scene, QWidget *parent)
15 : QtFlowView(scene, parent)
16 {
17 connect(scene, &QtFlowScene::outPortConextMenu, this, &QtNodeFlowView::showPortContextMenu);
18 }
19
20 void QtNodeFlowView::showPortContextMenu(QtNode& n, const PortIndex index, const QPointF& pos)
21 {
22 QMenu modelMenu;
23
24 auto scenePos = this->mapToScene(this->mapFromGlobal(QPoint(pos.x(), pos.y())));
25
26 //Filter classes
27 std::set<QString> categoryFiltered;
28 std::unordered_map<QString, QString> registeredModelsCategoryFiltered;
29
30 auto outData = n.nodeDataModel()->outData(index);
31 for (auto const& assoc : scene()->registry().registeredModelsCategoryAssociation())
32 {
33 auto modelName = QString(assoc.first);
34
35 auto type = scene()->registry().create(modelName);
36
37 if (type)
38 {
39 auto num = type->nPorts(PortType::In);
40
41 for (uint i = 0; i < num; i++)
42 {
43 if (type->tryInData(i, outData))
44 {
45 categoryFiltered.insert(assoc.second);
46 registeredModelsCategoryFiltered[modelName] = assoc.second;
47
48 continue;
49 }
50 }
51 }
52 }
53
54 //Add filterbox to the context menu
55 auto* txtBox = new QLineEdit(&modelMenu);
56 txtBox->grabKeyboard();
57
58 txtBox->setPlaceholderText(QStringLiteral("Filter"));
59 txtBox->setClearButtonEnabled(true);
60
61 auto* txtBoxAction = new QWidgetAction(&modelMenu);
62 txtBoxAction->setDefaultWidget(txtBox);
63
64 modelMenu.addAction(txtBoxAction);
65 modelMenu.addSeparator();
66
67 auto skipText = QStringLiteral("skip me");
68
69 //Show context menu
70 {
71 //Add result treeview to the context menu
72 auto* treeView = new QTreeWidget(&modelMenu);
73 treeView->header()->close();
74
75 auto* treeViewAction = new QWidgetAction(&modelMenu);
76 treeViewAction->setDefaultWidget(treeView);
77
78 modelMenu.addAction(treeViewAction);
79
80 QMap<QString, QTreeWidgetItem*> topLevelItems;
81 for (auto const& cat : categoryFiltered)
82 {
83 auto item = new QTreeWidgetItem(treeView);
84 item->setText(0, cat);
85 item->setData(0, Qt::UserRole, skipText);
86 topLevelItems[cat] = item;
87 }
88
89 for (auto const& assoc : registeredModelsCategoryFiltered)
90 {
91 auto parent = topLevelItems[assoc.second];
92 auto item = new QTreeWidgetItem(parent);
93 item->setText(0, assoc.first);
94 item->setData(0, Qt::UserRole, assoc.first);
95 }
96
97 treeView->expandAll();
98
99 connect(treeView, &QTreeWidget::itemClicked, [&](QTreeWidgetItem* item, int)
100 {
101 QString modelName = item->data(0, Qt::UserRole).toString();
102
103 if (modelName == skipText)
104 {
105 return;
106 }
107
108 auto type = scene()->registry().create(modelName);
109
110 if (type)
111 {
112 auto& node = scene()->createNode(std::move(type));
113
114 node.nodeGraphicsObject().setPos(scenePos);
115
116 scene()->nodePlaced(node);
117
118 //Create connection
119 {
120 auto num = node.nodeDataModel()->nPorts(PortType::In);
121
122 for (uint i = 0; i < num; i++)
123 {
124 //TODO: if multiple ports exist, how to choose the best one
125 if (node.nodeDataModel()->tryInData(i, outData))
126 {
127 scene()->createConnection(node, i, n, index);
128 break;
129 }
130 }
131 }
132 }
133 else
134 {
135 qDebug() << "Model not found";
136 }
137
138 modelMenu.close();
139 });
140
141 //Setup filtering
142 connect(txtBox, &QLineEdit::textChanged, [&](const QString& text)
143 {
144 for (auto& topLvlItem : topLevelItems)
145 {
146 bool topItemMatch = false;
147 for (int i = 0; i < topLvlItem->childCount(); ++i)
148 {
149 auto child = topLvlItem->child(i);
150 auto modelName = child->data(0, Qt::UserRole).toString();
151 const bool match = (modelName.contains(text, Qt::CaseInsensitive));
152 child->setHidden(!match);
153
154 topItemMatch |= match;
155 }
156 //If no child is matched, hide the top level item
157 topLvlItem->setHidden(!topItemMatch);
158 }
159 });
160
161 // make sure the text box gets focus so the user doesn't have to click on it
162 txtBox->setFocus();
163
164 categoryFiltered.clear();
165 registeredModelsCategoryFiltered.clear();
166
167 modelMenu.exec(QPoint(pos.x(), pos.y()));
168 }
169 }
170}
unsigned int uint
Definition VkReduce.h:5
int PortIndex
QtNodeFlowView(QWidget *parent=Q_NULLPTR)
void showPortContextMenu(QtNode &n, const PortIndex index, const QPointF &pos)