]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/alice-macros/SplitGLView.C
With Boris and Antonin:
[u/mrichter/AliRoot.git] / EVE / alice-macros / SplitGLView.C
1
2 #include "TApplication.h"
3 #include "TSystem.h"
4 #include "TGFrame.h"
5 #include "TGLayout.h"
6 #include "TGSplitter.h"
7 #include "TGLWidget.h"
8 #include "TEvePad.h"
9 #include "TGeoManager.h"
10 #include "TString.h"
11 #include "TGMenu.h"
12 #include "TGStatusBar.h"
13 #include "TGFileDialog.h"
14 #include "TGMsgBox.h"
15 #include "TGLPhysicalShape.h"
16 #include "TGLLogicalShape.h"
17 #include "HelpText.h"
18 #include "TClass.h"
19 #include "Riostream.h"
20 #include "TEnv.h"
21 #include "TGListTree.h"
22 #include "TOrdCollection.h"
23 #include "TArrayF.h"
24 #include "TGHtml.h"
25 #include "TPRegexp.h"
26
27 #include "TEveManager.h"
28 #include "TEveViewer.h"
29 #include "TEveBrowser.h"
30 #include "TEveProjectionManager.h"
31 #include "TEveGeoNode.h"
32 #include "TEveEventManager.h"
33 #include "TEveTrack.h"
34 #include "TEveSelection.h"
35
36 #include "TRootEmbeddedCanvas.h"
37 #include "TGSplitFrame.h"
38 #include "TGLEmbeddedViewer.h"
39 #include "TGShapedFrame.h"
40 #include "TGButton.h"
41 #include "TGTab.h"
42 #include "TEnv.h"
43
44 #include "TCanvas.h"
45 #include "TFormula.h"
46 #include "TF1.h"
47 #include "TH1F.h"
48
49 #ifdef WIN32
50 #include <TWin32SplashThread.h>
51 #endif
52
53 const char *filetypes[] = { 
54    "ROOT files",    "*.root",
55    "All files",     "*",
56    0,               0 
57 };
58
59 const char *rcfiletypes[] = { 
60    "All files",     "*",
61    0,               0 
62 };
63
64 ////////////////////////////////////////////////////////////////////////////////
65 class TGShapedToolTip : public TGShapedFrame {
66
67 private:
68    TGShapedToolTip(const TGShapedToolTip&); // Not implemented
69    TGShapedToolTip& operator=(const TGShapedToolTip&); // Not implemented
70
71 protected:
72    Int_t                 fTextX, fTextY, fTextH;
73    TString               fTextCol;
74
75    TRootEmbeddedCanvas  *fEc;       // embedded canvas for histogram
76    TH1                  *fHist;     // user histogram
77    TString               fText;     // info (as tool tip) text
78
79    virtual void          DoRedraw() {}
80
81 public:
82    TGShapedToolTip(const char *picname, Int_t cx=0, Int_t cy=0, Int_t cw=0, 
83                    Int_t ch=0, Int_t tx=0, Int_t ty=0, Int_t th=0, 
84                    const char *col="#ffffff");
85    virtual ~TGShapedToolTip();
86
87    virtual void   CloseWindow();
88    void           CreateCanvas(Int_t cx, Int_t cy, Int_t cw, Int_t ch);
89    void           CreateCanvas(Int_t cw, Int_t ch, TGLayoutHints *hints);
90    TH1           *GetHisto() const { return fHist; }
91    const char    *GetText() const { return fText.Data(); }
92    void           Refresh();
93    void           SetHisto(TH1 *hist);
94    void           SetText(const char *text);
95    void           SetTextColor(const char *col);
96    void           SetTextAttributes(Int_t tx, Int_t ty, Int_t th, const char *col=0);
97    void           Show(Int_t x, Int_t y, const char *text = 0, TH1 *hist = 0);
98
99    ClassDef(TGShapedToolTip, 0) // Shaped composite frame
100 };
101
102 ////////////////////////////////////////////////////////////////////////////////
103 class HtmlObjTable : public TObject {
104 public:                     // make them public for shorter code
105
106    TString   fName;
107    Int_t     fNValues;      // number of values
108    Int_t     fNFields;      // number of fields
109    TArrayF  *fValues;
110    TString  *fLabels;
111    Bool_t    fExpand;
112
113    TString   fHtml;         // HTML output code
114
115    void Build();
116    void BuildTitle();
117    void BuildLabels();
118    void BuildTable();
119
120 public:
121    HtmlObjTable(const char *name, Int_t nfields, Int_t nvals, Bool_t exp=kTRUE);
122    virtual ~HtmlObjTable();
123
124    void     SetLabel(Int_t col, const char *label) { fLabels[col] = label; }
125    void     SetValue(Int_t col, Int_t row, Float_t val) { fValues[col].SetAt(val, row); }
126    TString  Html() const { return fHtml; }
127
128    ClassDef(HtmlObjTable, 0);
129 };
130
131 ////////////////////////////////////////////////////////////////////////////////
132 class HtmlSummary {
133 public:                           // make them public for shorter code
134    Int_t           fNTables;
135    TOrdCollection *fObjTables;    // ->array of object tables
136    TString         fHtml;         // output HTML string
137    TString         fTitle;        // page title
138    TString         fHeader;       // HTML header
139    TString         fFooter;       // HTML footer
140
141    void     MakeHeader();
142    void     MakeFooter();
143
144 public:
145    HtmlSummary(const char *title);
146    virtual ~HtmlSummary();
147
148    HtmlObjTable  *AddTable(const char *name, Int_t nfields, Int_t nvals, 
149                            Bool_t exp=kTRUE, Option_t *opt="");
150    HtmlObjTable  *GetTable(Int_t at) const { return (HtmlObjTable *)fObjTables->At(at); }
151    void           Build();
152    void           Clear(Option_t *option="");
153    void           Reset(Option_t *option="");
154    TString        Html() const { return fHtml; }
155
156    ClassDef(HtmlSummary, 0);
157 };
158
159 ////////////////////////////////////////////////////////////////////////////////
160 class SplitGLView : public TGMainFrame {
161
162 public:
163    enum EMyCommands {
164       kFileOpen, kFileExit, kFileLoadConfig, kFileSaveConfig,
165       kHelpAbout, kGLPerspYOZ, kGLPerspXOZ, kGLPerspXOY, kGLXOY,
166       kGLXOZ, kGLZOY, kGLOrthoRotate, kGLOrthoDolly, kSceneUpdate, 
167       kSceneUpdateAll, kSummaryUpdate
168    };
169
170 private:
171    TEvePad               *fPad;           // pad used as geometry container
172    TGSplitFrame          *fSplitFrame;    // main (first) split frame
173    TGLEmbeddedViewer     *fViewer0;       // main GL viewer
174    TGLEmbeddedViewer     *fViewer1;       // first GL viewer
175    TGLEmbeddedViewer     *fViewer2;       // second GL viewer
176    TGLEmbeddedViewer     *fActViewer;     // actual (active) GL viewer
177    static HtmlSummary    *fgHtmlSummary;  // summary HTML table
178    static TGHtml         *fgHtml;
179    TGMenuBar             *fMenuBar;       // main menu bar
180    TGPopupMenu           *fMenuFile;      // 'File' popup menu
181    TGPopupMenu           *fMenuHelp;      // 'Help' popup menu
182    TGPopupMenu           *fMenuCamera;    // 'Camera' popup menu
183    TGPopupMenu           *fMenuScene;     // 'Scene' popup menu
184    TGStatusBar           *fStatusBar;     // status bar
185    TGShapedToolTip       *fShapedToolTip; // shaped tooltip
186    Bool_t                 fIsEmbedded;
187
188    TEveViewer            *fViewer[3];
189    TEveProjectionManager *fRPhiMgr;
190    TEveProjectionManager *fRhoZMgr;
191
192 public:
193    SplitGLView(const TGWindow *p=0, UInt_t w=800, UInt_t h=600, Bool_t embed=kFALSE);
194    virtual ~SplitGLView();
195
196    void           ItemClicked(TGListTreeItem *item, Int_t btn, Int_t x, Int_t y);
197    void           HandleMenu(Int_t id);
198    void           OnClicked(TObject *obj);
199    void           OnMouseIdle(TGLPhysicalShape *shape, UInt_t posx, UInt_t posy);
200    void           OnMouseOver(TGLPhysicalShape *shape);
201    void           OnViewerActivated();
202    void           OpenFile(const char *fname);
203    void           ToggleOrthoRotate();
204    void           ToggleOrthoDolly();
205    void           SwapToMainView();
206    void           LoadConfig(const char *fname);
207    void           SaveConfig(const char *fname);
208    static void    UpdateSummary();
209
210    TEveProjectionManager *GetRPhiMgr() const { return fRPhiMgr; }
211    TEveProjectionManager *GetRhoZMgr() const { return fRhoZMgr; }
212
213    ClassDef(SplitGLView, 0)
214 };
215
216 TEveProjectionManager *gRPhiMgr = 0;
217 TEveProjectionManager *gRhoZMgr = 0;
218
219 ClassImp(TGShapedToolTip)
220 ClassImp(HtmlObjTable)
221 ClassImp(HtmlSummary)
222 ClassImp(SplitGLView)
223
224 HtmlSummary *SplitGLView::fgHtmlSummary = 0;
225 TGHtml *SplitGLView::fgHtml = 0;
226
227 //______________________________________________________________________________
228 TGShapedToolTip::TGShapedToolTip(const char *pname, Int_t cx, Int_t cy, Int_t cw, 
229                              Int_t ch, Int_t tx, Int_t ty, Int_t th, 
230                              const char *col) : 
231    TGShapedFrame(pname, gClient->GetDefaultRoot(), 400, 300, kTempFrame | 
232                  kHorizontalFrame), fEc(0), fHist(0)
233 {
234    // Shaped window constructor
235
236    fTextX = tx; fTextY = ty; fTextH = th;
237    if (col)
238       fTextCol = col;
239    else
240       fTextCol = "0x000000";
241
242    // create the embedded canvas
243    if ((cx > 0) && (cy > 0) && (cw > 0) && (ch > 0)) {
244       Int_t lhRight  = fWidth-cx-cw;
245       Int_t lhBottom = fHeight-cy-ch;
246       fEc = new TRootEmbeddedCanvas("ec", this, cw, ch, 0);
247       AddFrame(fEc, new TGLayoutHints(kLHintsTop | kLHintsLeft, cx, 
248                                       lhRight, cy, lhBottom));
249    }
250    MapSubwindows();
251    Resize();
252    Resize(fBgnd->GetWidth(), fBgnd->GetHeight());
253 }
254
255 //______________________________________________________________________________
256 TGShapedToolTip::~TGShapedToolTip() 
257 {
258    // Destructor.
259
260    if (fHist)
261       delete fHist;
262    if (fEc)
263       delete fEc;
264 }
265
266 //______________________________________________________________________________
267 void TGShapedToolTip::CloseWindow() 
268 {
269    // Close shaped window.
270    
271    DeleteWindow();
272 }
273
274 //______________________________________________________________________________
275 void TGShapedToolTip::Refresh()
276 {
277    // Redraw the window with current attributes.
278
279    const char *str = fText.Data();
280    char *string = strdup(str);
281    Int_t nlines = 0, size = fTextH;
282    TString fp = gEnv->GetValue("Root.TTFontPath", "");
283    TString ar = fp + "/arial.ttf";
284    char *s = strtok((char *)string, "\n");
285    TImage *img = (TImage*)fImage->Clone("img");
286    img->DrawText(fTextX, fTextY+(nlines*size), s, size, fTextCol, ar);
287    while ((s = strtok(0, "\n"))) {
288       nlines++;
289       img->DrawText(fTextX, fTextY+(nlines*size), s, size, fTextCol, ar);
290    }
291    img->PaintImage(fId, 0, 0, 0, 0, 0, 0, "opaque");
292    free(string);
293    delete img;
294    gVirtualX->Update();
295 }
296
297 //______________________________________________________________________________
298 void TGShapedToolTip::CreateCanvas(Int_t cx, Int_t cy, Int_t cw, Int_t ch)
299 {
300
301    // create the embedded canvas
302    Int_t lhRight  = fWidth-cx-cw;
303    Int_t lhBottom = fHeight-cy-ch;
304    fEc = new TRootEmbeddedCanvas("ec", this, cw, ch, 0);
305    AddFrame(fEc, new TGLayoutHints(kLHintsTop | kLHintsLeft, cx, 
306                                    lhRight, cy, lhBottom));
307    MapSubwindows();
308    Resize();
309    Resize(fBgnd->GetWidth(), fBgnd->GetHeight());
310    if (IsMapped()) {
311       Refresh();
312    }
313 }
314
315 //______________________________________________________________________________
316 void TGShapedToolTip::CreateCanvas(Int_t cw, Int_t ch, TGLayoutHints *hints)
317 {
318    // Create the embedded canvas.
319
320    fEc = new TRootEmbeddedCanvas("ec", this, cw, ch, 0);
321    AddFrame(fEc, hints);
322    MapSubwindows();
323    Resize();
324    Resize(fBgnd->GetWidth(), fBgnd->GetHeight());
325    if (IsMapped()) {
326       Refresh();
327    }
328 }
329
330 //______________________________________________________________________________
331 void TGShapedToolTip::SetHisto(TH1 *hist)
332 {
333    // Set which histogram has to be displayed in the embedded canvas.
334
335    if (hist) {
336       if (fHist) {
337          delete fHist;
338          if (fEc)
339             fEc->GetCanvas()->Clear();
340       }
341       fHist = (TH1 *)hist->Clone();
342       if (fEc) {
343          fEc->GetCanvas()->SetBorderMode(0);
344          fEc->GetCanvas()->SetFillColor(10);
345          fEc->GetCanvas()->cd();
346          fHist->Draw();
347          fEc->GetCanvas()->Update();
348       }
349    }
350 }
351
352 //______________________________________________________________________________
353 void TGShapedToolTip::SetText(const char *text)
354 {
355    // Set which text has to be displayed.
356
357    if (text) {
358       fText = text;
359    }
360    if (IsMapped())
361       Refresh();
362 }
363
364 //______________________________________________________________________________
365 void TGShapedToolTip::SetTextColor(const char *col)
366 {
367    // Set text color.
368
369    fTextCol = col;
370    if (IsMapped())
371       Refresh();
372 }
373
374 //______________________________________________________________________________
375 void TGShapedToolTip::SetTextAttributes(Int_t tx, Int_t ty, Int_t th, 
376                                         const char *col)
377 {
378    // Set text attributes (position, size and color).
379
380    fTextX = tx; fTextY = ty; fTextH = th;
381    if (col)
382       fTextCol = col;
383    if (IsMapped())
384       Refresh();
385 }
386
387 //______________________________________________________________________________
388 void TGShapedToolTip::Show(Int_t x, Int_t y, const char *text, TH1 *hist)
389 {
390    // Show (popup) the shaped window at location x,y and possibly
391    // set the text and histogram to be displayed.
392
393    Move(x, y);
394    MapWindow();
395
396    if (text)
397       SetText(text);
398    if (hist)
399       SetHisto(hist);
400    // end of demo code -------------------------------------------
401    if (fHist) {
402       fEc->GetCanvas()->SetBorderMode(0);
403       fEc->GetCanvas()->SetFillColor(10);
404       fEc->GetCanvas()->cd();
405       fHist->Draw();
406       fEc->GetCanvas()->Update();
407    }
408    Refresh();
409 }
410
411 //______________________________________________________________________________
412 HtmlObjTable::HtmlObjTable(const char *name, Int_t nfields, Int_t nvals, Bool_t exp) : 
413    fName(name), fNValues(nvals), fNFields(nfields), fExpand(exp)
414 {
415    // Constructor.
416
417    fValues = new TArrayF[fNFields];
418    for (int i=0;i<fNFields;i++)
419       fValues[i].Set(nvals);
420    fLabels = new TString[fNFields];
421 }
422
423 //______________________________________________________________________________
424 HtmlObjTable::~HtmlObjTable()
425 {
426    // Destructor.
427
428    delete [] fValues;
429    delete [] fLabels;
430 }
431
432 //______________________________________________________________________________
433 void HtmlObjTable::Build()
434 {
435    // Build HTML code.
436
437    fHtml = "<table width=100% border=1 cellspacing=0 cellpadding=0 bgcolor=f0f0f0> ",
438
439    BuildTitle();
440    if (fExpand && (fNFields > 0) && (fNValues > 0)) {
441       BuildLabels();
442       BuildTable();
443    }
444
445    fHtml += "</table>";
446 }
447
448 //______________________________________________________________________________
449 void HtmlObjTable::BuildTitle()
450 {
451    // Build table title.
452    
453    fHtml += "<tr><td colspan=";
454    fHtml += Form("%d>", fNFields+1);
455    fHtml += "<table width=100% border=0 cellspacing=2 cellpadding=0 bgcolor=6e6ea0>";
456    fHtml += "<tr><td align=left>";
457    fHtml += "<font face=Verdana size=3 color=ffffff><b><i>";
458    fHtml += fName;
459    fHtml += "</i></b></font></td>";
460    fHtml += "<td>";
461    fHtml += "<td align=right> ";
462    fHtml += "<font face=Verdana size=3 color=ffffff><b><i>";
463    fHtml += Form("Size = %d", fNValues);
464    fHtml += "</i></b></font></td></tr>";
465    fHtml += "</table>";
466    fHtml += "</td></tr>";
467 }
468
469 //______________________________________________________________________________
470 void HtmlObjTable::BuildLabels()
471 {
472    // Build table labels.
473
474    Int_t i;
475    fHtml += "<tr bgcolor=c0c0ff>";
476    fHtml += "<th> </th>"; // for the check boxes
477    for (i=0;i<fNFields;i++) {
478       fHtml += "<th> ";
479       fHtml += fLabels[i];
480       fHtml += " </th>"; // for the check boxes
481    }
482    fHtml += "</tr>";
483 }
484
485 //______________________________________________________________________________
486 void HtmlObjTable::BuildTable()
487 {
488    // Build part of table with values.
489
490    for (int i = 0; i < fNValues; i++) {
491       if (i%2)
492          fHtml += "<tr bgcolor=e0e0ff>";
493       else
494          fHtml += "<tr bgcolor=ffffff>";
495       
496       TString name = fName;
497       name.ReplaceAll(" ", "_");
498       // checkboxes
499       fHtml += "<td bgcolor=d0d0ff align=\"center\">";
500       fHtml += "<input type=\"checkbox\" name=\"";
501       fHtml += name;
502       fHtml += Form("[%d]\">",i);
503       fHtml += "</td>";
504
505       for (int j = 0; j < fNFields; j++) {
506          fHtml += "<td width=";
507          fHtml += Form("%d%%", 100/fNFields);
508          fHtml += " align=\"center\"";
509          fHtml += ">";
510          fHtml += Form("%1.4f", fValues[j][i]);
511          fHtml += "</td>";
512       }
513       fHtml += "</tr> ";
514    }
515 }
516
517 //______________________________________________________________________________
518 HtmlSummary::HtmlSummary(const char *title) : fNTables(0), fTitle(title)
519 {
520    // Constructor.
521
522    fObjTables = new TOrdCollection();
523 }
524
525 //______________________________________________________________________________
526 HtmlSummary::~HtmlSummary()
527 {
528    // Destructor.
529
530    Reset();
531 }
532
533 //______________________________________________________________________________
534 HtmlObjTable *HtmlSummary::AddTable(const char *name, Int_t nfields, Int_t nvals,
535                                     Bool_t exp, Option_t *option)
536 {
537    // Add a new table in our list of tables.
538
539    TString opt = option;
540    opt.ToLower();
541    HtmlObjTable *table = new HtmlObjTable(name, nfields, nvals, exp);
542    fNTables++;
543    if (opt.Contains("first"))
544       fObjTables->AddFirst(table);
545    else
546       fObjTables->Add(table);
547    return table;
548 }
549
550 //______________________________________________________________________________
551 void HtmlSummary::Clear(Option_t *option)
552 {
553    // Clear the table list.
554
555    if (option && option[0] == 'D')
556       fObjTables->Delete(option);
557    else
558       fObjTables->Clear(option);
559    fNTables = 0;
560 }
561
562 //______________________________________________________________________________
563 void HtmlSummary::Reset(Option_t *)
564 {
565    // Reset (delete) the table list;
566
567    delete fObjTables; fObjTables = 0;
568    fNTables = 0;
569 }
570
571 //______________________________________________________________________________
572 void HtmlSummary::Build()
573 {
574    // Build the summary.
575
576    MakeHeader();
577    for (int i=0;i<fNTables;i++) {
578       GetTable(i)->Build();
579       fHtml += GetTable(i)->Html();
580    }
581    MakeFooter();
582 }
583
584 //______________________________________________________________________________
585 void HtmlSummary::MakeHeader()
586 {
587    // Make HTML header.
588
589    fHeader  = "<html><head><title>";
590    fHeader += fTitle;
591    fHeader += "</title></head><body>";
592    fHeader += "<center><h2><font color=#2222ee><i>";
593    fHeader += fTitle;
594    fHeader += "</i></font></h2></center>";
595    fHtml    = fHeader;
596 }
597
598 //______________________________________________________________________________
599 void HtmlSummary::MakeFooter()
600 {
601    // Make HTML footer.
602
603    fFooter  = "<br><p><br><center><strong><font size=2 color=#2222ee>";
604    fFooter += "Example of using Html widget to display tabular data";
605    fFooter += "<br>";
606    fFooter += "© 2007-2008 Bertrand Bellenot";
607    fFooter += "</font></strong></center></body></html>";  
608    fHtml   += fFooter;
609 }
610
611 //______________________________________________________________________________
612 SplitGLView::SplitGLView(const TGWindow *p, UInt_t w, UInt_t h, Bool_t embed) :
613    TGMainFrame(p, w, h), fActViewer(0), fShapedToolTip(0), fIsEmbedded(embed)
614 {
615    // Main frame constructor.
616
617    TGSplitFrame *frm;
618    TEveScene *s = 0;
619    TGHorizontalFrame *hfrm;
620    TGPictureButton *button;
621
622    // create the "file" popup menu
623    fMenuFile = new TGPopupMenu(gClient->GetRoot());
624    fMenuFile->AddEntry("&Open...", kFileOpen);
625    fMenuFile->AddSeparator();
626    fMenuFile->AddEntry( "&Update Summary", kSummaryUpdate);
627    fMenuFile->AddSeparator();
628    fMenuFile->AddEntry("&Load Config...", kFileLoadConfig);
629    fMenuFile->AddEntry("&Save Config...", kFileSaveConfig);
630    fMenuFile->AddSeparator();
631    fMenuFile->AddEntry("E&xit", kFileExit);
632
633    // create the "camera" popup menu
634    fMenuCamera = new TGPopupMenu(gClient->GetRoot());
635    fMenuCamera->AddEntry("Perspective (Floor XOZ)", kGLPerspXOZ);
636    fMenuCamera->AddEntry("Perspective (Floor YOZ)", kGLPerspYOZ);
637    fMenuCamera->AddEntry("Perspective (Floor XOY)", kGLPerspXOY);
638    fMenuCamera->AddEntry("Orthographic (XOY)", kGLXOY);
639    fMenuCamera->AddEntry("Orthographic (XOZ)", kGLXOZ);
640    fMenuCamera->AddEntry("Orthographic (ZOY)", kGLZOY);
641    fMenuCamera->AddSeparator();
642    fMenuCamera->AddEntry("Ortho allow rotate", kGLOrthoRotate);
643    fMenuCamera->AddEntry("Ortho allow dolly",  kGLOrthoDolly);
644
645    fMenuScene = new TGPopupMenu(gClient->GetRoot());
646    fMenuScene->AddEntry("&Update Current", kSceneUpdate);
647    fMenuScene->AddEntry("Update &All", kSceneUpdateAll);
648
649    // create the "help" popup menu
650    fMenuHelp = new TGPopupMenu(gClient->GetRoot());
651    fMenuHelp->AddEntry("&About", kHelpAbout);
652
653    // create the main menu bar
654    fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
655    fMenuBar->AddPopup("&File", fMenuFile, new TGLayoutHints(kLHintsTop | 
656                       kLHintsLeft, 0, 4, 0, 0));
657    fMenuBar->AddPopup("&Camera", fMenuCamera, new TGLayoutHints(kLHintsTop | 
658                       kLHintsLeft, 0, 4, 0, 0));
659    fMenuBar->AddPopup("&Scene", fMenuScene, new TGLayoutHints(kLHintsTop | 
660                       kLHintsLeft, 0, 4, 0, 0));
661    fMenuBar->AddPopup("&Help", fMenuHelp, new TGLayoutHints(kLHintsTop | 
662                       kLHintsRight));
663
664    AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
665
666    // connect menu signals to our menu handler slot
667    fMenuFile->Connect("Activated(Int_t)", "SplitGLView", this,
668                       "HandleMenu(Int_t)");
669    fMenuCamera->Connect("Activated(Int_t)", "SplitGLView", this,
670                         "HandleMenu(Int_t)");
671    fMenuScene->Connect("Activated(Int_t)", "SplitGLView", this,
672                        "HandleMenu(Int_t)");
673    fMenuHelp->Connect("Activated(Int_t)", "SplitGLView", this,
674                       "HandleMenu(Int_t)");
675    
676    if (fIsEmbedded && gEve) {
677       // use status bar from the browser
678       fStatusBar = gEve->GetBrowser()->GetStatusBar();
679    }
680    else {
681       // create the status bar
682       Int_t parts[] = {45, 15, 10, 30};
683       fStatusBar = new TGStatusBar(this, 50, 10);
684       fStatusBar->SetParts(parts, 4);
685       AddFrame(fStatusBar, new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 
686                0, 0, 10, 0));
687    }
688
689    // create eve pad (our geometry container)
690    fPad = new TEvePad();
691
692    // create the split frames
693    fSplitFrame = new TGSplitFrame(this, 800, 600);
694    AddFrame(fSplitFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
695    // split it once
696    fSplitFrame->VSplit(796);
697    // then split each part again (this will make four parts)
698    fSplitFrame->GetFirst()->HSplit(300);
699    fSplitFrame->GetFirst()->GetSecond()->VSplit(400);
700
701    // get top (main) split frame
702    frm = fSplitFrame->GetFirst()->GetFirst();
703    // create (embed) a GL viewer inside
704    fViewer0 = new TGLEmbeddedViewer(frm, fPad);
705    frm->AddFrame(fViewer0->GetFrame(), new TGLayoutHints(kLHintsExpandX | 
706                  kLHintsExpandY));
707    // set the camera to perspective (XOZ) for this viewer
708    fViewer0->SetCurrentCamera(TGLViewer::kCameraPerspXOZ);
709    // connect signal we are interested to
710    fViewer0->Connect("MouseOver(TGLPhysicalShape*)", "SplitGLView", this, 
711                       "OnMouseOver(TGLPhysicalShape*)");
712    fViewer0->Connect("Activated()", "SplitGLView", this, 
713                       "OnViewerActivated()");
714    fViewer0->Connect("MouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)", 
715                       "SplitGLView", this, 
716                       "OnMouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)");
717    fViewer0->Connect("Clicked(TObject*)", "SplitGLView", this, 
718                       "OnClicked(TObject*)");
719    fViewer[0] = new TEveViewer("SplitGLViewer[0]");
720    fViewer[0]->SetGLViewer(fViewer0);
721    fViewer[0]->IncDenyDestroy();
722    if (fIsEmbedded && gEve) {
723       fViewer[0]->AddScene(gEve->GetGlobalScene());
724       fViewer[0]->AddScene(gEve->GetEventScene());
725       gEve->AddElement(fViewer[0], gEve->GetViewers());
726       s = gEve->SpawnNewScene("Rho-Z Projection");
727       // projections
728       fRhoZMgr = new TEveProjectionManager();
729       gEve->AddElement(fRhoZMgr, (TEveElement *)s);
730       gEve->AddToListTree(fRhoZMgr, kTRUE);
731    }
732
733    // get bottom left split frame
734    frm = fSplitFrame->GetFirst()->GetSecond()->GetFirst();
735
736    hfrm = new TGHorizontalFrame(frm);
737    button= new TGPictureButton(hfrm, gClient->GetPicture("$ALICE_ROOT/EVE/alice-data/swap.png"));
738    button->SetToolTipText("Swap to big view");
739    hfrm->AddFrame(button);
740    button->Connect("Clicked()","SplitGLView",this,"SwapToMainView()");
741
742    // create (embed) a GL viewer inside
743    fViewer1 = new TGLEmbeddedViewer(hfrm, fPad);
744    hfrm->AddFrame(fViewer1->GetFrame(), new TGLayoutHints(kLHintsExpandX | 
745                   kLHintsExpandY));
746    frm->AddFrame(hfrm, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
747
748    // set the camera to orthographic (XOY) for this viewer
749    fViewer1->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
750    // connect signal we are interested to
751    fViewer1->Connect("MouseOver(TGLPhysicalShape*)", "SplitGLView", this, 
752                       "OnMouseOver(TGLPhysicalShape*)");
753    fViewer1->Connect("Activated()", "SplitGLView", this, 
754                       "OnViewerActivated()");
755    fViewer1->Connect("MouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)", 
756                       "SplitGLView", this, 
757                       "OnMouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)");
758    fViewer1->Connect("Clicked(TObject*)", "SplitGLView", this, 
759                       "OnClicked(TObject*)");
760    fViewer[1] = new TEveViewer("SplitGLViewer[1]");
761    fViewer[1]->SetGLViewer(fViewer1);
762    fViewer[1]->IncDenyDestroy();
763    if (fIsEmbedded && gEve) {
764       fRhoZMgr->ImportElements((TEveElement *)gEve->GetGlobalScene());
765       fRhoZMgr->ImportElements((TEveElement *)gEve->GetEventScene());
766       fRhoZMgr->SetProjection(TEveProjection::kPT_RhoZ);
767       fViewer[1]->AddScene(s);
768       gEve->AddElement(fViewer[1], gEve->GetViewers());
769       gRhoZMgr = fRhoZMgr;
770
771       s = gEve->SpawnNewScene("R-Phi Projection");
772       // projections
773       fRPhiMgr = new TEveProjectionManager();
774       gEve->AddElement(fRPhiMgr, (TEveElement *)s);
775       gEve->AddToListTree(fRPhiMgr, kTRUE);
776    }
777
778    // get bottom center split frame
779    frm = fSplitFrame->GetFirst()->GetSecond()->GetSecond();
780    // create (embed) a GL viewer inside
781    hfrm = new TGHorizontalFrame(frm);
782    button= new TGPictureButton(hfrm, gClient->GetPicture("$ALICE_ROOT/EVE/alice-data/swap.png"));
783    button->SetToolTipText("Swap to big view");
784    hfrm->AddFrame(button);
785    button->Connect("Clicked()","SplitGLView",this,"SwapToMainView()");
786
787    // create (embed) a GL viewer inside
788    fViewer2 = new TGLEmbeddedViewer(hfrm, fPad);
789    hfrm->AddFrame(fViewer2->GetFrame(), new TGLayoutHints(kLHintsExpandX | 
790                   kLHintsExpandY));
791    frm->AddFrame(hfrm, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
792
793    // set the camera to orthographic (XOY) for this viewer
794    fViewer2->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
795    // connect signal we are interested to
796    fViewer2->Connect("MouseOver(TGLPhysicalShape*)", "SplitGLView", this, 
797                       "OnMouseOver(TGLPhysicalShape*)");
798    fViewer2->Connect("Activated()", "SplitGLView", this, 
799                       "OnViewerActivated()");
800    fViewer2->Connect("MouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)", 
801                       "SplitGLView", this, 
802                       "OnMouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)");
803    fViewer2->Connect("Clicked(TObject*)", "SplitGLView", this, 
804                       "OnClicked(TObject*)");
805    fViewer[2] = new TEveViewer("SplitGLViewer[2]");
806    fViewer[2]->SetGLViewer(fViewer2);
807    fViewer[2]->IncDenyDestroy();
808    if (fIsEmbedded && gEve) {
809       fRPhiMgr->ImportElements((TEveElement *)gEve->GetGlobalScene());
810       fRPhiMgr->ImportElements((TEveElement *)gEve->GetEventScene());
811       fRPhiMgr->SetProjection(TEveProjection::kPT_RPhi);
812       fViewer[2]->AddScene(s);
813       gEve->AddElement(fViewer[2], gEve->GetViewers());
814       gRPhiMgr = fRPhiMgr;
815    }
816
817    // get bottom right split frame
818    frm = fSplitFrame->GetSecond();
819
820    hfrm  = new TGHorizontalFrame(frm);
821    button= new TGPictureButton(hfrm, gClient->GetPicture("$ALICE_ROOT/EVE/alice-data/swap.png"));
822    button->SetToolTipText("Swap to big view");
823    hfrm->AddFrame(button);
824    button->Connect("Clicked()","SplitGLView",this,"SwapToMainView()");
825    fgHtmlSummary = new HtmlSummary("Alice Event Display Summary Table");
826    fgHtml = new TGHtml(hfrm, 100, 100, -1);
827    hfrm->AddFrame(fgHtml, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
828    frm->AddFrame(hfrm, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
829
830    if (fIsEmbedded && gEve) {
831       gEve->GetListTree()->Connect("Clicked(TGListTreeItem*, Int_t, Int_t, Int_t)",
832          "SplitGLView", this, "ItemClicked(TGListTreeItem*, Int_t, Int_t, Int_t)");
833    }
834
835    fShapedToolTip = new TGShapedToolTip("$ALICE_ROOT/EVE/alice-data/Default.png", 120, 22, 160, 110, 
836                                         23, 115, 12, "#ffff80");
837    Resize(GetDefaultSize());
838    MapSubwindows();
839    MapWindow();
840
841    fSplitFrame->Layout();
842    // !!!! LoadConfig(".everc");
843 }
844
845 //______________________________________________________________________________
846 SplitGLView::~SplitGLView()
847 {
848    // Clean up main frame...
849    // Cleanup();
850    
851    fMenuFile->Disconnect("Activated(Int_t)", this, "HandleMenu(Int_t)");
852    fMenuCamera->Disconnect("Activated(Int_t)", this, "HandleMenu(Int_t)");
853    fMenuScene->Disconnect("Activated(Int_t)", this, "HandleMenu(Int_t)");
854    fMenuHelp->Disconnect("Activated(Int_t)", this, "HandleMenu(Int_t)");
855    fViewer0->Disconnect("MouseOver(TGLPhysicalShape*)", this, 
856                          "OnMouseOver(TGLPhysicalShape*)");
857    fViewer0->Disconnect("Activated()", this, "OnViewerActivated()");
858    fViewer0->Disconnect("MouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)", 
859                          this, "OnMouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)");
860    fViewer1->Disconnect("MouseOver(TGLPhysicalShape*)", this, 
861                          "OnMouseOver(TGLPhysicalShape*)");
862    fViewer1->Disconnect("Activated()", this, "OnViewerActivated()");
863    fViewer1->Disconnect("MouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)", 
864                          this, "OnMouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)");
865    fViewer2->Disconnect("MouseOver(TGLPhysicalShape*)", this, 
866                          "OnMouseOver(TGLPhysicalShape*)");
867    fViewer2->Disconnect("Activated()", this, "OnViewerActivated()");
868    fViewer2->Disconnect("MouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)", 
869                          this, "OnMouseIdle(TGLPhysicalShape*,UInt_t,UInt_t)");
870    if (!fIsEmbedded) {
871       delete fViewer[0];
872       delete fViewer[1];
873       delete fViewer[2];
874    }
875    delete fShapedToolTip;
876    delete fMenuFile;
877    delete fMenuScene;
878    delete fMenuCamera;
879    delete fMenuHelp;
880    if (!fIsEmbedded)
881       delete fMenuBar;
882    delete fViewer0;
883    delete fViewer1;
884    delete fViewer2;
885    delete fSplitFrame;
886    delete fPad;
887    if (!fIsEmbedded) {
888       delete fStatusBar;
889       gApplication->Terminate(0);
890    }
891 }
892
893 //______________________________________________________________________________
894 void SplitGLView::HandleMenu(Int_t id)
895 {
896    // Handle menu items.
897
898    static TString rcdir(".");
899    static TString rcfile(".everc");
900
901    switch (id) {
902
903       case kFileOpen:
904          {
905             static TString dir(".");
906             TGFileInfo fi;
907             fi.fFileTypes = filetypes;
908             fi.fIniDir    = StrDup(dir);
909             new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fi);
910             if (fi.fFilename)
911                OpenFile(fi.fFilename);
912             dir = fi.fIniDir;
913          }
914          break;
915
916       case kFileLoadConfig:
917          {
918             TGFileInfo fi;
919             fi.fFileTypes = rcfiletypes;
920             fi.fIniDir    = StrDup(rcdir);
921             fi.fFilename  = StrDup(rcfile);
922             new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fi);
923             if (fi.fFilename) {
924                rcfile = fi.fFilename;
925                LoadConfig(fi.fFilename);
926             }
927             rcdir = fi.fIniDir;
928          }
929          break;
930
931       case kFileSaveConfig:
932          {
933             TGFileInfo fi;
934             fi.fFileTypes = rcfiletypes;
935             fi.fIniDir    = StrDup(rcdir);
936             fi.fFilename  = StrDup(rcfile);
937             new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fi);
938             if (fi.fFilename) {
939                rcfile = fi.fFilename;
940                SaveConfig(fi.fFilename);
941             }
942             rcdir = fi.fIniDir;
943          }
944          break;
945
946       case kFileExit:
947          CloseWindow();
948          break;
949
950       case kGLPerspYOZ:
951          if (fActViewer)
952             fActViewer->SetCurrentCamera(TGLViewer::kCameraPerspYOZ);
953          break;
954       case kGLPerspXOZ:
955          if (fActViewer)
956             fActViewer->SetCurrentCamera(TGLViewer::kCameraPerspXOZ);
957          break;
958       case kGLPerspXOY:
959          if (fActViewer)
960             fActViewer->SetCurrentCamera(TGLViewer::kCameraPerspXOY);
961          break;
962       case kGLXOY:
963          if (fActViewer)
964             fActViewer->SetCurrentCamera(TGLViewer::kCameraOrthoXOY);
965          break;
966       case kGLXOZ:
967          if (fActViewer)
968             fActViewer->SetCurrentCamera(TGLViewer::kCameraOrthoXOZ);
969          break;
970       case kGLZOY:
971          if (fActViewer)
972             fActViewer->SetCurrentCamera(TGLViewer::kCameraOrthoZOY);
973          break;
974       case kGLOrthoRotate:
975          ToggleOrthoRotate();
976          break;
977       case kGLOrthoDolly:
978          ToggleOrthoDolly();
979          break;
980
981       case kSceneUpdate:
982          if (fActViewer)
983             fActViewer->UpdateScene();
984          UpdateSummary();
985          break;
986
987       case kSceneUpdateAll:
988          fViewer0->UpdateScene();
989          fViewer1->UpdateScene();
990          fViewer2->UpdateScene();
991          UpdateSummary();
992          break;
993
994       case kSummaryUpdate:
995          UpdateSummary();
996          break;
997
998       case kHelpAbout:
999          {
1000 #ifdef R__UNIX
1001             TString rootx;
1002 # ifdef ROOTBINDIR
1003             rootx = ROOTBINDIR;
1004 # else
1005             rootx = gSystem->Getenv("ROOTSYS");
1006             if (!rootx.IsNull()) rootx += "/bin";
1007 # endif
1008             rootx += "/root -a &";
1009             gSystem->Exec(rootx);
1010 #else
1011 #ifdef WIN32
1012             new TWin32SplashThread(kTRUE);
1013 #else
1014             char str[32];
1015             sprintf(str, "About ROOT %s...", gROOT->GetVersion());
1016             hd = new TRootHelpDialog(this, str, 600, 400);
1017             hd->SetText(gHelpAbout);
1018             hd->Popup();
1019 #endif
1020 #endif
1021          }
1022          break;
1023
1024       default:
1025          break;
1026    }
1027 }
1028
1029 //______________________________________________________________________________
1030 void SplitGLView::OnClicked(TObject *obj)
1031 {
1032    // Handle click events in GL viewer
1033
1034    if (obj)
1035       fStatusBar->SetText(Form("User clicked on: \"%s\"", obj->GetName()), 1);
1036    else
1037       fStatusBar->SetText("", 1);
1038 }
1039
1040 //______________________________________________________________________________
1041 void SplitGLView::OnMouseIdle(TGLPhysicalShape *shape, UInt_t posx, UInt_t posy)
1042 {
1043    // Slot used to handle "OnMouseIdle" signal coming from any GL viewer.
1044    // We receive a pointer on the physical shape in which the mouse cursor is
1045    // and the actual cursor position (x,y)
1046
1047    Window_t wtarget;
1048    Int_t    x = 0, y = 0;
1049
1050    static TH1F *h1f = 0;
1051    TFormula *form1 = new TFormula("form1","abs(sin(x)/x)");
1052    form1->Update(); // silent warning about unused variable...
1053    TF1 *sqroot = new TF1("sqroot","x*gaus(0) + [3]*form1",0,10);
1054    sqroot->SetParameters(10,4,1,20);
1055    if (h1f == 0)
1056       h1f = new TH1F("h1f","",50,0,10);
1057    h1f->Reset();
1058    h1f->SetFillColor(45);
1059    h1f->SetStats(0);
1060    h1f->FillRandom("sqroot",200);
1061
1062    if (fShapedToolTip) {
1063       fShapedToolTip->UnmapWindow();
1064    }
1065    if (shape && shape->GetLogical() && shape->GetLogical()->GetExternal()) {
1066       // get the actual viewer who actually emitted the signal
1067       TGLEmbeddedViewer *actViewer = dynamic_cast<TGLEmbeddedViewer*>((TQObject*)gTQSender);
1068       // then translate coordinates from the root (screen) coordinates 
1069       // to the actual frame (viewer) ones
1070       gVirtualX->TranslateCoordinates(actViewer->GetFrame()->GetId(),
1071                gClient->GetDefaultRoot()->GetId(), posx, posy, x, y,
1072                wtarget);
1073       // Then display our tooltip at this x,y location
1074       if (fShapedToolTip) {
1075          fShapedToolTip->Show(x+5, y+5, Form("%s\n     \n%s",
1076                               shape->GetLogical()->GetExternal()->IsA()->GetName(), 
1077                               shape->GetLogical()->GetExternal()->GetName()), h1f);
1078       }
1079    }
1080 }
1081
1082 //______________________________________________________________________________
1083 void SplitGLView::OnMouseOver(TGLPhysicalShape *shape)
1084 {
1085    // Slot used to handle "OnMouseOver" signal coming from any GL viewer.
1086    // We receive a pointer on the physical shape in which the mouse cursor is.
1087
1088    // display informations on the physical shape in the status bar
1089    if (shape && shape->GetLogical() && shape->GetLogical()->GetExternal())
1090       fStatusBar->SetText(Form("Mouse Over: \"%s\"", 
1091          shape->GetLogical()->GetExternal()->GetName()), 0);
1092    else
1093       fStatusBar->SetText("", 0);
1094 }
1095
1096 //______________________________________________________________________________
1097 void SplitGLView::OnViewerActivated()
1098 {
1099    // Slot used to handle "Activated" signal coming from any GL viewer.
1100    // Used to know which GL viewer is active.
1101
1102    static Pixel_t green = 0;
1103    // set the actual GL viewer frame to default color
1104    if (fActViewer && fActViewer->GetFrame())
1105       fActViewer->GetFrame()->ChangeBackground(GetDefaultFrameBackground());
1106
1107    // change the actual GL viewer to the one who emitted the signal
1108    // fActViewer = (TGLEmbeddedViewer *)gTQSender;
1109    fActViewer = dynamic_cast<TGLEmbeddedViewer*>((TQObject*)gTQSender);
1110
1111    if (fActViewer == 0) {
1112       printf ("dyncast failed ...\n");
1113       return;
1114    }
1115
1116    // get the highlight color (only once)
1117    if (green == 0) {
1118       gClient->GetColorByName("green", green);
1119    }
1120    // set the new actual GL viewer frame to highlight color
1121    if (fActViewer->GetFrame())
1122       fActViewer->GetFrame()->ChangeBackground(green);
1123
1124    // update menu entries to match actual viewer's options
1125    if (fActViewer->GetOrthoXOYCamera()->GetDollyToZoom() &&
1126        fActViewer->GetOrthoXOZCamera()->GetDollyToZoom() &&
1127        fActViewer->GetOrthoZOYCamera()->GetDollyToZoom())
1128       fMenuCamera->UnCheckEntry(kGLOrthoDolly);
1129    else
1130       fMenuCamera->CheckEntry(kGLOrthoDolly);
1131
1132    if (fActViewer->GetOrthoXOYCamera()->GetEnableRotate() &&
1133        fActViewer->GetOrthoXOYCamera()->GetEnableRotate() &&
1134        fActViewer->GetOrthoXOYCamera()->GetEnableRotate())
1135       fMenuCamera->CheckEntry(kGLOrthoRotate);
1136    else
1137       fMenuCamera->UnCheckEntry(kGLOrthoRotate);
1138 }
1139
1140 //______________________________________________________________________________
1141 void SplitGLView::OpenFile(const char *fname)
1142 {
1143    // Open a Root file to display a geometry in the GL viewers.
1144
1145    TString filename = fname;
1146    // check if the file type is correct
1147    if (!filename.EndsWith(".root")) {
1148       new TGMsgBox(gClient->GetRoot(), this, "OpenFile",
1149                    Form("The file \"%s\" is not a root file!", fname),
1150                    kMBIconExclamation, kMBOk);
1151       return;
1152    }
1153    // check if the root file contains a geometry
1154    if (TGeoManager::Import(fname) == 0) {
1155       new TGMsgBox(gClient->GetRoot(), this, "OpenFile",
1156                    Form("The file \"%s\" does't contain a geometry", fname),
1157                    kMBIconExclamation, kMBOk);
1158       return;
1159    }
1160    gGeoManager->DefaultColors();
1161    // delete previous primitives (if any)
1162    fPad->GetListOfPrimitives()->Delete();
1163    // and add the geometry to eve pad (container)
1164    fPad->GetListOfPrimitives()->Add(gGeoManager->GetTopVolume());
1165    // paint the geometry in each GL viewer
1166    fViewer0->PadPaint(fPad);
1167    fViewer1->PadPaint(fPad);
1168    fViewer2->PadPaint(fPad);
1169 }
1170
1171 //______________________________________________________________________________
1172 void SplitGLView::ToggleOrthoRotate()
1173 {
1174    // Toggle state of the 'Ortho allow rotate' menu entry.
1175
1176    if (fMenuCamera->IsEntryChecked(kGLOrthoRotate))
1177       fMenuCamera->UnCheckEntry(kGLOrthoRotate);
1178    else
1179       fMenuCamera->CheckEntry(kGLOrthoRotate);
1180    Bool_t state = fMenuCamera->IsEntryChecked(kGLOrthoRotate);
1181    if (fActViewer) {
1182       fActViewer->GetOrthoXOYCamera()->SetEnableRotate(state);
1183       fActViewer->GetOrthoXOYCamera()->SetEnableRotate(state);
1184       fActViewer->GetOrthoXOYCamera()->SetEnableRotate(state);
1185    }
1186 }
1187
1188 //______________________________________________________________________________
1189 void SplitGLView::ToggleOrthoDolly()
1190 {
1191    // Toggle state of the 'Ortho allow dolly' menu entry.
1192
1193    if (fMenuCamera->IsEntryChecked(kGLOrthoDolly))
1194       fMenuCamera->UnCheckEntry(kGLOrthoDolly);
1195    else
1196       fMenuCamera->CheckEntry(kGLOrthoDolly);
1197    Bool_t state = ! fMenuCamera->IsEntryChecked(kGLOrthoDolly);
1198    if (fActViewer) {
1199       fActViewer->GetOrthoXOYCamera()->SetDollyToZoom(state);
1200       fActViewer->GetOrthoXOZCamera()->SetDollyToZoom(state);
1201       fActViewer->GetOrthoZOYCamera()->SetDollyToZoom(state);
1202    }
1203 }
1204
1205 //______________________________________________________________________________
1206 void SplitGLView::ItemClicked(TGListTreeItem *item, Int_t, Int_t, Int_t)
1207 {
1208    // Item has been clicked, based on mouse button do:
1209
1210    static const TEveException eh("SplitGLView::ItemClicked ");
1211    TEveElement* re = (TEveElement*)item->GetUserData();
1212    if(re == 0) return;
1213    TObject* obj = re->GetObject(eh);
1214    if (obj->InheritsFrom("TEveViewer")) {
1215       TGLViewer *v = ((TEveViewer *)obj)->GetGLViewer();
1216       //v->Activated();
1217       if (v->InheritsFrom("TGLEmbeddedViewer")) {
1218          TGLEmbeddedViewer *ev = (TGLEmbeddedViewer *)v;
1219          gVirtualX->SetInputFocus(ev->GetGLWindow()->GetContainer()->GetId());
1220       }
1221    }
1222 }
1223
1224 //______________________________________________________________________________
1225 void SplitGLView::LoadConfig(const char *fname)
1226 {
1227
1228    Int_t height, width;
1229    TEnv *env = new TEnv(fname);
1230
1231    Int_t mainheight = env->GetValue("MainView.Height", 434);
1232    Int_t blwidth    = env->GetValue("Bottom.Left.Width", 266);
1233    Int_t bcwidth    = env->GetValue("Bottom.Center.Width", 266);
1234    Int_t brwidth    = env->GetValue("Bottom.Right.Width", 266);
1235    Int_t top_height = env->GetValue("Right.Tab.Height", 0);
1236    Int_t bottom_height = env->GetValue("Bottom.Tab.Height", 0);
1237
1238    if (fIsEmbedded && gEve) {
1239       Int_t sel = env->GetValue("Eve.Selection", gEve->GetSelection()->GetPickToSelect());
1240       Int_t hi = env->GetValue("Eve.Highlight", gEve->GetHighlight()->GetPickToSelect());
1241       gEve->GetBrowser()->EveMenu(9+sel);
1242       gEve->GetBrowser()->EveMenu(13+hi);
1243
1244       width  = env->GetValue("Eve.Width", (Int_t)gEve->GetBrowser()->GetWidth());
1245       height = env->GetValue("Eve.Height", (Int_t)gEve->GetBrowser()->GetHeight());
1246       gEve->GetBrowser()->Resize(width, height);
1247    }
1248
1249    // top (main) split frame
1250    width = fSplitFrame->GetFirst()->GetWidth();
1251    fSplitFrame->GetFirst()->Resize(width, mainheight);
1252    // bottom left split frame
1253    height = fSplitFrame->GetSecond()->GetFirst()->GetHeight();
1254    fSplitFrame->GetSecond()->GetFirst()->Resize(blwidth, height);
1255    // bottom center split frame
1256    height = fSplitFrame->GetSecond()->GetSecond()->GetFirst()->GetHeight();
1257    fSplitFrame->GetSecond()->GetSecond()->GetFirst()->Resize(bcwidth, height);
1258    // bottom right split frame
1259    height = fSplitFrame->GetSecond()->GetSecond()->GetSecond()->GetHeight();
1260    fSplitFrame->GetSecond()->GetSecond()->GetSecond()->Resize(brwidth, height);
1261
1262    fSplitFrame->Layout();
1263
1264    if (fIsEmbedded && gEve) {
1265       width = ((TGCompositeFrame *)gEve->GetBrowser()->GetTabBottom()->GetParent())->GetWidth();
1266       ((TGCompositeFrame *)gEve->GetBrowser()->GetTabBottom()->GetParent())->Resize(width, bottom_height);
1267       width = ((TGCompositeFrame *)gEve->GetBrowser()->GetTabRight()->GetParent())->GetWidth();
1268       ((TGCompositeFrame *)gEve->GetBrowser()->GetTabRight()->GetParent())->Resize(width, top_height);
1269    }
1270 }
1271
1272 //______________________________________________________________________________
1273 void SplitGLView::SaveConfig(const char *fname)
1274 {
1275
1276    Int_t bottom_height = 0;
1277    Int_t top_height = 0;
1278    TGSplitFrame *frm;
1279    TEnv *env = new TEnv(fname);
1280
1281    if (fIsEmbedded && gEve) {
1282       env->SetValue("Eve.Width", (Int_t)gEve->GetBrowser()->GetWidth());
1283       env->SetValue("Eve.Height", (Int_t)gEve->GetBrowser()->GetHeight());
1284    }
1285    // get top (main) split frame
1286    frm = fSplitFrame->GetFirst();
1287    env->SetValue("MainView.Height", (Int_t)frm->GetHeight());
1288    // get bottom left split frame
1289    frm = fSplitFrame->GetSecond()->GetFirst();
1290    env->SetValue("Bottom.Left.Width", (Int_t)frm->GetWidth());
1291    // get bottom center split frame
1292    frm = fSplitFrame->GetSecond()->GetSecond()->GetFirst();
1293    env->SetValue("Bottom.Center.Width", (Int_t)frm->GetWidth());
1294    // get bottom right split frame
1295    frm = fSplitFrame->GetSecond()->GetSecond()->GetSecond();
1296    env->SetValue("Bottom.Right.Width", (Int_t)frm->GetWidth());
1297    if (fIsEmbedded && gEve) {
1298       top_height = (Int_t)((TGCompositeFrame *)gEve->GetBrowser()->GetTabRight()->GetParent())->GetHeight();
1299       env->SetValue("Right.Tab.Height", top_height);
1300       bottom_height = (Int_t)((TGCompositeFrame *)gEve->GetBrowser()->GetTabBottom()->GetParent())->GetHeight();
1301       env->SetValue("Bottom.Tab.Height", bottom_height);
1302
1303       env->SetValue("Eve.Selection", gEve->GetSelection()->GetPickToSelect());
1304       env->SetValue("Eve.Highlight", gEve->GetHighlight()->GetPickToSelect());
1305    }
1306
1307    env->SaveLevel(kEnvLocal);
1308 #ifdef R__WIN32
1309    if (!gSystem->AccessPathName(Form("%s.new", fname))) {
1310       gSystem->Exec(Form("del %s", fname));
1311       gSystem->Rename(Form("%s.new", fname), fname);
1312    }
1313 #endif
1314 }
1315
1316 //______________________________________________________________________________
1317 void SplitGLView::SwapToMainView()
1318 {
1319    TGPictureButton *src = (TGPictureButton*)gTQSender;
1320    TGCompositeFrame *parent = (TGCompositeFrame *)(src->GetParent());
1321    TGFrame *source = dynamic_cast<TGFrameElement*>(parent->GetList()->Last())->fFrame;
1322    if (!source) return;
1323
1324    TGSplitFrame *dest = fSplitFrame->GetFirst()->GetFirst();
1325    
1326    TGFrame *prev = (TGFrame *)(dest->GetFrame());
1327    
1328    if ((source != prev) && (source != dest))
1329       TGSplitFrame::SwitchFrames(source, dest, prev);
1330 }
1331
1332 //______________________________________________________________________________
1333 void SplitGLView::UpdateSummary()
1334 {
1335    // Update summary of current event.
1336
1337    TEveElement::List_i i;
1338    TEveElement::List_i j;
1339    Int_t k;
1340    TEveElement *el;
1341    HtmlObjTable *table;
1342    TEveEventManager *mgr = gEve ? gEve->GetCurrentEvent() : 0;
1343    if (mgr) {
1344       fgHtmlSummary->Clear("D");
1345       for (i=mgr->BeginChildren(); i!=mgr->EndChildren(); ++i)
1346       {
1347          el = ((TEveElement*)(*i));
1348          if (el->IsA() == TEvePointSet::Class()) {
1349             TEvePointSet *ps = (TEvePointSet *)el;
1350             TString ename  = ps->GetElementName();
1351             TString etitle = ps->GetElementTitle();
1352             //ename.Remove(ename.First('\''));
1353             //etitle.Remove(0, 2);
1354             Int_t nel = atoi(etitle.Data());
1355             table = fgHtmlSummary->AddTable(ename, 0, nel);
1356          }
1357          else if (el->IsA() == TEveTrackList::Class()) {
1358             TEveTrackList *tracks = (TEveTrackList *)el;
1359             TString ename  = tracks->GetElementName();
1360             // ename.Remove(ename.First('\''));
1361             table = fgHtmlSummary->AddTable(ename.Data(), 5, 
1362                                             tracks->GetNChildren(), kTRUE, "first");
1363             table->SetLabel(0, "Momentum");
1364             table->SetLabel(1, "P_t");
1365             table->SetLabel(2, "Phi");
1366             table->SetLabel(3, "Theta");
1367             table->SetLabel(4, "Eta");
1368             k=0;
1369             for (j=tracks->BeginChildren(); j!=tracks->EndChildren(); ++j) {
1370                Float_t p     = ((TEveTrack*)(*j))->GetMomentum().Mag();
1371                table->SetValue(0, k, p);
1372                Float_t pt    = ((TEveTrack*)(*j))->GetMomentum().Perp();
1373                table->SetValue(1, k, pt);
1374                Float_t phi   = ((TEveTrack*)(*j))->GetMomentum().Phi();
1375                table->SetValue(2, k, phi);
1376                Float_t theta = ((TEveTrack*)(*j))->GetMomentum().Theta();
1377                table->SetValue(3, k, theta);
1378                Float_t eta   = ((TEveTrack*)(*j))->GetMomentum().Eta();
1379                table->SetValue(4, k, eta);
1380                ++k;
1381             }
1382          }
1383       }
1384       fgHtmlSummary->Build();
1385       fgHtml->Clear();
1386       fgHtml->ParseText((char*)fgHtmlSummary->Html().Data());
1387       fgHtml->Layout();
1388    }
1389 }
1390
1391 // Linkdef
1392 #ifdef __CINT__
1393
1394 #pragma link C++ class SplitGLView;
1395
1396 #endif