]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/RGBrowser.cxx
f53e06250919fa0b46bf10de7526a9433150a071
[u/mrichter/AliRoot.git] / EVE / Reve / RGBrowser.cxx
1 #include "RGBrowser.h"
2 #include "ReveManager.h"
3 #include "Reve.h"
4 #include "RGEditor.h"
5 #include "VSDSelector.h"
6 #include <Reve/PointSet.h>
7 #include <Reve/Track.h>
8
9 #include "TGFileBrowser.h"
10 #include <TBrowser.h>
11
12 #include <Riostream.h>
13
14 #include <TROOT.h>
15 #include <TStyle.h>
16 #include <TSystem.h>
17 #include <TRint.h>
18 #include <TVirtualX.h>
19 #include <TEnv.h>
20
21 #include <TApplication.h>
22 #include <TFile.h>
23 #include <TClassMenuItem.h>
24
25 #include <TColor.h>
26
27 #include <TGCanvas.h>
28 #include <TGSplitter.h>
29 #include <TGStatusBar.h>
30 #include <TGMenu.h>
31 #include <TGPicture.h>
32 #include <TGToolBar.h>
33 #include <TGLabel.h>
34 #include <TGXYLayout.h>
35 #include <TGNumberEntry.h>
36 #include <KeySymbols.h>
37
38 #include <TGLSAViewer.h>
39 #include <TGLSAFrame.h>
40 #include <TGTab.h>
41
42 #include <TGeoVolume.h>
43 #include <TGeoNode.h>
44
45 using namespace Reve;
46
47 //______________________________________________________________________
48 // RGLTEFrame
49 //
50 //
51
52 ClassImp(RGLTEFrame)
53
54 RGLTEFrame::RGLTEFrame(const Text_t* name, Int_t width, Int_t height) :
55   TGMainFrame(gClient->GetRoot(), width, height),
56   fCtxMenu     (0),
57   fNewSelected (0)
58 {
59   SetWindowName(name);
60   SetCleanup(kNoCleanup);
61
62   fFrame = new TGCompositeFrame(this, width, height, kVerticalFrame);
63
64   // List-tree
65   fLTFrame  = new TGCompositeFrame(fFrame, width, 3*height/7, kVerticalFrame);
66   fLTCanvas = new TGCanvas(fLTFrame, 10, 10, kSunkenFrame | kDoubleBorder);
67   fListTree = new TGListTree(fLTCanvas->GetViewPort(), 10, 10, kHorizontalFrame);
68   fListTree->SetCanvas(fLTCanvas);
69   fListTree->Associate(fFrame);
70   fListTree->SetColorMode(TGListTree::EColorMarkupMode(TGListTree::kColorUnderline | TGListTree::kColorBox));
71   fListTree->SetAutoCheckBoxPic(kFALSE);
72   fLTCanvas->SetContainer(fListTree);
73   fLTFrame->AddFrame(fLTCanvas, new TGLayoutHints
74                      (kLHintsNormal | kLHintsExpandX | kLHintsExpandY, 1, 1, 1, 1));
75   fFrame  ->AddFrame(fLTFrame, new TGLayoutHints
76                      (kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
77
78   // Splitter
79   fSplitter = new TGHSplitter(fFrame);
80   fFrame->AddFrame(fSplitter, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 1,1,2,2));
81
82   // Editor
83   fFrame->SetEditDisabled(kEditEnable);
84   fFrame->SetEditable();
85   fEditor = new RGEditor(0, width, 4*height/7);
86   fEditor->SetGlobal(kFALSE);
87   fEditor->ChangeOptions(fEditor->GetOptions() | kFixedHeight);
88   fFrame->SetEditable(kEditDisable);
89   fFrame->SetEditable(kFALSE);
90   {
91     TGFrameElement *el = 0;
92     TIter next(fFrame->GetList());
93     while ((el = (TGFrameElement *) next())) {
94       if (el->fFrame == fEditor)
95         if (el->fLayout) {
96           el->fLayout->SetLayoutHints(kLHintsTop | kLHintsExpandX);
97           el->fLayout->SetPadLeft(0); el->fLayout->SetPadRight(1);
98           el->fLayout->SetPadTop(2);  el->fLayout->SetPadBottom(1);
99           break;
100         }
101     }
102   }
103   fSplitter->SetFrame(fEditor, kFALSE);
104
105   AddFrame(fFrame, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
106
107   fCtxMenu = new TContextMenu("", "");
108
109   fListTree->Connect("Checked(TObject*,Bool_t)", "Reve::RGLTEFrame",
110                      this, "ItemChecked(TObject*, Bool_t)");
111   fListTree->Connect("Clicked(TGListTreeItem*, Int_t, Int_t, Int_t)", "Reve::RGLTEFrame",
112                      this, "ItemClicked(TGListTreeItem*, Int_t, Int_t, Int_t)");
113   fListTree->Connect("DoubleClicked(TGListTreeItem*, Int_t)", "Reve::RGLTEFrame",
114                      this, "ItemDblClicked(TGListTreeItem*, Int_t)");
115   fListTree->Connect("KeyPressed(TGListTreeItem*, ULong_t, ULong_t)", "Reve::RGLTEFrame",
116                      this, "ItemKeyPress(TGListTreeItem*, UInt_t, UInt_t)");
117
118   Layout();
119   MapSubwindows();
120   MapWindow();
121 }
122
123 RGLTEFrame::~RGLTEFrame()
124 {
125   delete fCtxMenu;
126
127   // Should un-register editor, all items and list-tree from gReve ... eventually.
128
129   delete fEditor;
130   delete fSplitter;
131   delete fListTree;
132   delete fLTCanvas;
133   delete fLTFrame;
134   delete fFrame;
135 }
136
137 /**************************************************************************/
138
139 void RGLTEFrame::ReconfToHorizontal()
140 {
141   UnmapWindow();
142
143   fFrame->ChangeOptions(kHorizontalFrame);
144   fLTFrame->ChangeOptions(kHorizontalFrame);
145   fListTree->ChangeOptions(kVerticalFrame);
146
147   TGFrameElement *el = 0;
148   TIter next(fFrame->GetList());
149   while ((el = (TGFrameElement *) next()))
150   {
151     if (el->fFrame == fSplitter)
152     {
153       delete fSplitter;
154       el->fFrame = fSplitter = new TGVSplitter(fFrame);
155       el->fLayout->SetLayoutHints(kLHintsLeft | kLHintsExpandY);
156       el->fLayout->SetPadLeft(2); el->fLayout->SetPadRight (2);
157       el->fLayout->SetPadTop (1); el->fLayout->SetPadBottom(1);
158     }
159     else if (el->fFrame == fEditor)
160     {
161       fEditor->ChangeOptions(fEditor->GetOptions() & (~kFixedHeight));
162       fEditor->ChangeOptions(fEditor->GetOptions() |   kFixedWidth);
163       el->fLayout->SetLayoutHints(kLHintsLeft | kLHintsExpandY);
164     }
165   }
166
167   fEditor->Resize(fEditor->GetWidth() / 2 - 1, fEditor->GetHeight());
168   fSplitter->SetFrame(fEditor, kFALSE);
169
170   Layout();
171   //fFrame->Layout();
172   //fLTFrame->Layout();
173   //fLTCanvas->Layout();
174   //fListTree->ClearViewPort();
175   MapSubwindows();
176   MapWindow();
177 }
178
179 void RGLTEFrame::ReconfToVertical()
180 {
181   UnmapWindow();
182
183   fFrame->ChangeOptions(kVerticalFrame);
184   fLTFrame->ChangeOptions(kVerticalFrame);
185   fListTree->ChangeOptions(kHorizontalFrame);
186
187   TGFrameElement *el = 0;
188   TIter next(fFrame->GetList());
189   while ((el = (TGFrameElement *) next()))
190   {
191     if (el->fFrame == fSplitter)
192     {
193       delete fSplitter;
194       el->fFrame = fSplitter = new TGHSplitter(fFrame);
195       el->fLayout->SetLayoutHints(kLHintsTop | kLHintsExpandX);
196       el->fLayout->SetPadLeft(2); el->fLayout->SetPadRight (2);
197       el->fLayout->SetPadTop (1); el->fLayout->SetPadBottom(1);
198     }
199     else if (el->fFrame == fEditor)
200     {
201       fEditor->ChangeOptions(fEditor->GetOptions() & (~kFixedWidth));
202       fEditor->ChangeOptions(fEditor->GetOptions() |   kFixedHeight);
203       el->fLayout->SetLayoutHints(kLHintsTop | kLHintsExpandX);
204     }
205   }
206
207   fEditor->Resize(fEditor->GetWidth(), fEditor->GetHeight() / 2 - 1);
208   fSplitter->SetFrame(fEditor, kFALSE);
209
210   Layout();
211   //fFrame->Layout();
212   //fLTFrame->Layout();
213   //fLTCanvas->Layout();
214   //fListTree->ClearViewPort();
215   MapSubwindows();
216   MapWindow();
217 }
218
219 /**************************************************************************/
220
221 void RGLTEFrame::ItemChecked(TObject* obj, Bool_t state)
222 {
223   // Item's user-data is blindly casted into TObject.
224   // We recast it blindly back into the render element.
225
226   RenderElement* rnrEl = (RenderElement*) obj;
227   gReve->RenderElementChecked(rnrEl, state);
228   gReve->Redraw3D();
229 }
230
231 void RGLTEFrame::ItemClicked(TGListTreeItem *item, Int_t btn, Int_t x, Int_t y)
232 {
233   //printf("ItemClicked item %s List %d btn=%d, x=%d, y=%d\n",
234   //  item->GetText(),fDisplayFrame->GetList()->GetEntries(), btn, x, y);
235
236   RenderElement* re = (RenderElement*)item->GetUserData();
237   if(re == 0) return;
238   TObject* obj = re->GetObject();
239
240   switch (btn)
241   {
242     case 1:
243       gReve->RenderElementSelect(re);
244       break;
245
246     case 2:
247       if (gReve->RenderElementPaste(re))
248         gReve->Redraw3D();
249       break;
250
251     case 3:
252       // If control pressed, show menu for render-element itself.
253       // event->fState & kKeyControlMask
254       // ??? how do i get current event?
255       if (obj) fCtxMenu->Popup(x, y, obj);
256       break;
257
258     default:
259       break;
260   }
261 }
262
263 void RGLTEFrame::ItemDblClicked(TGListTreeItem* item, Int_t btn)
264 {
265   if (btn != 1) return;
266
267   RenderElement* re = (RenderElement*) item->GetUserData();
268   if (re == 0) return;
269
270   re->ExpandIntoListTree(fListTree, item);
271
272   TObject* obj = re->GetObject();
273   if (obj)
274   {
275     // Browse geonodes.
276     if (obj->IsA()->InheritsFrom(TGeoNode::Class()))
277     {
278       TGeoNode* n = dynamic_cast<TGeoNode*>(obj);
279       if (item->GetFirstChild() == 0 && n->GetNdaughters())
280       {
281         fListTree->DeleteChildren(item);
282         for (Int_t i=0; i< n->GetNdaughters(); i++)
283         {
284           TString title;
285           title.Form("%d : %s[%d]", i,
286                      n->GetDaughter(i)->GetVolume()->GetName(),
287                      n->GetDaughter(i)->GetNdaughters());
288
289           TGListTreeItem* child = fListTree->AddItem( item, title.Data());
290           child->SetUserData(n->GetDaughter(i));
291         }
292       }
293     }
294   }
295 }
296
297 void RGLTEFrame::ItemKeyPress(TGListTreeItem *entry, UInt_t keysym, UInt_t /*mask*/)
298 {
299   static const Exc_t eH("RGLTEFrame::ItemKeyPress ");
300
301   // replace entry with selected!
302   entry = fListTree->GetSelected();
303   if (entry == 0) return;
304
305   if (keysym == kKey_Delete)
306   {
307     RenderElement* rnr_el = dynamic_cast<RenderElement*>
308       ((RenderElement*) entry->GetUserData());
309     if (rnr_el == 0)
310       return;
311
312     if (entry->GetParent())
313     {
314       if (rnr_el->GetDenyDestroy() > 0 && rnr_el->GetNItems() == 1)
315         throw(eH + "DestroyDenied set for this item.");
316
317       RenderElement* parent_re = dynamic_cast<RenderElement*>
318         ((RenderElement*) entry->GetParent()->GetUserData());
319
320       if (parent_re)
321       {
322         ResetSelectedTimer(entry);
323         gReve->RemoveRenderElement(rnr_el, parent_re);
324         gReve->Redraw3D();
325       }
326     }
327     else
328     {
329       if (rnr_el->GetDenyDestroy() > 0)
330         throw(eH + "DestroyDenied set for this top-level item.");
331       ResetSelectedTimer(entry);
332       gReve->RemoveFromListTree(rnr_el, fListTree, entry);
333       gReve->Redraw3D();
334     }
335   }
336 }
337
338 void RGLTEFrame::ResetSelectedTimer(TGListTreeItem* lti)
339 {
340   fNewSelected = lti->GetPrevSibling();
341   if (! fNewSelected) {
342     fNewSelected = lti->GetNextSibling();
343     if (! fNewSelected)
344       fNewSelected = lti->GetParent();
345   }
346
347   TTimer::SingleShot(0, IsA()->GetName(), this, "ResetSelected()");
348 }
349
350 void RGLTEFrame::ResetSelected()
351 {
352   fListTree->HighlightItem(fNewSelected);
353   fListTree->SetSelected(fNewSelected);
354   fNewSelected = 0;
355 }
356
357
358 /**************************************************************************/
359 /**************************************************************************/
360
361 //______________________________________________________________________
362 // RGBrowser
363 //
364 //
365
366 ClassImp(RGBrowser)
367
368 void RGBrowser::SetupCintExport(TClass* cl)
369 {
370   TList* l = cl->GetMenuList();
371   TClassMenuItem* n = new TClassMenuItem(TClassMenuItem::kPopupUserFunction, cl,
372                                          "Export to CINT", "ExportToCINT", this, "const char*,TObject*", 1);
373
374   l->AddFirst(n);
375 }
376
377 void RGBrowser::CalculateReparentXY(TGObject* parent, Int_t& x, Int_t& y)
378 {
379   UInt_t   w, h;
380   Window_t childdum;
381   gVirtualX->GetWindowSize(parent->GetId(), x, y, w, h);
382   gVirtualX->TranslateCoordinates(parent->GetId(),
383                                   gClient->GetDefaultRoot()->GetId(),
384                                   0, 0, x, y, childdum);
385 }
386
387 /**************************************************************************/
388
389 namespace
390 {
391 enum ReveMenu_e {
392   kNewViewer,  kNewScene,  kNewProjector,
393   kNewBrowser, kNewCanvas, kNewCanvasExt, kNewTextEditor, kNewHtmlBrowser,
394   kVerticalBrowser
395 };
396 }
397
398 RGBrowser::RGBrowser(UInt_t w, UInt_t h) :
399   TGNewBrowser("Reve Main Window", w, h, kFALSE),
400   fFileBrowser (0)
401 {
402   // Construct Reve menu
403
404   fRevePopup = new TGPopupMenu(gClient->GetRoot());
405   fRevePopup->AddEntry("New &Viewer",      kNewViewer);
406   fRevePopup->AddEntry("New &Scene",       kNewScene);
407   fRevePopup->AddEntry("New &Projector",   kNewProjector);
408   fRevePopup->AddSeparator();
409   fRevePopup->AddEntry("New &Browser",     kNewBrowser);
410   fRevePopup->AddEntry("New &Canvas",      kNewCanvas);
411   fRevePopup->AddEntry("New Canvas Ext",   kNewCanvasExt);
412   fRevePopup->AddEntry("New Text Editor",  kNewTextEditor);
413   // fRevePopup->AddEntry("New HTML Browser", kNewHtmlBrowser);
414   fRevePopup->AddSeparator();
415   fRevePopup->AddEntry("Vertical browser", kVerticalBrowser);
416   fRevePopup->CheckEntry(kVerticalBrowser);
417
418   fRevePopup->Connect("Activated(Int_t)", "Reve::RGBrowser", 
419                      this, "ReveMenu(Int_t)"); 
420
421   fMenuBar->RemovePopup("Framework");
422   // ?? should disconnect / delete.
423   fMenuBar->AddPopup("&Reve", fRevePopup, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0));
424
425   fPreMenuFrame->ChangeOptions(fPreMenuFrame->GetOptions() | kRaisedFrame);
426   fTopMenuFrame->Layout();
427   fTopMenuFrame->MapSubwindows();
428 }
429
430 /**************************************************************************/
431
432 void RGBrowser::ReveMenu(Int_t id)
433 {
434   switch (id)
435   {
436     case kNewViewer:
437       gReve->SpawnNewViewer("Viewer Pepe");
438       break;
439
440     case kNewScene:
441       gReve->SpawnNewScene("Scena Mica");
442       break;
443
444     case kNewProjector: {
445       RenderElement* pr = (RenderElement*) (gROOT->GetClass("Reve::NLTProjector")->New());
446       pr->SetRnrElNameTitle("Projector", "User-created projector.");
447       gReve->AddToListTree(pr, kTRUE);
448       break;
449     }
450     case kNewBrowser:
451       gROOT->ProcessLineFast("new TBrowser");
452       break;
453
454     case kNewCanvas:
455       StartEmbedding(1);
456       gROOT->ProcessLineFast("new TCanvas");
457       StopEmbedding();
458       SetTabTitle("Canvas", 1);
459       break;
460
461     case kNewCanvasExt:
462       gROOT->ProcessLineFast("new TCanvas");
463       break;
464
465     case kNewTextEditor:
466       StartEmbedding(1);
467       gROOT->ProcessLineFast(Form("new TGTextEditor((const char *)0, (const TGWindow *)0x%lx)", gClient->GetRoot()));
468       StopEmbedding();
469       SetTabTitle("Editor", 1);
470       break;
471
472     case kNewHtmlBrowser:
473       gSystem->Load("libGuiHtml");
474       if (gSystem->Load("libRHtml") >= 0)
475       {
476         StartEmbedding(1);
477         gROOT->ProcessLine(Form("new TGHtmlBrowser(\"http://root.cern.ch/root/html/ClassIndex.html\", \
478                               (const TGWindow *)0x%lx)", gClient->GetRoot()));
479         StopEmbedding();
480         SetTabTitle("HTML", 1);
481       }
482       break;
483
484     case kVerticalBrowser:
485       if (fRevePopup->IsEntryChecked(kVerticalBrowser)) {
486         gReve->GetLTEFrame()->ReconfToHorizontal();
487         fRevePopup->UnCheckEntry(kVerticalBrowser);
488       } else {
489         gReve->GetLTEFrame()->ReconfToVertical();
490         fRevePopup->CheckEntry(kVerticalBrowser);
491       }
492       break;
493
494     default:
495       break;
496   }
497 }
498
499 /**************************************************************************/
500
501 void RGBrowser::InitPlugins()
502 {
503   // File browser plugin...
504   StartEmbedding(0);
505   //gROOT->ProcessLine(Form("new TGFileBrowser((const TGWindow *)0x%lx, 200, 500)", 
506   //                   gClient->GetRoot()));
507   {
508     TGFileBrowser *fb = MakeFileBrowser();
509     fb->BrowseObj(gROOT);
510     fb->AddFSDirectory("/");
511     fb->Show();
512
513     fFileBrowser = fb;
514   }
515   StopEmbedding();
516   SetTabTitle("Files", 0);
517
518   // Class browser plugin
519   /*
520     StartEmbedding(0);
521     gROOT->ProcessLine(Form("new TGClassBrowser((const TGWindow *)0x%lx, 200, 500)", 
522     gClient->GetRoot()));
523     StopEmbedding();
524     SetTabTitle("Classes", 0, 1);
525   */
526
527   // --- main frame
528
529   // Canvas plugin...
530   /* Now in menu
531   StartEmbedding(1);
532   gROOT->ProcessLineFast("new TCanvas");
533   StopEmbedding();
534   SetTabTitle("Canvas", 1);
535   */
536
537   // Editor plugin...
538   /* Now in menu
539   StartEmbedding(1);
540   gROOT->ProcessLineFast(Form("new TGTextEditor((const char *)0, (const TGWindow *)0x%lx)", 
541                           gClient->GetRoot()));
542   StopEmbedding();
543   SetTabTitle("Editor", 1);
544   */
545
546   // --- bottom area
547
548   // Command plugin...
549   StartEmbedding(2);
550   gROOT->ProcessLineFast(Form("new TGCommandPlugin((const TGWindow *)0x%lx, 700, 300)", 
551                           gClient->GetRoot()));
552   StopEmbedding();
553   SetTabTitle("Command", 2);
554
555   // --- Select first tab everywhere
556   SetTab(0, 0);
557   SetTab(1, 0);
558   SetTab(2, 0);
559 }