CANdevStudio
Development tool for CAN bus simulation
Loading...
Searching...
No Matches
componentmodel.h
Go to the documentation of this file.
1#ifndef COMPONENTMODEL_H
2#define COMPONENTMODEL_H
3
4#include <QThread>
5#include <QtCore/QObject>
6#include <QtWidgets/QLabel>
7#include <bcastmsgs.h>
8#include <functional>
9#include <log.h>
10#include <nodes/Node>
11#include <nodes/NodeDataModel>
12
14
15struct ComponentModelInterface : public QtNodes::NodeDataModel {
16
17 Q_OBJECT
18
19public:
20 virtual ~ComponentModelInterface() = default;
22 virtual void setCaption(const QString& caption) = 0;
23 virtual bool restored() = 0;
24 virtual void setColorMode(bool darkMode) = 0;
25 virtual bool hasSeparateThread() const = 0;
26 virtual void initModel(QtNodes::Node& node, int nodeCnt, bool darkMode) = 0;
27 virtual void simBcastRcv(const QJsonObject& msg, const QVariant& param) = 0;
28 virtual void simBcastSndSlot(const QJsonObject& msg, const QVariant& param) = 0;
29
30signals:
33 void handleDock(QWidget* widget);
34 void simBcastSnd(const QJsonObject& msg, const QVariant& param);
35};
36
37template <typename C, typename Derived> class ComponentModel : public ComponentModelInterface {
38
39public:
40 ComponentModel() = default;
41
42 ComponentModel(const QString& name)
43 : _caption(name)
44 , _name(name)
45 {
46 }
47
49 {
50 if (_thread) {
51 _thread->exit();
52 _thread->wait();
53 }
54 }
55
56 virtual void initModel(QtNodes::Node& node, int nodeCnt, bool darkMode) override
57 {
58 if (!restored()) {
59 setCaption(node.nodeDataModel()->caption() + " #" + QString::number(nodeCnt));
60 }
61
62 // For some reason QWidget title is being set to name instead of caption.
63 // TODO: investigate why
64 setCaption(node.nodeDataModel()->caption());
65 setColorMode(darkMode);
66
67 connect((Derived*)this, &Derived::requestRedraw, [&node] { node.nodeGraphicsObject().update(); });
68 connect(this, &ComponentModelInterface::startSimulation, &_component, &C::startSimulation);
69 connect(this, &ComponentModelInterface::stopSimulation, &_component, &C::stopSimulation);
70 connect(&_component, &C::mainWidgetDockToggled, this, &ComponentModelInterface::handleDock);
71 connect(&_component, &C::simBcastSnd, this, &ComponentModelInterface::simBcastSndSlot);
72
73 _id = node.id();
74
75 if (hasSeparateThread()) {
76 _thread = std::make_unique<QThread>();
77 if (_thread) {
78 cds_info("Setting separate event loop for component {}", _caption.toStdString());
79
80 this->moveToThread(_thread.get());
81 _component.moveToThread(_thread.get());
82
83 _thread->start();
84 }
85 }
86 }
87
92 virtual QString caption() const override
93 {
94 return _caption;
95 }
96
101 virtual void setCaption(const QString& caption) override
102 {
104
105 auto w = _component.mainWidget();
106 if (w) {
107 w->setWindowTitle(_caption);
108 }
109 }
110
115 virtual QString name() const override
116 {
117 return _name;
118 }
119
124 virtual std::unique_ptr<QtNodes::NodeDataModel> clone() const override
125 {
126 return std::make_unique<Derived>();
127 }
128
133 virtual QJsonObject save() const override
134 {
135 QJsonObject json = _component.getConfig();
136 json["name"] = name();
137 json["caption"] = caption();
138 return json;
139 }
140
145 virtual void restore(QJsonObject const& json) override
146 {
147 if (json.find("name") == json.end()) {
148 cds_error("Problem with validation of restore configuration: component model name tag not exist.");
149 return;
150 }
151
152 if (json.find("caption") == json.end()) {
153 cds_error("Problem with validation of restore configuration: component model caption tag not exist.");
154 return;
155 }
156
157 _restored = true;
158 _name = json.find("name").value().toString();
159 _caption = json.find("caption").value().toString();
160 _component.setConfig(json);
161 _component.configChanged();
162 cds_info("Correct validation of restore configuration for {} modul", _name.toStdString());
163 }
164
169 virtual QWidget* embeddedWidget() override
170 {
171 return _label;
172 }
173
178 virtual bool resizable() const override
179 {
180 return _resizable;
181 }
182
188 {
189 return _component;
190 }
191
192 virtual bool restored() override
193 {
194 return _restored;
195 }
196
197 virtual void setColorMode(bool darkMode) override
198 {
199 _darkMode = darkMode;
200
201 if (darkMode) {
202 QColor bgColor = QColor(94, 94, 94);
203 _nodeStyle.GradientColor0 = bgColor;
204 _nodeStyle.GradientColor1 = bgColor;
205 _nodeStyle.GradientColor2 = bgColor;
206 _nodeStyle.GradientColor3 = bgColor;
207 _nodeStyle.NormalBoundaryColor = bgColor;
208 _nodeStyle.FontColor = QColor(206, 206, 206);
209 _nodeStyle.FontColorFaded = QColor(125, 125, 125);
210 _nodeStyle.ShadowColor = QColor(20, 20, 20);
211 _nodeStyle.ConnectionPointColor = QColor(125, 125, 125);
212 _nodeStyle.FilledConnectionPointColor = QColor(206, 206, 206);
213 } else {
214 QColor bgColor = QColor(255, 255, 255);
215 _nodeStyle.GradientColor0 = bgColor;
216 _nodeStyle.GradientColor1 = bgColor;
217 _nodeStyle.GradientColor2 = bgColor;
218 _nodeStyle.GradientColor3 = bgColor;
219 _nodeStyle.NormalBoundaryColor = bgColor;
220 _nodeStyle.FontColor = QColor(110, 110, 110);
221 _nodeStyle.FontColorFaded = QColor(189, 189, 189);
222 _nodeStyle.ShadowColor = QColor(170, 170, 170);
223 _nodeStyle.ConnectionPointColor = QColor(170, 170, 170);
224 _nodeStyle.FilledConnectionPointColor = QColor(110, 110, 110);
225 }
226
227 _nodeStyle.SelectedBoundaryColor = QColor(20, 146, 202);
228 _nodeStyle.Opacity = 1.0;
229 _nodeStyle.PenWidth = 1.5;
230 _nodeStyle.HoveredPenWidth = 2.0;
231 _nodeStyle.ConnectionPointDiameter = 3.5;
232
233 setNodeStyle(_nodeStyle);
234 }
235
236 virtual bool hasSeparateThread() const override
237 {
238 // Override if you want model and underlying component to be run in separate thread
239 return false;
240 }
241
242 void simBcastRcv(const QJsonObject& msg, const QVariant& param) override
243 {
244 if (msg["id"].toString() != _id.toString()) {
245 _component.simBcastRcv(msg, param);
246 } else if (msg["msg"].toString() == BcastMsg::NodeCreated) {
247 QJsonObject msg2 = msg;
248 msg2["msg"] = BcastMsg::InitDone;
249 _component.simBcastRcv(msg2, param);
250 }
251 }
252
253 void simBcastSndSlot(const QJsonObject& msg, const QVariant& param) override
254 {
255 emit simBcastSnd(fillBcastMsg(msg), param);
256 }
257
258private:
259 QJsonObject fillBcastMsg(const QJsonObject& msg)
260 {
261 QJsonObject ret(msg);
262
263 ret["id"] = _id.toString();
264 ret["name"] = name();
265 ret["caption"] = caption();
266
267 return ret;
268 }
269
270protected:
272 QLabel* _label{ new QLabel };
273 QString _caption;
274 QString _name;
275 bool _resizable{ false };
276 bool _restored{ false };
277 bool _darkMode{ true };
278 QtNodes::NodeStyle _nodeStyle;
279 std::unique_ptr<QThread> _thread;
280 QUuid _id;
281};
282
283#endif // COMPONENTMODEL_H
Definition componentmodel.h:37
virtual ~ComponentModel()
Definition componentmodel.h:48
ComponentModel(const QString &name)
Definition componentmodel.h:42
QLabel * _label
Definition componentmodel.h:272
virtual QString name() const override
Used to identify model by data model name.
Definition componentmodel.h:115
ComponentModel()=default
bool _restored
Definition componentmodel.h:276
void simBcastSndSlot(const QJsonObject &msg, const QVariant &param) override
Definition componentmodel.h:253
C _component
Definition componentmodel.h:271
bool _resizable
Definition componentmodel.h:275
QUuid _id
Definition componentmodel.h:280
QString _caption
Definition componentmodel.h:273
virtual void setColorMode(bool darkMode) override
Definition componentmodel.h:197
bool _darkMode
Definition componentmodel.h:277
std::unique_ptr< QThread > _thread
Definition componentmodel.h:279
virtual void setCaption(const QString &caption) override
Sets model caption and updates widget title.
Definition componentmodel.h:101
virtual bool restored() override
Definition componentmodel.h:192
virtual QString caption() const override
Used to get node caption.
Definition componentmodel.h:92
virtual bool resizable() const override
Used to get information if node is resizable.
Definition componentmodel.h:178
QtNodes::NodeStyle _nodeStyle
Definition componentmodel.h:278
void simBcastRcv(const QJsonObject &msg, const QVariant &param) override
Definition componentmodel.h:242
virtual ComponentInterface & getComponent() override
Component getter.
Definition componentmodel.h:187
virtual std::unique_ptr< QtNodes::NodeDataModel > clone() const override
Creates new node of the same type.
Definition componentmodel.h:124
virtual QWidget * embeddedWidget() override
Used to get widget embedded in Node.
Definition componentmodel.h:169
virtual bool hasSeparateThread() const override
Definition componentmodel.h:236
virtual void initModel(QtNodes::Node &node, int nodeCnt, bool darkMode) override
Definition componentmodel.h:56
virtual void restore(QJsonObject const &json) override
Used to restore node configurations.
Definition componentmodel.h:145
virtual QJsonObject save() const override
Possibility to save node properties.
Definition componentmodel.h:133
QString _name
Definition componentmodel.h:274
#define cds_error(fmt,...)
Definition log.h:21
#define cds_info(fmt,...)
Definition log.h:25
Interface to be implemented by every component.
Definition componentinterface.h:15
Definition componentmodel.h:15
virtual void initModel(QtNodes::Node &node, int nodeCnt, bool darkMode)=0
virtual void simBcastRcv(const QJsonObject &msg, const QVariant &param)=0
virtual ComponentInterface & getComponent()=0
virtual ~ComponentModelInterface()=default
void handleDock(QWidget *widget)
virtual void setCaption(const QString &caption)=0
virtual bool restored()=0
virtual void setColorMode(bool darkMode)=0
virtual void simBcastSndSlot(const QJsonObject &msg, const QVariant &param)=0
void simBcastSnd(const QJsonObject &msg, const QVariant &param)
virtual bool hasSeparateThread() const =0