ICF 3.1.1.10
Technical documentation of ICF Libraries
TShapeParamsGuiCompBase.h
Go to the documentation of this file.
1/********************************************************************************
2** This file is part of the ICF Framework. Copyright (C) Witold Gantzke & Kirill Lepskiy
3** ICF Framework may be used under the terms of the LGPL License v. 2.1 by the Free Software Foundation.
4********************************************************************************/
5
6#pragma once
7
8
9// Qt includes
10#include <QtCore/QtGlobal>
11#include <QtWidgets/QMenu>
12#include <QtWidgets/QPushButton>
13#include <QtWidgets/QToolButton>
14#include <QtWidgets/QToolBar>
15
16// ICF includes
17#include <i2d/ICalibration2d.h>
19#include <iview/IColorSchema.h>
20#include <iview/IShapeFactory.h>
24
25
26namespace i2dgui
27{
28
29
30template <class Ui, class Shape, class ShapeModel>
33 istdgui::TDesignerGuiObserverCompBase<Ui, ShapeModel> >,
34 virtual public iview::IShapeFactory
35{
36public:
38
39 I_BEGIN_BASE_COMPONENT(TShapeParamsGuiCompBase);
40 I_REGISTER_INTERFACE(iview::IShapeFactory);
41 I_ASSIGN(m_defaultUnitInfoCompPtr, "DefaultUnitInfo", "Provide default information about the logical value units e.g. mm, this will be used if no unit information found in model", false, "DefaultUnitInfo");
42 I_ASSIGN(m_colorSchemaCompPtr, "ShapeColorSchema", "Color schema used by displayed shape", false, "ShapeColorSchema");
43 I_ASSIGN(m_fixedPositionAttrPtr, "FixedPosition", "If enabled, the shape position will be not editable", true, false);
44 I_ASSIGN(m_fixedPositionParamPtr, "FixedPositionParam", "If set, will be used instead of FixedPosition attribute", false, "FixedPositionParam");
45 I_ASSIGN(m_allowToolsMenuAttrPtr, "ShowTools", "Show extended shape edit tools", true, true);
46 I_ASSIGN(m_toolBarGuiCompPtr, "ToolBarGui", "Toolbar GUI object to fill with actions", false, "ToolBarGui");
47 I_ASSIGN(m_shapeToolTipAttrPtr, "ShapeToolTip", "Tool tip will be show on console", false, "");
48 I_END_COMPONENT;
49
51
52 // reimplemented (imod::IObserver)
53 bool OnModelAttached(imod::IModel* modelPtr, istd::IChangeable::ChangeSet& changeMask) override;
54 bool OnModelDetached(imod::IModel* modelPtr) override;
55
56 // reimplemented (iview::IShapeFactory)
57 std::unique_ptr<iview::IShape> CreateShape(const istd::IChangeable* objectPtr, bool connectToModel = false) const override;
58
59protected:
60 typedef typename BaseClass::Shapes Shapes;
62
63 QString GetUnitName() const;
64 bool IsPositionFixed() const;
65 bool IsToolsMenuAllowed() const;
66 QToolBar* GetToolBar() const;
67
71 virtual void CreateToolsMenu(QAbstractButton* buttonPtr);
72 virtual bool PopulateActions(QWidget& host, imod::IModel* modelPtr);
73 virtual void OnModelAttachedAndGuiShown(imod::IModel* modelPtr);
74 virtual void OnModelDetachedOrGuiHidden(imod::IModel* modelPtr);
75 virtual void OnActionTriggered(QAction* actionPtr);
76
80 virtual std::unique_ptr<iview::IShape> CreateShapeInstance() const;
81
82 // reimplemented (i2dgui::TViewExtenderCompBase)
83 void CreateShapes(int sceneId, Shapes& result) override;
84
85 // reimplemented (istdgui::CGuiComponentBase)
86 void OnGuiDestroyed() override;
87 void OnGuiShown() override;
88 void OnGuiHidden() override;
89
90 // reimplemented (istdgui::TGuiObserverWrap)
91 void OnGuiModelAttached() override;
92 void OnGuiModelDetached() override;
93
94 // reimplemented (imod::IModelEditor)
95 void SetReadOnly(bool state) override;
96
97private:
98 QMenu* m_menuPtr;
99 QAbstractButton* m_menuButtonPtr;
100
101 typedef QSet<QAction*> Actions;
102 Actions m_toolBarActions;
103
104 I_REF(imath::IUnitInfo, m_defaultUnitInfoCompPtr);
105 I_REF(iview::IColorSchema, m_colorSchemaCompPtr);
106 I_REF(iprm::IEnableableParam, m_fixedPositionParamPtr);
107 I_ATTR(bool, m_fixedPositionAttrPtr);
108 I_ATTR(bool, m_allowToolsMenuAttrPtr);
109 I_REF(istdgui::IGuiObject, m_toolBarGuiCompPtr);
110 I_TEXTATTR(m_shapeToolTipAttrPtr);
111};
112
113
114// public methods
115
116template <class Ui, class Shape, class ShapeModel>
118: m_menuPtr(nullptr),
119 m_menuButtonPtr(nullptr)
120{
121}
122
123
124// reimplemented (imod::IObserver)
125
126template <class Ui, class Shape, class ShapeModel>
128{
129 if (BaseClass::OnModelAttached(modelPtr, changeMask)) {
130 const ShapesMap& shapesMap = BaseClass::GetShapesMap();
131 for (typename ShapesMap::const_iterator iter = shapesMap.begin();
132 iter != shapesMap.end();
133 ++iter) {
134 const Shapes& shapes = iter.value();
135 int shapesCount = shapes.GetCount();
136 for (int shapeIndex = 0; shapeIndex < shapesCount; ++shapeIndex) {
137 Shape* shapePtr = dynamic_cast<Shape*>(shapes.GetAt(shapeIndex));
138 if (shapePtr != nullptr) {
139 if (modelPtr->AttachObserver(shapePtr)) {
140 shapePtr->SetVisible(true);
141 }
142 }
143 }
144 }
145
146 return true;
147 }
148 else {
149 return false;
150 }
151}
152
153
154template <class Ui, class Shape, class ShapeModel>
156{
157 if (BaseClass::OnModelDetached(modelPtr)) {
158 const ShapesMap& shapesMap = BaseClass::GetShapesMap();
159 for (typename ShapesMap::const_iterator iter = shapesMap.begin();
160 iter != shapesMap.end();
161 ++iter) {
162 const Shapes& shapes = iter.value();
163 int shapesCount = shapes.GetCount();
164 for (int shapeIndex = 0; shapeIndex < shapesCount; ++shapeIndex) {
165 Shape* shapePtr = dynamic_cast<Shape*>(shapes.GetAt(shapeIndex));
166 if (shapePtr != nullptr) {
167 if (modelPtr->IsAttached(shapePtr)) {
168 modelPtr->DetachObserver(shapePtr);
169 }
170
171 shapePtr->SetVisible(false);
172 }
173 }
174 }
175
176 return true;
177 }
178 else {
179 return false;
180 }
181}
182
183
184// reimplemented (iview::IShapeFactory)
185
186template <class Ui, class Shape, class ShapeModel>
187std::unique_ptr<iview::IShape> TShapeParamsGuiCompBase<Ui, Shape, ShapeModel>::CreateShape(const istd::IChangeable* objectPtr, bool connectToModel) const
188{
189 std::unique_ptr<iview::IShape> shapePtr = CreateShapeInstance();
190 if (auto* interactiveShapePtr = dynamic_cast<iview::CInteractiveShapeBase*>(shapePtr.get())) {
191 interactiveShapePtr->SetEditablePosition(!IsPositionFixed());
192
193 if (m_colorSchemaCompPtr != nullptr) {
194 interactiveShapePtr->SetUserColorSchema(m_colorSchemaCompPtr.get());
195 }
196
197 if (m_shapeToolTipAttrPtr != nullptr) {
198 interactiveShapePtr->SetDefaultDescription(*m_shapeToolTipAttrPtr);
199 }
200 }
201
202 if (connectToModel) {
203 imod::IModel* modelPtr = dynamic_cast<imod::IModel*>(const_cast<istd::IChangeable*>(objectPtr));
204 if (modelPtr != nullptr) {
205 if (modelPtr->AttachObserver(shapePtr.get())) {
206 shapePtr->SetVisible(true);
207 }
208 }
209 }
210
211 return shapePtr;
212}
213
214
215// protected methods
216
217template <class Ui, class Shape, class ShapeModel>
219{
220 if (m_fixedPositionParamPtr != nullptr) {
221 return m_fixedPositionParamPtr->IsEnabled();
222 }
223
224 return *m_fixedPositionAttrPtr;
225}
226
227
228template <class Ui, class Shape, class ShapeModel>
230{
231 return *m_allowToolsMenuAttrPtr;
232}
233
234
235template <class Ui, class Shape, class ShapeModel>
237{
238 return m_toolBarGuiCompPtr != nullptr ? dynamic_cast<QToolBar*>(m_toolBarGuiCompPtr->GetWidget()) : nullptr;
239}
240
241
242template <class Ui, class Shape, class ShapeModel>
244{
245 const imath::IUnitInfo* unitInfoPtr = nullptr;
246
247 const ShapeModel* objectPtr = BaseClass::GetObservedObject();
248 if (objectPtr != nullptr) {
249 const i2d::ICalibration2dProvider* calibrationProviderPtr = dynamic_cast<const i2d::ICalibration2dProvider*>(objectPtr);
250 if (calibrationProviderPtr != nullptr) {
251 const i2d::ICalibration2d* calibrationPtr = calibrationProviderPtr->GetCalibration();
252 if (calibrationPtr != nullptr) {
253 unitInfoPtr = calibrationPtr->GetArgumentUnitInfo();
254 }
255 }
256 }
257
258 if (unitInfoPtr != nullptr) {
259 return unitInfoPtr->GetUnitName();
260 }
261
262 if (m_defaultUnitInfoCompPtr != nullptr) {
263 return m_defaultUnitInfoCompPtr->GetUnitName();
264 }
265
266 return QString();
267}
268
269
270template <class Ui, class Shape, class ShapeModel>
272{
273 return std::unique_ptr<iview::IShape>{new Shape()};
274}
275
276
277template <class Ui, class Shape, class ShapeModel>
279{
280 m_menuButtonPtr = buttonPtr;
281
282 if (buttonPtr == nullptr) {
283 return;
284 }
285
286 if (!IsToolsMenuAllowed()) {
287 buttonPtr->hide();
288 return;
289 }
290
291 if (m_menuPtr == nullptr) {
292 m_menuPtr = new QMenu(buttonPtr);
293 QObject::connect(m_menuPtr, SIGNAL(triggered(QAction*)), this, SLOT(OnActionTriggered(QAction*)));
294
295 QPushButton* pushButtonPtr = dynamic_cast<QPushButton*>(buttonPtr);
296 if (pushButtonPtr != nullptr) {
297 pushButtonPtr->setMenu(m_menuPtr);
298 }
299 else {
300 QToolButton* toolButtonPtr = dynamic_cast<QToolButton*>(buttonPtr);
301 if (toolButtonPtr != nullptr) {
302 toolButtonPtr->setMenu(m_menuPtr);
303 }
304 }
305 }
306}
307
308
309template <class Ui, class Shape, class ShapeModel>
311{
312 return true;
313}
314
315
316template <class Ui, class Shape, class ShapeModel>
318{
319 if (m_menuPtr != nullptr) {
320 m_menuPtr->clear();
321
322 if (PopulateActions(*m_menuPtr, modelPtr)) {
323 m_menuButtonPtr->setEnabled(true);
324 }
325 else
326 m_menuButtonPtr->setEnabled(false);
327 }
328
329 QToolBar* toolBarPtr = GetToolBar();
330 if (toolBarPtr != nullptr) {
331 // get actual toolbar actions
332 auto toolbarKeys = toolBarPtr->actions();
333 QSet<QAction*> oldActions(toolbarKeys.begin(), toolbarKeys.end());
334
335 if (PopulateActions(*toolBarPtr, modelPtr)) {
336 auto newToolbarKeys = toolBarPtr->actions();
337 // store added actions
338 QSet<QAction*> newActions(newToolbarKeys.begin(), newToolbarKeys.end());
339 m_toolBarActions = newActions - oldActions;
340
341 toolBarPtr->setVisible(true);
342
343 // connect toolbar signals ONLY if there is no menu
344 // because of a Qt issue, an action added to both of menu and toolbar will emit actionTriggered() signal twice :(
345 if (m_menuPtr == nullptr) {
346 QObject::connect(toolBarPtr, SIGNAL(actionTriggered(QAction*)), this, SLOT(OnActionTriggered(QAction*)));
347 }
348 }
349 else {
350 toolBarPtr->disconnect();
351 }
352 }
353}
354
355
356template <class Ui, class Shape, class ShapeModel>
358{
359 if (m_menuButtonPtr != nullptr) {
360 m_menuButtonPtr->setEnabled(false);
361 }
362
363 QToolBar* toolBarPtr = GetToolBar();
364 if (toolBarPtr) {
365 toolBarPtr->disconnect();
366
367 // depopulate stored actions
368 for (Actions::const_iterator iter = m_toolBarActions.constBegin(); iter != m_toolBarActions.constEnd(); ++iter) {
369 toolBarPtr->removeAction(*iter);
370 }
371
372 m_toolBarActions.clear();
373 }
374}
375
376
377// reimplemented (i2dgui::TShapeParamsGuiCompBase)
378
379template <class Ui, class Shape, class ShapeModel>
383
384
385// reimplemented (i2dgui::TViewExtenderCompBase)
386
387template <class Ui, class Shape, class ShapeModel>
389{
390 bool areShapesVisible = !BaseClass::IsReadOnly();
391 auto shapePtr = CreateShape(BaseClass::GetObservedObject(), true);
392 if (shapePtr != nullptr) {
393 shapePtr->SetVisible(areShapesVisible);
394 result.PushBack(shapePtr.release());
395 }
396}
397
398
399// reimplemented (istdgui::CGuiComponentBase)
400
401template <class Ui, class Shape, class ShapeModel>
403{
404 m_menuButtonPtr = nullptr;
405 if (m_menuPtr != nullptr) {
406 m_menuPtr->deleteLater();
407
408 m_menuPtr = nullptr;
409 }
410
411 BaseClass::OnGuiDestroyed();
412}
413
414
415template <class Ui, class Shape, class ShapeModel>
417{
418 BaseClass::OnGuiShown();
419
420 OnModelAttachedAndGuiShown(BaseClass::GetObservedModel());
421}
422
423
424template <class Ui, class Shape, class ShapeModel>
426{
427 OnModelDetachedOrGuiHidden(BaseClass::GetObservedModel());
428
429 BaseClass::OnGuiHidden();
430}
431
432
433// reimplemented (istdgui::TGuiObserverWrap)
434
435template <class Ui, class Shape, class ShapeModel>
437{
438 BaseClass::OnGuiModelAttached();
439
440 if (BaseClass::IsGuiShown()) {
441 OnModelAttachedAndGuiShown(BaseClass::GetObservedModel());
442 }
443
444 m_fixedPositionParamPtr.EnsureInitialized();
445}
446
447
448template <class Ui, class Shape, class ShapeModel>
450{
451 OnModelDetachedOrGuiHidden(BaseClass::GetObservedModel());
452
453 BaseClass::OnGuiModelDetached();
454}
455
456
457// reimplemented (imod::IModelEditor)
458
459template <class Ui, class Shape, class ShapeModel>
461{
462 BaseClass::SetReadOnly(state);
463 BaseClass::SetAllShapesVisible(!state);
464}
465
466
467} // namespace iview
468
469
virtual const imath::IUnitInfo * GetArgumentUnitInfo() const =0
Get unit description of calibration input (transformation function argument).
Common interface for an object, which delivers a 2D-calibration.
virtual const ICalibration2d * GetCalibration() const =0
Get access to transformation object, which transforms a local logical coordinate system to global one...
i2dgui::TViewExtenderCompBase< istdgui::TDesignerGuiObserverCompBase< Ui, ShapeModel > > BaseClass
void OnGuiShown() override
Called from widget event filter when slave widget is shown.
void SetReadOnly(bool state) override
Set flag that the model data can be changed.
bool OnModelDetached(imod::IModel *modelPtr) override
This call back function will be called, if an observable object is about to be detached.
virtual bool PopulateActions(QWidget &host, imod::IModel *modelPtr)
bool OnModelAttached(imod::IModel *modelPtr, istd::IChangeable::ChangeSet &changeMask) override
This call back function will be called, if an observable object is about to be attached.
void OnGuiDestroyed() override
Called just before GUI is released.
virtual void OnModelAttachedAndGuiShown(imod::IModel *modelPtr)
virtual void OnModelDetachedOrGuiHidden(imod::IModel *modelPtr)
void OnGuiHidden() override
Called from widget event filter when slave widget is hidden.
virtual std::unique_ptr< iview::IShape > CreateShapeInstance() const
Simple creation of shape instance.
virtual void OnActionTriggered(QAction *actionPtr)
void CreateShapes(int sceneId, Shapes &result) override
virtual void CreateToolsMenu(QAbstractButton *buttonPtr)
Maintenance of the tools actions.
std::unique_ptr< iview::IShape > CreateShape(const istd::IChangeable *objectPtr, bool connectToModel=false) const override
Create a graphical representation of the given 2D-object object.
Common interface to get information about a measurement unit.
Definition IUnitInfo.h:27
virtual QString GetUnitName() const =0
Get name of unit.
Common interface for model objects, that supports Model/Observer design pattern.
Definition IModel.h:29
virtual void DetachObserver(IObserver *observerPtr)=0
Detaches model object from observer observerPtr.
virtual bool AttachObserver(IObserver *observerPtr)=0
Attaches model object to observer observerPtr.
virtual bool IsAttached(const IObserver *observerPtr) const =0
Returns true if observer observer is attached to this model object.
Interface for objects which can be enabled/disabled.
Set of change flags (its IDs).
Definition IChangeable.h:38
Common interface for data model objects, which can be changed.
Definition IChangeable.h:32
Common interface for GUI objects using in component context.
Definition IGuiObject.h:27
Base class of shape implementation with user interaction.
Defines set of standard pens, brushes and simple management of unions.
Interface for creation of visualization shapes of some geometrical object.
This package contains Qt based implementations for 2D graphic objects.

© Witold Gantzke and Kirill Lepskiy