Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TEveGedEditor.cxx
Go to the documentation of this file.
1 // @(#)root/eve:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 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 "TEveGedEditor.h"
13 #include "TEveElement.h"
14 #include "TEveManager.h"
15 
16 #include "TGButton.h"
17 #include "TGLabel.h"
18 #include "TGToolTip.h"
19 #include "TGDNDManager.h"
20 #include "TGMsgBox.h"
21 
22 #include "TClass.h"
23 #include "TContextMenu.h"
24 
25 /** \class TEveGedEditor
26 \ingroup TEve
27 Specialization of TGedEditor for proper update propagation to TEveManager.
28 */
29 
30 ClassImp(TEveGedEditor);
31 
32 Int_t TEveGedEditor::fgMaxExtraEditors = 10;
33 TList *TEveGedEditor::fgExtraEditors = new TList;
34 
35 TContextMenu *TEveGedEditor::fgContextMenu = 0;
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Constructor.
39 
40 TEveGedEditor::TEveGedEditor(TCanvas* canvas, UInt_t width, UInt_t height) :
41  TGedEditor(canvas, width, height),
42  fElement (0),
43  fObject (0)
44 {
45  // Remove old name-frame -- it is created in TGedEditor constructor
46  // so virtuals are not active yet.
47  fTabContainer->RemoveAll();
48  TGedFrame* nf = CreateNameFrame(fTabContainer, "Style");
49  nf->SetGedEditor(this);
50  nf->SetModelClass(0);
51  fTabContainer->AddFrame(nf, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2));
52 
53  // Fix priority for TAttMarkerEditor.
54  TClass* amClass = TClass::GetClass("TAttMarker");
55  TClass* edClass = TClass::GetClass("TAttMarkerEditor");
56  TGWindow *exroot = (TGWindow*) fClient->GetRoot();
57  fClient->SetRoot(fTabContainer);
58  SetFrameCreator(this);
59  TGedFrame *frame = reinterpret_cast<TGedFrame*>(edClass->New());
60  frame->SetModelClass(amClass);
61  {
62  Int_t off = edClass->GetDataMemberOffset("fPriority");
63  if (off == 0)
64  Warning("TEveGedEditor::TEveGedEditor", "Can't fix priority for TAttMarkerEditor.\n");
65  else
66  * (Int_t*) (((char*)frame) + off) = 1;
67  }
68  SetFrameCreator(0);
69  fClient->SetRoot(exroot);
70  fFrameMap.Add(amClass, frame);
71 }
72 
73 ////////////////////////////////////////////////////////////////////////////////
74 /// Destructor.
75 
76 TEveGedEditor::~TEveGedEditor()
77 {
78  if (gDebug > 0)
79  Info("TEveGedEditor::~TEveGedEditor", "%p going down.", this);
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Called from window-manger close button.
84 /// Unregister from global list and delete the window.
85 
86 void TEveGedEditor::CloseWindow()
87 {
88  if (gDebug > 0)
89  Info("TEveGedEditor::CloseWindow", "%p closing.", this);
90 
91  fgExtraEditors->Remove(this);
92 
93  DisplayElement(0);
94 
95  if (gDNDManager) {
96  if (gDNDManager->GetMainFrame() == this)
97  gDNDManager->SetMainFrame(0);
98  }
99  DeleteWindow();
100 }
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 /// Create name-frame for a tab.
104 
105 TGedFrame* TEveGedEditor::CreateNameFrame(const TGWindow* parent, const char* /*tab_name*/)
106 {
107  return new TEveGedNameFrame(parent);
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 /// Return eve-element if it is the model object.
112 
113 TEveElement* TEveGedEditor::GetEveElement() const
114 {
115  return (fModel == fObject) ? fElement : 0;
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Show a TEveElement in editor.
120 
121 void TEveGedEditor::DisplayElement(TEveElement* re)
122 {
123  static const TEveException eh("TEveGedEditor::DisplayElement ");
124 
125  fElement = re;
126  fObject = fElement ? fElement->GetEditorObject(eh) : 0;
127  TGedEditor::SetModel(fPad, fObject, kButton1Down, kTRUE);
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 /// Show a TObject in editor.
132 
133 void TEveGedEditor::DisplayObject(TObject* obj)
134 {
135  fElement = dynamic_cast<TEveElement*>(obj);
136  fObject = obj;
137  TGedEditor::SetModel(fPad, obj, kButton1Down, kTRUE);
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Set model object.
142 
143 void TEveGedEditor::SetModel(TVirtualPad* pad, TObject* obj, Int_t event, Bool_t force)
144 {
145  fElement = dynamic_cast<TEveElement*>(obj);
146  fObject = obj;
147  TGedEditor::SetModel(pad, obj, event, force);
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Virtual method from TGedEditor, called on every change.
152 /// Propagates changes to TEveElement and TEveManager.
153 
154 void TEveGedEditor::Update(TGedFrame* /*gframe*/)
155 {
156  if (fElement)
157  {
158  fElement->ElementChanged();
159  fElement->PropagateVizParamsToProjecteds();
160  }
161 
162  gEve->Redraw3D();
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 /// Static function to create a new extra editor.
167 
168 void TEveGedEditor::SpawnNewEditor(TObject* obj)
169 {
170  if (fgExtraEditors->GetSize() >= fgMaxExtraEditors)
171  {
172  new TGMsgBox(gClient->GetDefaultRoot(), gEve->GetMainWindow(),
173  "Clutter warning",
174  "Maximum number of extra editors reached.",
175  kMBIconStop, kMBOk);
176  }
177 
178  if (obj)
179  {
180  TEveGedEditor *ed = new TEveGedEditor();
181  ed->DisplayObject(obj);
182  ed->SetWindowName(Form("GED %s", obj->GetName()));
183 
184  fgExtraEditors->Add(ed);
185  }
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// Element was changed. Update editors showing it.
190 
191 void TEveGedEditor::ElementChanged(TEveElement* el)
192 {
193  TObject *eobj = el->GetEditorObject("TEveGedEditor::ElementChanged ");
194  TObjLink *lnk = fgExtraEditors->FirstLink();
195  while (lnk)
196  {
197  TEveGedEditor *ed = (TEveGedEditor*) lnk->GetObject();
198  if (ed->GetModel() == eobj)
199  ed->DisplayElement(el);
200  lnk = lnk->Next();
201  }
202 }
203 
204 ////////////////////////////////////////////////////////////////////////////////
205 /// Element is being deleted. Close editors showing it.
206 
207 void TEveGedEditor::ElementDeleted(TEveElement* el)
208 {
209  TObject *eobj = el->GetEditorObject("TEveGedEditor::ElementChanged ");
210  TObjLink *lnk = fgExtraEditors->FirstLink();
211  while (lnk)
212  {
213  TEveGedEditor *ed = (TEveGedEditor*) lnk->GetObject();
214  if (ed->GetModel() == eobj)
215  {
216  TObjLink *next = lnk->Next();
217  ed->DeleteWindow();
218  fgExtraEditors->Remove(lnk);
219  lnk = next;
220  }
221  else
222  {
223  lnk = lnk->Next();
224  }
225  }
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// Destroys all editors. Called from EVE termination.
230 
231 void TEveGedEditor::DestroyEditors()
232 {
233  while ( ! fgExtraEditors->IsEmpty())
234  {
235  TEveGedEditor *ed = (TEveGedEditor*) fgExtraEditors->First();
236  ed->DeleteWindow();
237  fgExtraEditors->RemoveFirst();
238  }
239 }
240 
241 ////////////////////////////////////////////////////////////////////////////////
242 /// Return context menu object shared among eve-ged-editors.
243 
244 TContextMenu* TEveGedEditor::GetContextMenu()
245 {
246  if (fgContextMenu == 0)
247  fgContextMenu = new TContextMenu("", "");
248  return fgContextMenu;
249 }
250 
251 /** \class TEveGedNameFrame
252 \ingroup TEve
253 Specialization of TGedNameFrame used in EVE.
254 It provides the ability to undock given editor for easier use.
255 Support for that is also provided from the TEveManager.
256 */
257 
258 ClassImp(TEveGedNameFrame);
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 /// Constructor.
262 
263 TEveGedNameFrame::TEveGedNameFrame(const TGWindow *p, Int_t width, Int_t height,
264  UInt_t options) :
265  TGedFrame(p, width, height, options),
266  fNCButton(0)
267 {
268  fNCButton = new TEveGedNameTextButton(this);
269  fNCButton->SetTextColor(0x0020a0);
270  AddFrame(fNCButton, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
271  fNCButton->Connect("Clicked()", "TEveGedNameFrame", this, "SpawnEditorClone()");
272 }
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Destructor.
276 
277 TEveGedNameFrame::~TEveGedNameFrame()
278 {
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// Set model object.
283 
284 void TEveGedNameFrame::SetModel(TObject* obj)
285 {
286  if (obj)
287  {
288  fNCButton->SetText(Form("%s [%s]", obj->GetName(), obj->ClassName()));
289  fNCButton->SetToolTipText(obj->GetTitle());
290  fNCButton->SetEnabled(kTRUE);
291  }
292  else
293  {
294  fNCButton->SetText("No object selected.");
295  fNCButton->SetToolTipText(0);
296  fNCButton->SetEnabled(kFALSE);
297  }
298 }
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 /// Create a new floating editor with current object.
302 
303 void TEveGedNameFrame::SpawnEditorClone()
304 {
305  TEveGedEditor::SpawnNewEditor(fGedEditor->GetModel());
306 }
307 
308 /** \class TEveGedNameTextButton
309 \ingroup TEve
310 Specialization of TGTextButton for EVE name frame.
311 It opens a context-menu on right-click.
312 */
313 
314 ClassImp(TEveGedNameTextButton);
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// Constructor.
318 
319 TEveGedNameTextButton::TEveGedNameTextButton(TEveGedNameFrame* p) :
320  TGTextButton(p, ""),
321  fFrame(p)
322 {
323  gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
324  kButtonPressMask | kButtonReleaseMask,
325  kNone, kNone);
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////
329 /// Destructor.
330 
331 TEveGedNameTextButton::~TEveGedNameTextButton()
332 {
333 }
334 
335 ////////////////////////////////////////////////////////////////////////////////
336 /// Handle button.
337 
338 Bool_t TEveGedNameTextButton::HandleButton(Event_t* event)
339 {
340  static const TEveException eh("TEveGedNameTextButton::HandleButton ");
341 
342  if (fTip) fTip->Hide();
343  if (fState == kButtonDisabled) return kTRUE;
344 
345  if (event->fCode == kButton3 && event->fType == kButtonPress)
346  {
347  TEveGedEditor *eged = (TEveGedEditor*) fFrame->GetGedEditor();
348  TEveElement *el = eged->GetEveElement();
349  if (el)
350  TEveGedEditor::GetContextMenu()->Popup(event->fXRoot, event->fYRoot,
351  el->GetObject(eh));
352  return 1;
353  }
354  else if (event->fCode == kButton1)
355  {
356  return TGTextButton::HandleButton(event);
357  }
358  else
359  {
360  return 0;
361  }
362 }