6723a437fe7fd05f3fbffe77e78d860c9fdce3f6
[u/mrichter/AliRoot.git] / EVE / Reve / RGTopFrame.cxx
1 #include "RGTopFrame.h"
2
3 #include "RGBrowser.h"
4 #include "RGEditor.h"
5
6 #include <Reve/EventBase.h>
7 #include "VSDSelector.h"
8
9 #include <TGMenu.h>
10 #include <TGTab.h>
11 #include <TGToolBar.h>
12 #include <TGLabel.h>
13 #include <TGTextEntry.h>
14 #include <TGSplitter.h>
15 #include <TRootEmbeddedCanvas.h>
16 #include <TGMimeTypes.h>
17
18 #include <TGLSAViewer.h>
19 #include <TH1F.h>
20 #include <TView.h>
21
22 #include <TROOT.h>
23 #include <TFile.h>
24 #include <TMacro.h>
25 #include <TFolder.h>
26 #include <TStyle.h>
27 #include <TPad.h>
28 #include <TCanvas.h>
29 #include <TSystem.h>
30 #include <TRint.h>
31 #include <TVirtualX.h>
32 #include <TPolyLine3D.h>
33 #include <TPolyMarker3D.h>
34 #include <TEnv.h>
35 #include <TStyle.h>
36 #include <KeySymbols.h>
37 #include "TVirtualGL.h"
38 #include "TPluginManager.h"
39
40 #include <iostream>
41
42 using namespace Reve;
43 using namespace Reve;
44
45 Reve::RGTopFrame* gReve = 0;
46
47 /**************************************************************************/
48
49 RGTopFrame::RGTopFrame(const TGWindow *p, UInt_t w, UInt_t h, LookType_e look) :
50   TGMainFrame(p, w, h),
51
52   fGLCanvas    (0),
53   fSelector    (0),
54   fBrowser     (0),
55   fStatusBar   (0),
56   fVSDFile     (""),
57
58   fMacroFolder(0),
59   fEditor (0),
60
61   fCurrentEvent   (0),
62   fGlobalStore    (0),
63
64   fRedrawDisabled (0),
65   fResetCameras   (kFALSE),
66   fTimerActive    (kFALSE),
67   fRedrawTimer    (),
68
69   fLook           (LT_Editor),
70   fGeometries     ()
71 {
72   gReve = this;
73   fRedrawTimer.Connect("Timeout()", "Reve::RGTopFrame", this, "DoRedraw3D()");
74   fMacroFolder = new TFolder("EVE", "Visualization macros");
75   gROOT->GetListOfBrowsables()->Add(fMacroFolder);
76
77   fClient->GetMimeTypeList()->AddType("root/tmacro", "Reve::RMacro",
78                                       "tmacro_s.xpm", "tmacro_t.xpm", "");
79
80   // Build GUI
81
82   TGLayoutHints *lay0 = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY | kLHintsExpandY | kLHintsExpandX);
83   TGLayoutHints *lay1 = new TGLayoutHints(kLHintsCenterX | kLHintsCenterY | kLHintsExpandY | kLHintsExpandX, 2, 0, 2, 2);
84   TGLayoutHints *lay2 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2);
85
86   TGCompositeFrame*  mainFrame = new TGCompositeFrame(this, w, h, kHorizontalFrame | kRaisedFrame);
87   TGVerticalFrame* fV2 = new TGVerticalFrame(mainFrame, GetWidth()-40, GetHeight()-40, kSunkenFrame);
88
89   mainFrame->AddFrame(fV2, lay1);
90
91   TGTab* mainTab = new TGTab(fV2, GetWidth(), GetHeight());  
92
93   // browser tab
94   TGCompositeFrame* tframe1 = mainTab->AddTab("Object Browser");
95   fBrowser = new RGBrowser(tframe1, w, h);
96   tframe1->AddFrame(fBrowser, lay2);
97
98   // tree selection tab
99   TGCompositeFrame* tframe2 = mainTab->AddTab("Tree Selections");  
100   fSelector = new VSDSelector(fBrowser->GetListTree(), tframe2);
101
102   // gl-canvas
103   Reve::PushPad();
104   TGCompositeFrame* tframe3 = mainTab->AddTab("GLCanvas");
105   TRootEmbeddedCanvas* ecanvas3 = new TRootEmbeddedCanvas("GLCanvas", tframe3, 580, 360);
106   tframe3->AddFrame(ecanvas3, lay2);
107   fGLCanvas = ecanvas3->GetCanvas();
108   fGLCanvas->SetEditable(kFALSE);
109   Reve::PopPad();
110
111   fV2->AddFrame(mainTab, lay0);
112   AddFrame(mainFrame, lay0);
113    
114   // Create status bar
115   Int_t parts[] = {45, 45, 10};
116   fStatusBar = new TGStatusBar(this, 50, 10, kHorizontalFrame);
117   fStatusBar->SetParts(parts, 3);
118   TGLayoutHints* lay6 = new TGLayoutHints(kLHintsBottom| kLHintsExpandX, 0, 0, 0, 0);
119   AddFrame(fStatusBar, lay6);
120   fStatusBar->SetText("GUI created", 0);
121
122   MapSubwindows();
123
124   /**************************************************************************/
125   /**************************************************************************/
126   
127   switch(look) {
128   case LT_Classic: {
129     fBrowser->SetupClassicLook(fEditor, fGLCanvas);
130     fGLCanvas->GetViewer3D("ogl");
131     break;
132   }
133
134   case LT_Editor: {
135     fBrowser->SetupEditorLook(fEditor, fGLCanvas);
136     fGLCanvas->GetViewer3D("ogl");
137     break;
138   }
139
140   case LT_GLViewer: {
141     fBrowser->SetupGLViewerLook(fEditor, fGLCanvas);
142     break;
143   }
144
145   default: {
146     printf("RGTopFrame unknown look-type, ignoring.\n");
147     break;
148   }
149   }
150
151   TGLViewer* glv = dynamic_cast<TGLViewer*>(fGLCanvas->GetViewer3D());
152   if(glv) {
153     glv->SetSmartRefresh(kTRUE);
154     glv->SetResetCamerasOnUpdate(kFALSE);
155     glv->SetResetCameraOnDoubleClick(kFALSE);
156   }
157
158   /**************************************************************************/
159   /**************************************************************************/
160
161   fGlobalStore = new RenderElementList("Geometry", "");
162   fGlobalStore->SetDenyDestroy(kTRUE);
163   TGListTreeItem* glti = fGlobalStore->AddIntoListTree(GetListTree(), (TGListTreeItem*)0);
164   GetListTree()->OpenItem(glti);
165   DrawRenderElement(fGlobalStore);
166
167   Resize(GetDefaultSize()); // this is used here to init layout algorithm
168   SetWindowName("Reve");
169   MapWindow();
170
171   fEditor->DisplayObject(0);
172
173   gSystem->ProcessEvents();
174 }
175
176 /**************************************************************************/
177
178 TGListTree* RGTopFrame::GetListTree() const
179 {
180   return fBrowser->GetListTree();
181 }
182
183 /**************************************************************************/
184 // Macro management
185 /**************************************************************************/
186
187 TMacro* RGTopFrame::GetMacro(const Text_t* name) const
188 {
189   return dynamic_cast<TMacro*>(fMacroFolder->FindObject(name));
190 }
191
192 /**************************************************************************/
193 // Editor
194 /**************************************************************************/
195
196 void RGTopFrame::EditRenderElement(RenderElement* rnr_element)
197 {
198   static const Exc_t eH("RGTopFrame::EditRenderElement ");
199
200   fEditor->DisplayRenderElement(rnr_element);
201 }
202
203 /**************************************************************************/
204 // 3D Pad management
205 /**************************************************************************/
206
207 void RGTopFrame::RegisterRedraw3D()
208 {
209   fRedrawTimer.Start(0, kTRUE);
210   fTimerActive = true;
211 }
212
213 void RGTopFrame::DoRedraw3D()
214 {
215   // printf("RGTopFrame::DoRedraw3D redraw triggered\n");
216   if (fResetCameras) {
217     fGLCanvas->GetViewer3D()->ResetCamerasAfterNextUpdate();
218     fResetCameras = kFALSE;
219   }
220
221   fGLCanvas->Modified();
222   fGLCanvas->Update();
223   fTimerActive = kFALSE;
224 }
225
226 /**************************************************************************/
227
228 int RGTopFrame::SpawnGuiAndRun(int argc, char **argv)
229 {
230   LookType_e revemode = LT_Editor;
231   Int_t w = 540;
232   Int_t h = 500;
233   if(argc >= 3 && (strcmp(argv[1], "-revemode")==0 || strcmp(argv[1], "-mode")==0)) {
234     LookType_e m = LookType_e(atoi(argv[2]));
235     if(m >= LT_Classic && m <= LT_GLViewer)
236       revemode = m;
237     printf("revemode = %d\n", revemode);
238     if(revemode == LT_GLViewer) {
239       w = 1024; h = 768;
240     }
241   }
242
243   TRint theApp("App", &argc, argv);
244
245   /* gReve = */ new RGTopFrame(gClient->GetRoot(), w, h, revemode);
246
247  run_loop:
248   try {
249     theApp.Run();
250   }
251   catch(std::string exc) {
252     gReve->GetStatusBar()->SetText(exc.c_str());
253     fprintf(stderr, "Exception: %s\n", exc.c_str());
254     goto run_loop;
255   }
256   return 0;
257 }
258
259 /**************************************************************************/
260 /**************************************************************************/
261
262 TGListTreeItem* RGTopFrame::AddEvent(EventBase* event)
263 {
264   fCurrentEvent = event;
265   fCurrentEvent->SetDenyDestroy(kTRUE);
266   TGListTreeItem* elti = event->AddIntoListTree(GetListTree(), (TGListTreeItem*)0);
267   GetListTree()->OpenItem(elti);
268   DrawRenderElement(event);
269   return elti;
270 }
271
272 TGListTreeItem* RGTopFrame::AddRenderElement(RenderElement* rnr_element)
273 {
274   return AddRenderElement(fCurrentEvent, rnr_element);
275 }
276
277 TGListTreeItem* RGTopFrame::AddRenderElement(RenderElement* parent,
278                                              RenderElement* rnr_element)
279 {
280   static const Exc_t eH("RGTopFrame::AddRenderElement ");
281
282   // Here could route rnr-element to several browsers/pads.
283
284   RenderElementListBase* rel = dynamic_cast<RenderElementListBase*>(parent);
285   if(rel)
286     rel->AddElement(rnr_element);
287
288   TGListTreeItem* newitem =
289     rnr_element->AddIntoListTree(GetListTree(), parent);
290
291   return newitem;
292 }
293
294 TGListTreeItem* RGTopFrame::AddGlobalRenderElement(RenderElement* rnr_element)
295 {
296   return AddGlobalRenderElement(fGlobalStore, rnr_element);
297 }
298
299 TGListTreeItem* RGTopFrame::AddGlobalRenderElement(RenderElement* parent,
300                                                    RenderElement* rnr_element)
301 {
302   static const Exc_t eH("RGTopFrame::AddGlobalRenderElement ");
303
304   // Here could route rnr-element to several browsers/pads.
305
306   RenderElementListBase* rel = dynamic_cast<RenderElementListBase*>(parent);
307   if(rel)
308     rel->AddElement(rnr_element);
309
310   TGListTreeItem* newitem =
311     rnr_element->AddIntoListTree(GetListTree(), parent);
312
313   return newitem;
314 }
315
316 /**************************************************************************/
317
318 void RGTopFrame::RemoveRenderElement(RenderElement* parent,
319                                      RenderElement* rnr_element)
320 {
321   rnr_element->RemoveFromListTree(GetListTree());
322
323   RenderElementListBase* rel = dynamic_cast<RenderElementListBase*>(parent);
324   if(rel)
325     rel->RemoveElement(rnr_element);
326 }
327
328 /**************************************************************************/
329
330 void RGTopFrame::DrawRenderElement(RenderElement* rnr_element, TVirtualPad* pad)
331 {
332   if(pad == 0) pad = fGLCanvas;
333
334   { Reve::PadHolder pHolder(false, pad);
335     if (pad == fGLCanvas) fGLCanvas->SetEditable(kTRUE);
336     rnr_element->GetObject()->Draw();
337     if (pad == fGLCanvas) fGLCanvas->SetEditable(kFALSE);
338   }
339   Redraw3D();
340 }
341
342 void RGTopFrame::UndrawRenderElement(RenderElement* rnr_element, TVirtualPad* pad)
343 {
344   if(pad == 0) pad = fGLCanvas;
345   { Reve::PadHolder pHolder(false, pad);
346     pad->GetListOfPrimitives()->Remove(rnr_element->GetObject());
347   }
348   Redraw3D();
349 }
350
351 /**************************************************************************/
352
353 void RGTopFrame::RenderElementChecked(TObject* obj, Bool_t state)
354 {
355   // Item's user-data is blindly casted into TObject.
356   // We recast it blindly back into the render element.
357
358   RenderElement* rnrEl = (RenderElement*) obj;
359   rnrEl->SetRnrElement(state);
360   Redraw3D();
361 }
362
363 /**************************************************************************/
364
365 void RGTopFrame::NotifyBrowser(TGListTreeItem* parent_lti)
366 {
367   TGListTree* l_tree = GetListTree();
368   if(parent_lti)
369     l_tree->OpenItem(parent_lti);
370   gClient->NeedRedraw(l_tree);
371 }
372
373 void RGTopFrame::NotifyBrowser(RenderElement* parent)
374 {
375   TGListTreeItem* parent_lti = parent ? parent->FindListTreeItem(GetListTree()) : 0;
376   NotifyBrowser(parent_lti);
377 }
378
379 /**************************************************************************/
380 // GeoManager registration
381 /**************************************************************************/
382
383 TGeoManager* RGTopFrame::GetGeometry(const TString& filename)
384 {
385   static const Exc_t eH("RGTopFrame::GetGeometry ");
386
387   TString exp_filename = filename;
388   gSystem->ExpandPathName(exp_filename);
389   printf("%s loading: '%s' -> '%s'.\n", eH.Data(),
390          filename.Data(), exp_filename.Data());
391
392   std::map<TString, TGeoManager*>::iterator g = fGeometries.find(filename);
393   if(g != fGeometries.end()) {
394     return g->second;
395   } else {
396     if(gSystem->AccessPathName(exp_filename, kReadPermission))
397       throw(eH + "file '" + exp_filename + "' not readable.");
398     gGeoManager = 0;
399     TGeoManager::Import(filename); 
400     if(gGeoManager == 0)
401       throw(eH + "GeoManager import failed.");
402     gGeoManager->GetTopVolume()->VisibleDaughters(1);
403
404     // Import colors exported by Gled, if they exist.
405     {
406       TFile f(exp_filename, "READ");
407       TObjArray* collist = (TObjArray*) f.Get("ColorList");
408       f.Close();
409       if(collist != 0) {
410         TSeqCollection* glist = gROOT->GetListOfColors();
411         glist->Clear();
412         glist->AddAll(collist);
413       }
414     }
415
416     fGeometries[filename] = gGeoManager;
417     return gGeoManager;
418   }
419 }