ATLAS Offline Software
Loading...
Searching...
No Matches
VP1Controller.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7// //
8// Implementation of class VP1Controller //
9// //
10// Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11// Initial version: August 2008 //
12// //
14
17#include "VP1Base/IVP1System.h"
23
24#include <QPushButton>
25#include <QCheckBox>
26#include <QComboBox>
27#include <QGroupBox>
28#include <QSpinBox>
29#include <QDoubleSpinBox>
30#include <QRadioButton>
31#include <QSlider>
32#include <QScrollArea>
33#include <QScrollBar>
34#include <QShortcut>
35#include <QButtonGroup>
36#include <QTimer>
37
38#include <Inventor/C/errors/debugerror.h>
39#include <Inventor/SbColor4f.h>
40#include <Inventor/nodes/SoMaterial.h>
41
43
44
45//____________________________________________________________________
47public:
48
49 const char * lastUpdateSlot;
51 class DialogInfo {
52 public:
53 DialogInfo(QPushButton * lb,std::unique_ptr<QWidget> dw,QAbstractButton * ec)
54 : enabledButton(ec), dialogWidget(std::move(dw)), launchButton(lb), neverShown(true) {}
56 QAbstractButton * enabledButton;
57 std::unique_ptr<QWidget> dialogWidget;
58 QPushButton * launchButton;
60 };
61
62 QList<DialogInfo *> dialogs;
63
64 SoMaterial * fallBackMaterial;
65};
66
67//____________________________________________________________________
69{
70 m_initVarsMode = true;
72 m_initVarsMode = false;
73}
74
75//____________________________________________________________________
76VP1Controller::VP1Controller(IVP1System * sys, const QString& classname )
77 : QWidget(0),//Controllers always created parentless.
78 VP1HelperClassBase(sys,classname),
79 m_d(new Imp),
80 m_initVarsMode(true)//Start as true in case any possible_change
81 //stuff are called before intLastVars()?
82{
83 m_d->fallBackMaterial = 0;
84 m_d->lastUpdateSlot = 0;
85 m_d->collWidget = 0;
86 setObjectName(classname);
87}
88
89//____________________________________________________________________
91{
92 for (Imp::DialogInfo* di : m_d->dialogs)
93 delete di;
94 if (m_d->fallBackMaterial)
95 m_d->fallBackMaterial->unref();
96 delete m_d;
97}
98
99//____________________________________________________________________
100QString VP1Controller::toString( const bool& par )
101{
102 return par?"On":"Off";
103}
104
105//____________________________________________________________________
106QString VP1Controller::toString( const QList<VP1Interval>& l )
107{
108 QString s;
109 for(int i=0;i<l.count();++i)
110 s+= l.at(i).toString()+(i==l.count()-1?"":", ");
111 return s;
112}
113
114//____________________________________________________________________
115QString VP1Controller::toString( SbColor4f p )
116{
117 float r, g, b, a;
118 p.getValue(r, g, b, a);
119 return "("+str(r)+", "+str(g)+", "+str(b)+", "+str(1-a)+")";
120}
121
122//____________________________________________________________________
123void VP1Controller::initDialog(std::unique_ptr<QWidget> dialogPtr, QPushButton* launchButton, QPushButton* closeButton,QAbstractButton* enabledButton)
124{
125 QString txt(enabledButton?enabledButton->text():launchButton->text());
126 txt.replace("&&","&");
127 dialogPtr->setWindowTitle(txt+" ["+systemBase()->name()+"]");
128 dialogPtr->setWindowIcon(QIcon(QString(":/vp1/icons/icons/3d_32x32.png")));
129 launchButton->setMaximumHeight(static_cast<int>(0.5+QFontMetricsF(launchButton->font()).height()*1.05+2));
130 launchButton->setMinimumHeight(launchButton->maximumHeight());
131 launchButton->setCheckable(true);
132
133 QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
134 sizePolicy.setHorizontalStretch(0);
135 sizePolicy.setVerticalStretch(0);
136 sizePolicy.setHeightForWidth(launchButton->sizePolicy().hasHeightForWidth());
137 launchButton->setSizePolicy(sizePolicy);
138 launchButton->setFocusPolicy(Qt::NoFocus);
139
140 if (enabledButton)
141 launchButton->setEnabled(enabledButton->isChecked());
142
143 auto di = std::make_unique<Imp::DialogInfo>(launchButton,std::move(dialogPtr),enabledButton);
144 QWidget* dialog = di->dialogWidget.get();
145 m_d->dialogs << di.release();
146
147 connect(launchButton,SIGNAL(clicked()),this,SLOT(toggleDialogState()));
148 if (enabledButton)
149 connect(enabledButton,SIGNAL(toggled(bool)),this,SLOT(enabledButtonStateChanged()));
150 CloseEventEater* closeEventEater = new CloseEventEater(this);
151 dialog->installEventFilter(closeEventEater);
152
153 if(closeButton) {
154 closeButton->setText("&Close");
155 closeButton->setToolTip("Close this dialog [Esc]");
156 connect(closeButton,SIGNAL(clicked()),dialog,SLOT(close()));
157 }
158 connect(new QShortcut(QKeySequence(Qt::Key_Escape), dialog),SIGNAL(activated()),dialog,SLOT(close()));
159
160 //To avoid an extra call in the code we do this a few times more than necessary (fixme: put in initLastVars!!):
161 int maxwidth(0);
162 for (Imp::DialogInfo* di : m_d->dialogs)
163 maxwidth = std::max(maxwidth,di->launchButton->sizeHint().width());
164 for (Imp::DialogInfo* di : m_d->dialogs)
165 di->launchButton->setMinimumWidth(maxwidth);
166}
167
168//____________________________________________________________________
170{
171 Imp::DialogInfo * di(0);
172 for (Imp::DialogInfo* di2 : m_d->dialogs) {
173 if (di2->enabledButton==sender()) {
174 di = di2;
175 break;
176 }
177 }
178 if (!di) {
179 message("ERROR: enabledButtonStateChanged() triggered with unrecognised sender() ="
180 +QString(sender()?sender()->objectName():"NULL"));
181 return;
182 }
183
184 bool on(di->enabledButton->isChecked());
185 if (di->launchButton->isEnabled()!=on)
186 di->launchButton->setEnabled(on);
187 if (!on) {
188 if (di->dialogWidget->isVisible())
189 di->dialogWidget->setVisible(false);
190 if (di->dialogWidget->windowState()==Qt::WindowMinimized)
191 di->dialogWidget->setWindowState(Qt::WindowNoState);
192 }
193}
194
195//____________________________________________________________________
197{
198 Imp::DialogInfo * di(0);
199 for (Imp::DialogInfo* di2 : m_d->dialogs) {
200 if (di2->launchButton==sender() || (widget && di2->dialogWidget.get()==widget)) {
201 di = di2;
202 break;
203 }
204 }
205
206 if (!di) {
207 message("ERROR: toggleDialogState() triggered with unrecognised sender() ="
208 +QString(sender()?sender()->objectName():"NULL"));
209 return;
210 }
211
212 bool oldvis = di->dialogWidget->isVisible();
213
214 if (oldvis&&di->dialogWidget->windowState()==Qt::WindowMinimized) {
215 di->dialogWidget->setWindowState(Qt::WindowNoState);
216 } else {
217 di->dialogWidget->setVisible(!oldvis);
218 if (!oldvis && di->neverShown) {
219 di->neverShown = false;
220 //do stuff
221 // QSize size(955, 717);
222 // size = size.expandedTo(VP1MainWindow->minimumSizeHint());
223 // di->dialogWidget->resize(di->dialogWidget->minimumSizeHint());
224 }
225 }
226
227 //synchronise toggle button state (for example if this was called by CloseEventEater)
228 if (di->launchButton->isCheckable() && oldvis){
229 di->launchButton->setChecked(false);
230 }
231}
232
233//____________________________________________________________________
235{
236 if (sender()!=m_d->collWidget||!m_d->collWidget) {
237 message("ERROR: Unexpected signal in collWidgetContentChanged slot!!");
238 return;
239 }
240 QScrollArea* scrollarea = dynamic_cast<QScrollArea*>(m_d->collWidget->parent());
241 if (!scrollarea&&m_d->collWidget->parent())
242 scrollarea = dynamic_cast<QScrollArea*>(m_d->collWidget->parent()->parent());
243 if (!scrollarea) {
244 message("ERROR: m_d->collWidget not child or grandchild of a scroll area!!");
245 return;
246 }
247 int width = m_d->collWidget->appropriateFixedWidth();
248 m_d->collWidget->setMinimumWidth(width);
249 m_d->collWidget->setMaximumWidth(width);
250 QScrollBar * sb = scrollarea->verticalScrollBar();
251 if (sb)
252 width+=sb->sizeHint().width();
253 scrollarea->setMinimumWidth(width+2);//2 is just some margin
254}
255
256//____________________________________________________________________
257void VP1Controller::setupCollWidgetInScrollArea(QScrollArea * scrollarea, VP1CollectionWidget* collWidget)
258{
259 if (!scrollarea || !collWidget) {
260 message("ERROR: NULL scrollarea or collWidget");
261 return;
262 }
263 QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
264 sizePolicy.setHorizontalStretch(0);
265 sizePolicy.setVerticalStretch(scrollarea->sizePolicy().verticalStretch());
266 sizePolicy.setHeightForWidth(scrollarea->sizePolicy().hasHeightForWidth());
267 scrollarea->setSizePolicy(sizePolicy);
268
269 collWidget->setContentsMargins(0,0,0,0);
270 if (!collWidget->children().isEmpty()&&collWidget->children().at(0)->isWidgetType()) {
271 static_cast<QWidget*>(collWidget->children().at(0))->setContentsMargins(0,0,0,0);
272 }
273 scrollarea->setContentsMargins(0,0,0,0);
274
275 scrollarea->setWidgetResizable(true);
276 scrollarea->setFrameShape(QFrame::NoFrame);
277 scrollarea->setFrameShadow(QFrame::Plain);
278 collWidget->setParent(scrollarea);
279 scrollarea->setWidget(collWidget);
280 scrollarea->viewport()->setContentsMargins(0,0,0,0);
281 scrollarea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
282 collWidget->setObjectName(objectName()+"_CollWidget");
283 scrollarea->setObjectName(objectName()+"_CollWidgetScrollArea");
284 m_d->collWidget = collWidget;
285 connect(collWidget,SIGNAL(visibleContentsChanged()),this,SLOT(collWidgetContentChanged()));
286}
287
288
289//____________________________________________________________________
290QButtonGroup * VP1Controller::defineRadioButtonGroup( QRadioButton * rb0, QRadioButton * rb1,QRadioButton * rb2,
291 QRadioButton * rb3,QRadioButton * rb4,QRadioButton * rb5,
292 QRadioButton * rb6,QRadioButton * rb7,QRadioButton * rb8,
293 QRadioButton * rb9 )
294{
295 QList<QRadioButton *> l;
296 l << rb0 << rb1 << rb2 << rb3 << rb4 << rb5 << rb6 << rb7 << rb8 << rb9;
297 l.removeAll(0);
298 return defineRadioButtonGroup(l);
299}
300
301//____________________________________________________________________
302QButtonGroup * VP1Controller::defineRadioButtonGroup( const QList<QRadioButton *>& l )
303{
304 QRadioButton * rb_checked(0);
305 for (QRadioButton *rb : l) {
306 if (rb->isChecked()) {
307 rb_checked = rb;
308 break;
309 }
310 }
311 QButtonGroup * radiogroup = new QButtonGroup(this);
312 for (QRadioButton *rb : l)
313 radiogroup->addButton(rb);
314 if (rb_checked)
315 rb_checked->setChecked(true);
316 return radiogroup;
317}
318
319//____________________________________________________________________
320const char * VP1Controller::addUpdateSlot(const char * slot)
321{
322 messageVerbose("Adding update slot: "+QString(slot));
323 connect(this,SIGNAL(dummyUpdateTrigger()),this,slot);
324 m_d->lastUpdateSlot = slot;
325 return slot;
326}
327
328//____________________________________________________________________
329void VP1Controller::connectToLastUpdateSlot(QObject* sender,const char * signal)
330{
331 connect(sender,signal,this,m_d->lastUpdateSlot);
332}
333
334//____________________________________________________________________
336{
337 connectToLastUpdateSlot(cb,SIGNAL(toggled(bool)));
338}
339
340//____________________________________________________________________
342{
343 connectToLastUpdateSlot(cb,SIGNAL(currentIndexChanged(int)));
344}
345
346//____________________________________________________________________
348{
349 connectToLastUpdateSlot(gb,SIGNAL(toggled(bool)));
350}
351
352//____________________________________________________________________
354{
355 connectToLastUpdateSlot(sb,SIGNAL(valueChanged(int)));
356}
357
358//____________________________________________________________________
360{
361 connectToLastUpdateSlot(dsb,SIGNAL(valueChanged(double)));
362}
363
364//____________________________________________________________________
366{
367 connectToLastUpdateSlot(rb,SIGNAL(toggled(bool)));
368}
369
370//____________________________________________________________________
372{
373 connectToLastUpdateSlot(bg,SIGNAL(buttonClicked(int)));
374}
375
376//____________________________________________________________________
378{
379 connectToLastUpdateSlot(s,SIGNAL(valueChanged(int)));
380}
381
382//____________________________________________________________________
384{
385 connectToLastUpdateSlot(csb,SIGNAL(colorChanged(const QColor&)));
386}
387
388//____________________________________________________________________
389void VP1Controller::restoreSettings(const QByteArray& ba)
390{
391 messageDebug("VP1Controller::restoreSettings()");
392
395
396 //warn unrestored:
397 if (m_d->collWidget)
398 s.ignoreWidget(m_d->collWidget);
399 s.warnUnrestored(static_cast<QWidget*>(this));
400 for (Imp::DialogInfo* di : m_d->dialogs)
401 s.warnUnrestored(di->dialogWidget.get());
402
403 QTimer::singleShot(0, this, SLOT(testForChanges()));
404}
405
406//____________________________________________________________________
408{
409 messageDebug("VP1Controller::saveSettings()");
410
412
413 messageDebug("calling actualSaveSettings()...");
415
416 //Warn unsaved:
417 if (m_d->collWidget)
418 s.ignoreWidget(m_d->collWidget);
419
420 s.warnUnsaved(static_cast<const QWidget*>(this));
421 for (Imp::DialogInfo* di : m_d->dialogs)
422 s.warnUnsaved(di->dialogWidget.get());
423
424 return s.result();
425
426}
427
428//____________________________________________________________________
430{
431 if (!m_d->fallBackMaterial) {
432 m_d->fallBackMaterial = new SoMaterial;
433 m_d->fallBackMaterial->ref();
434 }
435 return m_d->fallBackMaterial;
436}
437
438//____________________________________________________________________
440{
441 if (!mb) {
442 message("ERROR: Null material button pointer");
443 return fallBackMaterial();
444 }
445 QList<SoMaterial*> mats = mb->handledMaterials();
446 if (mats.count()!=1) {
447 message("ERROR: No material in button "+mb->objectName());
448 return fallBackMaterial();
449 }
450 return mats.at(0);
451
452
453}
static Double_t a
const double width
DialogInfo(QPushButton *lb, std::unique_ptr< QWidget > dw, QAbstractButton *ec)
std::unique_ptr< QWidget > dialogWidget
QList< DialogInfo * > dialogs
const char * lastUpdateSlot
SoMaterial * fallBackMaterial
VP1CollectionWidget * collWidget
virtual void actualSaveSettings(VP1Serialise &) const =0
QByteArray saveSettings() const
virtual ~VP1Controller()
void restoreSettings(const QByteArray &)
void dummyUpdateTrigger()
virtual void actualRestoreSettings(VP1Deserialise &)=0
void initDialog(T &theUI, QPushButton *launchbutton, QAbstractButton *enabledButton=0)
void toggleDialogState(QObject *widget=0)
static QString toString(const T &par)
SoMaterial * getMaterial(VP1MaterialButton *) const
void connectToLastUpdateSlot(QObject *sender, const char *signal)
void setupCollWidgetInScrollArea(QScrollArea *scrollarea, VP1CollectionWidget *collWidget)
const char * addUpdateSlot(const char *slot)
virtual int currentSettingsVersion() const =0
SoMaterial * fallBackMaterial() const
void collWidgetContentChanged()
QButtonGroup * defineRadioButtonGroup(QRadioButton *rb0, QRadioButton *rb1, QRadioButton *rb2=0, QRadioButton *rb3=0, QRadioButton *rb4=0, QRadioButton *rb5=0, QRadioButton *rb6=0, QRadioButton *rb7=0, QRadioButton *rb8=0, QRadioButton *rb9=0)
static VP1CustomTourEditor * m_customTourEditor
void testForChanges()
VP1Controller(IVP1System *sys, const QString &classname)
void enabledButtonStateChanged()
VP1HelperClassBase(IVP1System *sys=0, QString helpername="")
void messageVerbose(const QString &) const
void message(const QString &) const
IVP1System * systemBase() const
void messageDebug(const QString &) const
int lb
Definition globals.cxx:23
int r
Definition globals.cxx:22
STL namespace.