ImagingTools Core SDK
TQmlModelEditorCompBase.h
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ImtCore-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtCore/QJsonDocument>
7
8// ACF includes
9#include <imod/TSingleModelObserverBase.h>
10
11// ImtCore includes
12#include <imtqml/CQmlModelEditorCompBase.h>
13
14
15namespace imtqml
16{
17
18
19template<typename ModelInterface>
20class TQmlModelEditorCompBase:
21 public CQmlModelEditorCompBase,
22 public imod::TSingleModelObserverBase<ModelInterface>
23{
24public:
25 typedef CQmlModelEditorCompBase BaseClass;
26 typedef imod::TSingleModelObserverBase<ModelInterface> BaseClass2;
27
28 I_BEGIN_BASE_COMPONENT(TQmlModelEditorCompBase)
29 I_END_COMPONENT;
30
31 TQmlModelEditorCompBase();
32
33protected:
37 virtual QJsonDocument CreateRepresentationFromObject(const ModelInterface& object) const = 0;
38
42 virtual void UpdateObjectFromRepresentation(const QJsonDocument& representation, ModelInterface& object) const = 0;
43
44 // reimplemented (imod::CSingleModelObserverBase)
45 virtual void OnUpdate(const istd::IChangeable::ChangeSet& changeSet) override;
46
47 // reimplemented (CQmlModelEditorCompBase)
48 virtual void OnGuiCreated() override;
49
50protected:
51 class UpdateBlocker
52 {
53 public:
54 explicit UpdateBlocker(const TQmlModelEditorCompBase<ModelInterface>* parentPtr);
55 ~UpdateBlocker();
56
57 private:
58 const TQmlModelEditorCompBase& m_parent;
59 };
60
61private:
62 bool IsUpdateBlocked() const;
63
64 // reimplemented (CQmlBasedEditorCompBase)
65 virtual void OnRepresentationChanged() override;
66
67private:
68 bool m_isUpdatePending = false;
69 mutable int m_ignoreUpdatesCounter = 0;
70};
71
72
73// public methods
74
75template<typename ModelInterface>
76TQmlModelEditorCompBase<ModelInterface>::TQmlModelEditorCompBase()
77{
78}
79
80
81// protected methods
82
83// reimplemented (imod::CSingleModelObserverBase)
84
85template<typename ModelInterface>
86inline void TQmlModelEditorCompBase<ModelInterface>::OnUpdate(const istd::IChangeable::ChangeSet& /*changeSet*/)
87{
88 if (IsUpdateBlocked()){
89 return;
90 }
91
92 UpdateBlocker blocker(this);
93
94 ModelInterface* objectPtr = BaseClass2::GetObservedObject();
95 Q_ASSERT(objectPtr != nullptr);
96
97 QQuickItem* quickItemPtr = m_quickWidget->rootObject();
98 if (quickItemPtr != nullptr){
99 QJsonDocument jsonDoc = CreateRepresentationFromObject(*objectPtr);
100 if (jsonDoc.isObject()){
101 QString jsonRepresentation = QString::fromUtf8(jsonDoc.toJson(QJsonDocument::Compact));
102
103 QMetaObject::invokeMethod(
104 quickItemPtr, "setRepresentation", Q_ARG(QVariant, QVariant::fromValue(jsonRepresentation)));
105 }
106 }
107 else{
108 m_isUpdatePending = true;
109 }
110}
111
112
113// reimplemented (CQuickObjectCompBase)
114
115template<typename ModelInterface>
116inline void TQmlModelEditorCompBase<ModelInterface>::OnGuiCreated()
117{
118 BaseClass::OnGuiCreated();
119
120 if (m_isUpdatePending){
121 m_isUpdatePending = false;
122
123 OnUpdate(istd::IChangeable::GetAnyChange());
124 }
125}
126
127
128// private methods
129
130template<typename ModelInterface>
131inline bool TQmlModelEditorCompBase<ModelInterface>::IsUpdateBlocked() const
132{
133 return (m_ignoreUpdatesCounter > 0);
134}
135
136
137// reimplemented (CQmlBasedEditorCompBase)
138
139template<typename ModelInterface>
140inline void TQmlModelEditorCompBase<ModelInterface>::OnRepresentationChanged()
141{
142 if (IsUpdateBlocked()){
143 return;
144 }
145
146 UpdateBlocker blocker(this);
147
148 ModelInterface* objectPtr = BaseClass2::GetObservedObject();
149 Q_ASSERT(objectPtr != nullptr);
150
151 QQuickItem* quickItemPtr = m_quickWidget->rootObject();
152 if (quickItemPtr != nullptr){
153 QVariant var;
154 if (QMetaObject::invokeMethod(
155 quickItemPtr, "getRepresentation", Qt::DirectConnection, Q_RETURN_ARG(QVariant, var)))
156 {
157 if (var.typeId() == QMetaType::QString){
158 QString jsonRepresentation = var.toString();
159
160 QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonRepresentation.toUtf8());
161
162 UpdateObjectFromRepresentation(jsonDocument, *objectPtr);
163 }
164 }
165 }
166}
167
168
169// public methods of embedded class UpdateBlocker
170
171template<typename ModelInterface>
172TQmlModelEditorCompBase<ModelInterface>::UpdateBlocker::UpdateBlocker(const TQmlModelEditorCompBase<ModelInterface>* parentPtr)
173 :m_parent(*parentPtr)
174{
175 ++m_parent.m_ignoreUpdatesCounter;
176}
177
178
179template<typename ModelInterface>
180TQmlModelEditorCompBase<ModelInterface>::UpdateBlocker::~UpdateBlocker()
181{
182 --m_parent.m_ignoreUpdatesCounter;
183}
184
185
186} // namespace imtqml
187
188