ATLAS Offline Software
Loading...
Searching...
No Matches
IVP13DSystem.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
6// //
7// Implementation of class IVP13DSystem //
8// //
9// Author: Thomas Kittelmann <Thomas.Kittelmann@cern.ch> //
10// //
11// Initial version: April 2007 //
12// //
14
17#include "VP1Base/VP1Msg.h"
18
19#include <Inventor/nodes/SoCamera.h>
20#include <Inventor/Qt/viewers/SoQtViewer.h>
21
22#include <QTimer>
23
24#include <iostream>
25#include <map>
26
27//* Always use SoCooperativeSelections
28//* A selection node should only appear in the subtree of just one system
29
30//___________________________________________________________________________________________________________
32public:
33 // List of selection callbacks.
34 std::vector<SoSelectionPathCB *> _callbacks;
35 //camera lists:
36 std::set<SoCamera*> staticcameras;
37 std::set<SoQtViewer*> viewers;
38
39 //(De)selection callbacks:
40 static void start_changeselection(void *userdata, SoSelection *sel);
41 static void finished_changeselection(void *userdata, SoSelection *sel);
42 static void made_selection( void * userdata, SoPath * path );
43 static void made_deselection( void * userdata, SoPath * path );
44 static void clickedoutside(void *userdata, SoCooperativeSelection *sel);
45
46 static std::map<SoCooperativeSelection*,IVP13DSystem*> selection2system;
47 //We add the selection pointers as userdata, so selection2sys is
48 //used to get the system pointer(s) in the callback functions.
49
50 QSet<SoCooperativeSelection *> selectionsWithDisabledNotifications;
51
52 std::map<SoCooperativeSelection*,SoPathList> selection2lastpathlist;
54};
55
56std::map<SoCooperativeSelection*,IVP13DSystem*> IVP13DSystem::Imp::selection2system;
57
58// Methods invoked upon selection / deselection (to be reimplemented in derived classes).
61void IVP13DSystem::userChangedSelection(SoCooperativeSelection*, const QSet<SoNode*>&, QSet<SoPath*>) {}
63
64//___________________________________________________________________________________________________________
66{
67 if (!selection) {
68 std::cout<<"IVP13DSystem::Imp::clickedoutside Error: Got null selection pointer!"<<std::endl;
69 return;
70 }
71 IVP13DSystem * system = dynamic_cast<IVP13DSystem *>(static_cast<IVP1System * >(userdata));
72 if (!system) {
73 std::cout<<"IVP13DSystem::Imp::clickedoutside Error: Could not find system pointer!"<<std::endl;
74 return;
75 }
77 return;
78 if (system->m_d->clickedoutsideScheduled)
79 return;
80 system->m_d->clickedoutsideScheduled = true;
81 QTimer::singleShot(0, system, SLOT(activateClickedOutside()));
82}
83
84//___________________________________________________________________________________________________________
86{
87 if (!m_d->clickedoutsideScheduled)
88 return;
89 m_d->clickedoutsideScheduled = false;
91}
92
93//___________________________________________________________________________________________________________
94void IVP13DSystem::Imp::start_changeselection(void * userdata, SoSelection *sel)
95{
97 if (!selection) {
98 std::cout<<"IVP13DSystem::Imp::start_changeselection Error: Could not find selection pointer!"<<std::endl;
99 return;
100 }
101
102 if (selection->policy.getValue()==SoSelection::SINGLE)
103 return;
104
105 IVP13DSystem * system = static_cast<IVP13DSystem *>(userdata);
106 if (!system) {
107 std::cout<<"IVP13DSystem::Imp::start_changeselection Error: Could not find system pointer!"<<std::endl;
108 return;
109 }
110
112 return;
113
114 system->m_d->selection2lastpathlist[selection] = *(selection->getList());
115
116 //redraw and emission of itemFromSystemSelected() take place in finished_changeselection!
117
118}
119
120//___________________________________________________________________________________________________________
121void IVP13DSystem::Imp::finished_changeselection(void *userdata, SoSelection *sel)
122{
124 if (!selection) {
125 std::cout<<"IVP13DSystem::Imp::finished_changeselection Error: Could not find selection pointer!"<<std::endl;
126 return;
127 }
128
129 IVP13DSystem * system = static_cast<IVP13DSystem *>(userdata);
130 if (!system) {
131 std::cout<<"IVP13DSystem::Imp::finished_changeselection Error: Could not find system pointer!"<<std::endl;
132 return;
133 }
134
135 selection->touch(); // to redraw
136
137 if (selection->policy.getValue()==SoSelection::SINGLE)
138 return;
139
140 //Only take action when selection actually changed between start and finish:
141 if (system->m_d->selection2lastpathlist.find(selection)==system->m_d->selection2lastpathlist.end()) {
142 std::cout<<"IVP13DSystem::Imp::finished_changeselection Error: Could not find last selection path list!"<<std::endl;
143 return;
144 }
145
146 int nlastselection = system->m_d->selection2lastpathlist[selection].getLength();
147 bool changed = false;
148 if (nlastselection!=selection->getList()->getLength()) {
149 changed = true;
150 } else {
151 for (int i = 0; i < selection->getList()->getLength(); ++i) {
152 if (system->m_d->selection2lastpathlist[selection].get(i)!=selection->getList()->get(i)) {
153 changed = true;
154 break;
155 }
156 }
157 }
158 if (!changed) {
159 system->m_d->selection2lastpathlist.erase(system->m_d->selection2lastpathlist.find(selection));
160 return;
161 }
162
163 //To avoid having different systems emit itemFromSystemSelected due
164 //to one user interaction, we only emit here if the action resulted
165 //in an increase in the number of selected objects:
166 if (selection->getList()->getLength()>nlastselection) {
167 system->itemFromSystemSelected();//Emit this signal
168 }
169
171 return;
172
173 QSet<SoNode*> selnodes;
174 QSet<SoPath*> selpaths;
175 int n = selection->getList()->getLength();
176 for (int i = 0; i < n; ++i) {
177 SoPath * path = (*(selection->getList()))[i];
178 if (!path)
179 continue;
180 SoFullPath *fPath = static_cast<SoFullPath *>(path);
181 SoNode * node = fPath->getTail();
182 if (!node)
183 continue;
184 selpaths << fPath;
185 selnodes << node;
186 }
187
188 system->userChangedSelection(selection,selnodes,selpaths);
189}
190
191//___________________________________________________________________________________________________________
192void IVP13DSystem::Imp::made_selection( void * userdata, SoPath * path )
193{
194 SoFullPath *fPath = static_cast<SoFullPath *>(path);
195 if (!fPath)
196 return;
197 SoNode *selectedNode = fPath->getTail();
198 if (!selectedNode)
199 return;
200 SoCooperativeSelection * selection = static_cast<SoCooperativeSelection*>(userdata);
201 if (!selection) {
202 std::cout<<"IVP13DSystem::Imp::made_selection Error: Could not find selection pointer!"<<std::endl;
203 return;
204 }
205 if (selection->policy.getValue()!=SoSelection::SINGLE)
206 return;
207
209 std::cout << "IVP13DSystem::Imp::made_selection Error: Could not find system pointer!"<<std::endl;
210 return;
211 }
212
214
215 system->itemFromSystemSelected();//Emit this signal
216
218 return;
219
220
221 system->userSelectedSingleNode(selection,selectedNode,fPath);
222
223 //redraw takes place in finished_changeselection!
224}
225
226//___________________________________________________________________________________________________________
227void IVP13DSystem::Imp::made_deselection( void * userdata, SoPath * path )
228{
229 SoFullPath *fPath = static_cast<SoFullPath *>(path);
230 if (!fPath)
231 return;
232 SoNode *deselectedNode = fPath->getTail();
233 if (!deselectedNode)
234 return;
235
236 SoCooperativeSelection * selection = static_cast<SoCooperativeSelection*>(userdata);
237 if (!selection) {
238 std::cout<<"IVP13DSystem::Imp::made_deselection Error: Could not find selection pointer!"<<std::endl;
239 return;
240 }
241 if (selection->policy.getValue()!=SoSelection::SINGLE)
242 return;
243
245 std::cout << "IVP13DSystem::Imp::made_deselection Error: Could not find system pointer!"<<std::endl;
246 return;
247 }
248
251 return;
252
253 system->userDeselectedSingleNode(selection,deselectedNode,fPath);
254}
255
256//___________________________________________________________________________________________________________
258{
259 if (!selection) {
260 message("registerSelectionNode Error: NULL selection pointer!");
261 return;
262 }
264 message("registerSelectionNode Error: Trying to register selection node more than once!");
265 return;
266 }
267
268 selection->addSelectionCallback( Imp::made_selection, selection );
269 selection->addDeselectionCallback( Imp::made_deselection, selection );
270 selection->addStartCallback( Imp::start_changeselection, this );
271 selection->addFinishCallback( Imp::finished_changeselection, this );
272 selection->addClickOutsideCallback( Imp::clickedoutside, this );
273
275 selection->ref();
276
277 messageVerbose("selection node registered");
278}
279
280//___________________________________________________________________________________________________________
282{
283 if (!selection) {
284 message("unregisterSelectionNode Error: NULL selection pointer!");
285 return;
286 }
288 message("registerSelectionNode Error: Trying to unregister unknown selection node!");
289 return;
290 }
291
292 selection->removeSelectionCallback( Imp::made_selection, selection );
293 selection->removeDeselectionCallback( Imp::made_deselection, selection );
294 selection->removeStartCallback( Imp::start_changeselection, this );
295 selection->removeFinishCallback( Imp::finished_changeselection, this );
296 selection->removeClickOutsideCallback( Imp::clickedoutside, this );
297
299 if (m_d->selectionsWithDisabledNotifications.contains(selection))
300 m_d->selectionsWithDisabledNotifications.remove(selection);
301 selection->unref();
302
303 messageVerbose("selection node unregistered");
304
305}
306
307
308
309//___________________________________________________________________________________________________________
311{
312 if (!selection) {
313 message("setUserSelectionNotificationsEnabled Error: NULL selection pointer!");
314 return;
315 }
317 message("setUserSelectionNotificationsEnabled Error: Called for selection which was never registered!");
318 return;
319 }
320 if (enabled != m_d->selectionsWithDisabledNotifications.contains(selection))
321 return;
322
323 if (enabled)
324 m_d->selectionsWithDisabledNotifications.remove(selection);
325 else
326 m_d->selectionsWithDisabledNotifications << selection;
327
328}
329
330//___________________________________________________________________________________________________________
332{
333 static std::map<SoCooperativeSelection*,IVP13DSystem*>::iterator it, itE = Imp::selection2system.end();
334 for (it = Imp::selection2system.begin(); it!=itE;++it) {
335 if (it->second!=this)
336 continue;
337 if (it->first!=exception_sel) {
338 if (it->first->policy.getValue()!=SoCooperativeSelection::SINGLE) {
339 Imp::start_changeselection(this, it->first);
340 it->first->deselectAll();
341 Imp::finished_changeselection(this, it->first);
342 } else {
343 if (it->first->getList()->getLength()==1) {
344 Imp::start_changeselection(this, it->first);
345 SoPath * path = static_cast<SoPath*>(it->first->getList()->get(0));
346 Imp::made_deselection(it->first,path);
347 it->first->deselectAll();
348 Imp::finished_changeselection(this, it->first);
349 }
350 }
351 }
352 }
353}
354
355//___________________________________________________________________________________________________________
356IVP13DSystem::IVP13DSystem( const QString & name, const QString & information, const QString & contact_info):
358{
360 m_d->clickedoutsideScheduled = false;
361}
362
363//___________________________________________________________________________________________________________
365{
366 messageDebug("~IVP13DSystem()");
367
368 m_d->selection2lastpathlist.clear();
369
370 //Unregister all nodes for this system:
371 std::set<SoCooperativeSelection*> sel2unregister;
372 std::map<SoCooperativeSelection*,IVP13DSystem*>::iterator it, itE = Imp::selection2system.end();
373 for (it = Imp::selection2system.begin();it!=itE;++it)
374 if (it->second == this)
375 sel2unregister.insert(it->first);
376 std::set<SoCooperativeSelection*>::iterator itSel, itSelE = sel2unregister.end();
377
378 for (itSel = sel2unregister.begin();itSel!=itSelE;++itSel) {
380 }
381
382 messageDebug("Unregistered all nodes. Unref all camera pointers...");
383
384 //Unref all camera pointers:
385 std::set<SoCamera*> ::iterator itCam, itCamE = m_d->staticcameras.end();
386 for (itCam = m_d->staticcameras.begin();itCam!=itCamE;++itCam)
387 (*itCam)->unref();
388
389 messageDebug("Unref all camera pointers: done.");
390
391 delete m_d; m_d=0;
392}
393
394//___________________________________________________________________________________________________________
395std::set<SoCamera*> IVP13DSystem::getCameraList()
396{
397 std::set<SoCamera*> cameralist = m_d->staticcameras;
398 std::set<SoQtViewer*>::const_iterator it, itE=m_d->viewers.end();
399 for (it=m_d->viewers.begin();it!=itE;++it) {
400 SoCamera*cam = (*it)->getCamera();
401 if (cam)
402 cameralist.insert(cam);
403 }
404
405 //m_d->camerasfromviewer
406 return cameralist;
407}
408
409//___________________________________________________________________________________________________________
410void IVP13DSystem::registerCamera(SoCamera *cam) {
411 if (!cam)
412 return;
413 m_d->staticcameras.insert(cam);
414 cam->ref();
415}
416
417//___________________________________________________________________________________________________________
418void IVP13DSystem::registerViewer(SoQtViewer *viewer)
419{
420 if (!viewer)
421 return;
422 m_d->viewers.insert(viewer);
423}
static void clickedoutside(void *userdata, SoCooperativeSelection *sel)
std::set< SoQtViewer * > viewers
std::vector< SoSelectionPathCB * > _callbacks
static void start_changeselection(void *userdata, SoSelection *sel)
QSet< SoCooperativeSelection * > selectionsWithDisabledNotifications
static void made_selection(void *userdata, SoPath *path)
std::set< SoCamera * > staticcameras
static void finished_changeselection(void *userdata, SoSelection *sel)
static std::map< SoCooperativeSelection *, IVP13DSystem * > selection2system
std::map< SoCooperativeSelection *, SoPathList > selection2lastpathlist
static void made_deselection(void *userdata, SoPath *path)
void activateClickedOutside()
void itemFromSystemSelected()
virtual void userClickedOnBgd()
virtual void userChangedSelection(SoCooperativeSelection *, const QSet< SoNode * > &, QSet< SoPath * >)
void unregisterSelectionNode(SoCooperativeSelection *)
void registerCamera(SoCamera *camera)
virtual void deselectAll(SoCooperativeSelection *exception_sel=0)
IVP13DSystem(const QString &name, const QString &information, const QString &contact_info)
virtual void userDeselectedSingleNode(SoCooperativeSelection *, SoNode *, SoPath *)
virtual void userSelectedSingleNode(SoCooperativeSelection *, SoNode *, SoPath *)
void setUserSelectionNotificationsEnabled(SoCooperativeSelection *sel, bool enabled)
void registerSelectionNode(SoCooperativeSelection *)
virtual ~IVP13DSystem()
CamList getCameraList()
void registerViewer(SoQtViewer *viewer)
void messageVerbose(const QString &) const
void messageDebug(const QString &) const
const QString & name() const
IVP1System(const QString &name, const QString &information, const QString &contact_info)
void message(const QString &) const
const QString & information() const
const QString & contact_info() const
Definition node.h:24
const std::string selection
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138