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