Merge from EVE-dev.
[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
74 void RGTopFrame::Init()
75 {
76   gReve = this;
77
78   fCC          = 0;
79   fHistoCanvas = 0;
80   fSelector    = 0;
81   fBrowser     = 0;
82   fStatusBar   = 0;
83   fVSDFile     = "";
84
85   fMacroFolder = new TFolder("EVE", "Visualization macros");
86   gROOT->GetListOfBrowsables()->Add(fMacroFolder);
87
88   fClient->GetMimeTypeList()->AddType("root/tmacro", "Reve::RMacro",
89                                       "tmacro_s.xpm", "tmacro_t.xpm", "");
90
91   fEditor = 0;
92
93   fCurrentEvent   = 0;
94   fGlobalStore    = 0;
95
96   fRedrawDisabled = 0;
97   fResetCameras   = kFALSE;
98   fTimerActive    = kFALSE;
99   fRedrawTimer.Connect("Timeout()", "Reve::RGTopFrame", this, "DoRedraw3D()");
100 }
101
102
103 RGTopFrame::RGTopFrame(const TGWindow *p, UInt_t w, UInt_t h, LookType_e look)
104   : TGMainFrame(p, w, h)
105 {
106   Init();
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 }