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