Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TEveSelection.cxx
Go to the documentation of this file.
1 // @(#)root/eve:$Id$
2 // Author: Matevz Tadel 2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TEveSelection.h"
13 #include "TEveProjectionBases.h"
14 #include "TEveCompound.h"
15 #include "TEveManager.h"
16 
17 #include "TClass.h"
18 
19 /** \class TEveSelection
20 \ingroup TEve
21 Make sure there is a SINGLE running TEveSelection for each
22 selection type (select/highlight).
23 */
24 
25 ClassImp(TEveSelection);
26 
27 ////////////////////////////////////////////////////////////////////////////////
28 /// Constructor.
29 
30 TEveSelection::TEveSelection(const char* n, const char* t) :
31  TEveElementList(n, t),
32  fPickToSelect (kPS_Projectable),
33  fActive (kTRUE),
34  fIsMaster (kTRUE)
35 {
36  fSelElement = &TEveElement::SelectElement;
37  fIncImpSelElement = &TEveElement::IncImpliedSelected;
38  fDecImpSelElement = &TEveElement::DecImpliedSelected;
39 }
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /// Set to 'highlight' mode.
43 
44 void TEveSelection::SetHighlightMode()
45 {
46  // Most importantly, this sets the pointers-to-function-members in
47  // TEveElement that are used to mark elements as (un)selected and
48  // implied-(un)selected.
49 
50  fPickToSelect = kPS_Projectable;
51  fIsMaster = kFALSE;
52 
53  fSelElement = &TEveElement::HighlightElement;
54  fIncImpSelElement = &TEveElement::IncImpliedHighlighted;
55  fDecImpSelElement = &TEveElement::DecImpliedHighlighted;
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Select element indicated by the entry and fill its
60 /// implied-selected set.
61 
62 void TEveSelection::DoElementSelect(TEveSelection::SelMap_i entry)
63 {
64  TEveElement *el = entry->first;
65  Set_t &set = entry->second;
66 
67  (el->*fSelElement)(kTRUE);
68  el->FillImpliedSelectedSet(set);
69  for (Set_i i = set.begin(); i != set.end(); ++i)
70  ((*i)->*fIncImpSelElement)();
71 }
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 /// Deselect element indicated by the entry and clear its
75 /// implied-selected set.
76 
77 void TEveSelection::DoElementUnselect(TEveSelection::SelMap_i entry)
78 {
79  TEveElement *el = entry->first;
80  Set_t &set = entry->second;
81 
82  for (Set_i i = set.begin(); i != set.end(); ++i)
83  ((*i)->*fDecImpSelElement)();
84  set.clear();
85  (el->*fSelElement)(kFALSE);
86 }
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 /// Pre-addition check. Deny addition if el is already selected.
90 /// Virtual from TEveElement.
91 
92 Bool_t TEveSelection::AcceptElement(TEveElement* el)
93 {
94  return el != this && fImpliedSelected.find(el) == fImpliedSelected.end() &&
95  el->IsA()->InheritsFrom(TEveSelection::Class()) == kFALSE;
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Add an element into selection, virtual from TEveElement.
100 
101 void TEveSelection::AddElement(TEveElement* el)
102 {
103  TEveElementList::AddElement(el);
104 
105  SelMap_i i = fImpliedSelected.insert(std::make_pair(el, Set_t())).first;
106  if (fActive)
107  {
108  DoElementSelect(i);
109  }
110  SelectionAdded(el);
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Add an element into selection, virtual from TEveElement.
115 /// Overriden here just so that a signal can be emitted.
116 
117 void TEveSelection::RemoveElement(TEveElement* el)
118 {
119  TEveElementList::RemoveElement(el);
120  SelectionRemoved(el);
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Virtual from TEveElement.
125 
126 void TEveSelection::RemoveElementLocal(TEveElement* el)
127 {
128  SelMap_i i = fImpliedSelected.find(el);
129 
130  if (i != fImpliedSelected.end())
131  {
132  if (fActive)
133  {
134  DoElementUnselect(i);
135  }
136  fImpliedSelected.erase(i);
137  }
138  else
139  {
140  Warning("TEveSelection::RemoveElementLocal", "element not found in map.");
141  }
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 /// Add an element into selection, virtual from TEveElement.
146 /// Overriden here just so that a signal can be emitted.
147 
148 void TEveSelection::RemoveElements()
149 {
150  TEveElementList::RemoveElements();
151  SelectionCleared();
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Virtual from TEveElement.
156 
157 void TEveSelection::RemoveElementsLocal()
158 {
159  if (fActive)
160  {
161  for (SelMap_i i = fImpliedSelected.begin(); i != fImpliedSelected.end(); ++i)
162  DoElementUnselect(i);
163  }
164  fImpliedSelected.clear();
165 }
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 /// Remove element from all implied-selected sets.
169 ///
170 /// This is called as part of the element destruction from
171 /// TEveManager::PreDeleteElement() and should not be called
172 /// directly.
173 
174 void TEveSelection::RemoveImpliedSelected(TEveElement* el)
175 {
176  for (SelMap_i i = fImpliedSelected.begin(); i != fImpliedSelected.end(); ++i)
177  {
178  Set_i j = i->second.find(el);
179  if (j != i->second.end())
180  i->second.erase(j);
181  }
182 }
183 
184 ////////////////////////////////////////////////////////////////////////////////
185 /// Recalculate implied-selected state for given selection entry.
186 /// Add new elements to implied-selected set and increase their
187 /// implied-selected count.
188 
189 void TEveSelection::RecheckImpliedSet(SelMap_i smi)
190 {
191  Set_t set;
192  smi->first->FillImpliedSelectedSet(set);
193  for (Set_i i = set.begin(); i != set.end(); ++i)
194  {
195  if (smi->second.find(*i) == smi->second.end())
196  {
197  smi->second.insert(*i);
198  ((*i)->*fIncImpSelElement)();
199  }
200  }
201 }
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 /// If given element is selected or implied-selected with this
205 /// selection and recheck implied-set for given selection entry.
206 
207 void TEveSelection::RecheckImpliedSetForElement(TEveElement* el)
208 {
209  // Top-level selected.
210  {
211  SelMap_i i = fImpliedSelected.find(el);
212  if (i != fImpliedSelected.end())
213  RecheckImpliedSet(i);
214  }
215 
216  // Implied selected, need to loop over all.
217  {
218  for (SelMap_i i = fImpliedSelected.begin(); i != fImpliedSelected.end(); ++ i)
219  {
220  if (i->second.find(el) != i->second.end())
221  RecheckImpliedSet(i);
222  }
223  }
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Emit SelectionAdded signal.
228 
229 void TEveSelection::SelectionAdded(TEveElement* el)
230 {
231  Emit("SelectionAdded(TEveElement*)", (Long_t)el);
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Emit SelectionRemoved signal.
236 
237 void TEveSelection::SelectionRemoved(TEveElement* el)
238 {
239  Emit("SelectionRemoved(TEveElement*)", (Long_t)el);
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Emit SelectionCleared signal.
244 
245 void TEveSelection::SelectionCleared()
246 {
247  Emit("SelectionCleared()");
248 }
249 
250 ////////////////////////////////////////////////////////////////////////////////
251 /// Called when secondary selection changed internally.
252 
253 void TEveSelection::SelectionRepeated(TEveElement* el)
254 {
255  Emit("SelectionRepeated(TEveElement*)", (Long_t)el);
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Activate this selection.
260 
261 void TEveSelection::ActivateSelection()
262 {
263  for (SelMap_i i = fImpliedSelected.begin(); i != fImpliedSelected.end(); ++i)
264  DoElementSelect(i);
265  fActive = kTRUE;
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Deactivate this selection.
270 
271 void TEveSelection::DeactivateSelection()
272 {
273  fActive = kFALSE;
274  for (SelMap_i i = fImpliedSelected.begin(); i != fImpliedSelected.end(); ++i)
275  DoElementUnselect(i);
276 }
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 /// Given element el that was picked or clicked by the user, find
280 /// the parent/ancestor element that should actually become the main
281 /// selected element according to current selection mode.
282 
283 TEveElement* TEveSelection::MapPickedToSelected(TEveElement* el)
284 {
285  if (el == 0)
286  return 0;
287 
288  if (el->ForwardSelection())
289  {
290  return el->ForwardSelection();
291  }
292 
293  switch (fPickToSelect)
294  {
295  case kPS_Ignore:
296  {
297  return 0;
298  }
299  case kPS_Element:
300  {
301  return el;
302  }
303  case kPS_Projectable:
304  {
305  TEveProjected* pted = dynamic_cast<TEveProjected*>(el);
306  if (pted)
307  return dynamic_cast<TEveElement*>(pted->GetProjectable());
308  return el;
309  }
310  case kPS_Compound:
311  {
312  TEveElement* cmpnd = el->GetCompound();
313  if (cmpnd)
314  return cmpnd;
315  return el;
316  }
317  case kPS_PableCompound:
318  {
319  TEveProjected* pted = dynamic_cast<TEveProjected*>(el);
320  if (pted)
321  el = dynamic_cast<TEveElement*>(pted->GetProjectable());
322  TEveElement* cmpnd = el->GetCompound();
323  if (cmpnd)
324  return cmpnd;
325  return el;
326  }
327  case kPS_Master:
328  {
329  TEveElement* mstr = el->GetMaster();
330  if (mstr)
331  return mstr;
332  return el;
333  }
334  }
335  return el;
336 }
337 
338 ////////////////////////////////////////////////////////////////////////////////
339 /// Called when user picks/clicks on an element. If multi is true,
340 /// the user is requiring a multiple selection (usually this is
341 /// associated with control-key being pressed at the time of pick
342 /// event).
343 
344 void TEveSelection::UserPickedElement(TEveElement* el, Bool_t multi)
345 {
346  TEveElement *edit_el = el ? el->ForwardEdit() : 0;
347 
348  el = MapPickedToSelected(el);
349 
350  if (el || HasChildren())
351  {
352  if (!multi)
353  RemoveElements();
354  if (el)
355  {
356  if (HasChild(el))
357  RemoveElement(el);
358  else
359  AddElement(el);
360  }
361  if (fIsMaster)
362  gEve->ElementSelect(edit_el ? edit_el : el);
363  gEve->Redraw3D();
364  }
365 }
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Called when secondary selection becomes empty.
369 
370 void TEveSelection::UserRePickedElement(TEveElement* el)
371 {
372  el = MapPickedToSelected(el);
373  if (el && HasChild(el))
374  {
375  SelectionRepeated(el);
376  gEve->Redraw3D();
377  }
378 }
379 
380 ////////////////////////////////////////////////////////////////////////////////
381 /// Called when secondary selection becomes empty.
382 
383 void TEveSelection::UserUnPickedElement(TEveElement* el)
384 {
385  el = MapPickedToSelected(el);
386  if (el)
387  {
388  RemoveElement(el);
389  gEve->Redraw3D();
390  }
391 }