CANdevStudio
Development tool for CAN bus simulation
Loading...
Searching...
No Matches
projectconfig_p.h
Go to the documentation of this file.
1#ifndef PROJECTCONFIG_P_H
2#define PROJECTCONFIG_P_H
3
4#include "flowviewwrapper.h"
5#include "iconlabel.h"
6#include "modeltoolbutton.h"
7#include "pcimpl.h"
8#include "ui_projectconfig.h"
9#include <QMenu>
10#include <QtWidgets/QPushButton>
11#include <log.h>
12#include <modelvisitor.h> // apply_model_visitor
13#include <nodes/Node>
15#include <bcastmsgs.h>
16
17#include "componentinterface.h"
18#include "plugins.hpp"
19
20namespace Ui {
22}
23
24class ProjectConfigPrivate : public QWidget {
25 Q_OBJECT
26 Q_DECLARE_PUBLIC(ProjectConfig)
27
28public:
30 : QWidget(parent)
31 , _ctx(std::move(ctx))
32 , _pcInt(_ctx.get<PCInterface>())
33 , _graphView(new FlowViewWrapper(&_graphScene))
34 , _ui(std::make_unique<Ui::ProjectConfigPrivate>())
35 , q_ptr(q)
36 , _plugins(_graphScene.registry())
37 {
39 &_graphScene, std::bind(&ProjectConfigPrivate::nodeCreatedCallback, this, std::placeholders::_1));
41 &_graphScene, std::bind(&ProjectConfigPrivate::nodeDeletedCallback, this, std::placeholders::_1));
43 &_graphScene, std::bind(&ProjectConfigPrivate::nodeDoubleClickedCallback, this, std::placeholders::_1));
44 _pcInt.setNodeContextMenuCallback(&_graphScene,
45 std::bind(
46 &ProjectConfigPrivate::nodeContextMenuCallback, this, std::placeholders::_1, std::placeholders::_2));
47
48 _ui->setupUi(this);
49 _ui->layout->addWidget(_graphView);
50
51 _ui->scrollArea->setMinimumSize(165, 0);
52 _ui->scrollArea->setMaximumSize(165, 10000);
53 _plugins.initSections(*_ui);
54
55 _pcInt.setConfigChangedCbk([this](QtNodes::Node& node) {
56 QJsonObject msg = initBcast(node);
57 msg["msg"] = BcastMsg::ConfigChanged;
58
59 auto& component = getComponent(node);
60 auto propObj = component.getQConfig();
61 auto prop = propObj->property("exposedProperties");
62
63 QJsonObject confObj;
64 for (const auto& p : prop.toStringList()) {
65 confObj[p] = propObj->property(p.toStdString().c_str()).toString();
66 }
67
68 msg["config"] = confObj;
69
70 emit simBcast(msg);
71 });
72 }
73
75 {
76 QColor bgColor;
77
78 if (_darkMode) {
79 bgColor = QColor(94, 94, 94);
80 } else {
81 bgColor = QColor(255, 255, 255);
82 }
83
84 _plugins.clearSections();
85 _plugins.addWidgets(bgColor);
86 }
87
89
90 QByteArray save() const
91 {
92 return _graphScene.saveToMemory();
93 }
94
95 void load(const QByteArray& data)
96 {
97 return _graphScene.loadFromMemory(data);
98 }
99
101 {
102 return _graphScene.clearScene();
103 };
104
105 void nodeCreatedCallback(QtNodes::Node& node)
106 {
107 Q_Q(ProjectConfig);
108
109 auto& iface = getComponentModel(node);
110 iface.initModel(node, _nodeCnt, _darkMode);
111
117
118 node.nodeGraphicsObject().setOpacity(node.nodeDataModel()->nodeStyle().Opacity);
119 addShadow(node);
120 node.nodeGraphicsObject().update();
121
122 _nodeCnt++;
123
124 cds_debug("Node '{}' created", node.nodeDataModel()->caption().toStdString());
125
126 QJsonObject msg = initBcast(node);
127 msg["msg"] = BcastMsg::NodeCreated;
128
129 emit simBcast(msg);
130 }
131
132 void nodeDeletedCallback(QtNodes::Node& node)
133 {
134 Q_Q(ProjectConfig);
135 auto& component = getComponent(node);
136
137 cds_debug("Node '{}' deleted", node.nodeDataModel()->caption().toStdString());
138
139 emit q->handleWidgetDeletion(component.mainWidget());
140
141 QJsonObject msg = initBcast(node);
142 msg["msg"] = BcastMsg::NodeDeleted;
143
144 emit simBcast(msg);
145 }
146
147 void nodeDoubleClickedCallback(QtNodes::Node& node)
148 {
149 auto& component = getComponent(node);
150
151 cds_debug("Node '{}' double clicked", node.nodeDataModel()->caption().toStdString());
152
153 if (component.mainWidget() != nullptr) {
154 openWidget(node);
155 } else {
156 if (!_simStarted) {
157 _pcInt.openProperties(node);
158 }
159 }
160 }
161
162 void nodeContextMenuCallback(QtNodes::Node& node, const QPointF& pos)
163 {
164 auto& component = getComponent(node);
165 cds_debug("Node '{}' context menu", node.nodeDataModel()->caption().toStdString());
166
167 QMenu contextMenu(tr("Node options"), this);
168
169 QAction actionOpen("Open", this);
170 connect(&actionOpen, &QAction::triggered, [this, &node]() { openWidget(node); });
171
172 QAction actionProperties("Properties", this);
173 connect(&actionProperties, &QAction::triggered, [this, &node]() { _pcInt.openProperties(node); });
174
175 if (_simStarted) {
176 actionProperties.setDisabled(true);
177 }
178
179 QAction actionDelete("Delete", this);
180 connect(&actionDelete, &QAction::triggered, [this, &node]() { _graphScene.removeNode(node); });
181
182 if (component.mainWidget() != nullptr) {
183 contextMenu.addAction(&actionOpen);
184 contextMenu.addAction(&actionProperties);
185 contextMenu.setDefaultAction(&actionOpen);
186 } else {
187 contextMenu.addAction(&actionProperties);
188 contextMenu.setDefaultAction(&actionProperties);
189 }
190
191 contextMenu.addAction(&actionDelete);
192
193 _pcInt.showContextMenu(contextMenu, mapToGlobal(_graphView->mapFromScene(pos)));
194 }
195
196 void updateNodeStyle(bool darkMode)
197 {
198 _darkMode = darkMode;
199
200 _graphScene.iterateOverNodes([this](QtNodes::Node* node) {
201 auto& iface = getComponentModel(*node);
202 iface.setColorMode(_darkMode);
203 node->nodeGraphicsObject().update();
204 addShadow(*node);
205 });
206
207 QJsonObject msg;
208 msg["msg"] = BcastMsg::GuiStyleSwitched;
209 msg["dark_mode_style"] = darkMode;
210
211 emit simBcast(msg);
212 }
213
214signals:
215 void simBcast(const QJsonObject& msg, const QVariant& param = QVariant());
216
217private:
218 void openWidget(QtNodes::Node& node)
219 {
220 Q_Q(ProjectConfig);
221 auto& component = getComponent(node);
222
223 emit q->handleWidgetShowing(component.mainWidget(), component.mainWidgetDocked());
224 }
225
226 ComponentInterface& getComponent(QtNodes::Node& node)
227 {
228 auto& iface = getComponentModel(node);
229 auto& component = iface.getComponent();
230 return component;
231 }
232
233 ComponentModelInterface& getComponentModel(QtNodes::Node& node)
234 {
235 auto dataModel = node.nodeDataModel();
236 assert(nullptr != dataModel);
237
238 auto iface = dynamic_cast<ComponentModelInterface*>(dataModel);
239 return *iface;
240 }
241
242 void addShadow(QtNodes::Node& node)
243 {
244 auto const& nodeStyle = node.nodeDataModel()->nodeStyle();
245 auto effect = new QGraphicsDropShadowEffect;
246
247 effect->setOffset(4, 4);
248 effect->setBlurRadius(20);
249 effect->setColor(nodeStyle.ShadowColor);
250 node.nodeGraphicsObject().setGraphicsEffect(effect);
251 }
252
253 QJsonObject initBcast(const QtNodes::Node& node)
254 {
255 QJsonObject msg;
256 msg["id"] = node.id().toString();
257 msg["name"] = node.nodeDataModel()->name();
258 msg["caption"] = node.nodeDataModel()->caption();
259
260 return msg;
261 }
262
263public:
264 bool _simStarted{ false };
265
266private:
267 ProjectConfigCtx _ctx;
268 PCInterface& _pcInt;
269 QtNodes::FlowScene _graphScene;
270 FlowViewWrapper* _graphView;
271 std::unique_ptr<Ui::ProjectConfigPrivate> _ui;
272 int _nodeCnt = 1;
273 ProjectConfig* q_ptr;
274 bool _darkMode;
275 Plugins _plugins;
276};
277#endif // PROJECTCONFIG_P_H
Definition pcimpl.h:11
Definition projectconfig.h:16
void startSimulation()
void handleWidgetDeletion(QWidget *widget)
void handleWidgetShowing(QWidget *widget, bool docked)
void handleDock(QWidget *component)
void stopSimulation()
Definition projectconfig_p.h:24
void addModelIcons()
Definition projectconfig_p.h:74
void nodeDoubleClickedCallback(QtNodes::Node &node)
Definition projectconfig_p.h:147
bool _simStarted
Definition projectconfig_p.h:264
void nodeDeletedCallback(QtNodes::Node &node)
Definition projectconfig_p.h:132
void clearGraphView()
Definition projectconfig_p.h:100
QByteArray save() const
Definition projectconfig_p.h:90
void load(const QByteArray &data)
Definition projectconfig_p.h:95
void updateNodeStyle(bool darkMode)
Definition projectconfig_p.h:196
void nodeCreatedCallback(QtNodes::Node &node)
Definition projectconfig_p.h:105
void nodeContextMenuCallback(QtNodes::Node &node, const QPointF &pos)
Definition projectconfig_p.h:162
void simBcast(const QJsonObject &msg, const QVariant &param=QVariant())
~ProjectConfigPrivate()
Definition projectconfig_p.h:88
ProjectConfigPrivate(ProjectConfig *q, QWidget *parent, ProjectConfigCtx &&ctx=ProjectConfigCtx(new PCImpl()))
Definition projectconfig_p.h:29
#define cds_debug(fmt,...)
Definition log.h:13
Definition canrawsender_p.h:13
Context< PCInterface > ProjectConfigCtx
Definition projectconfig.h:8
Interface to be implemented by every component.
Definition componentinterface.h:15
Definition componentmodel.h:15
virtual void simBcastRcv(const QJsonObject &msg, const QVariant &param)=0
void handleDock(QWidget *widget)
void simBcastSnd(const QJsonObject &msg, const QVariant &param)
Definition flowviewwrapper.h:7
Definition pcinterface.h:16
virtual void setNodeDoubleClickedCallback(QtNodes::FlowScene *scene, const node_t &cb)=0
virtual void setConfigChangedCbk(const node_t cb)=0
virtual void showContextMenu(QMenu &menu, const QPoint &pos)=0
virtual void setNodeContextMenuCallback(QtNodes::FlowScene *scene, const menu_t &cb)=0
virtual void setNodeDeletedCallback(QtNodes::FlowScene *scene, const node_t &cb)=0
virtual void setNodeCreatedCallback(QtNodes::FlowScene *scene, const node_t &cb)=0
virtual void openProperties(QtNodes::Node &node)=0