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