Avoid jumping of entries in data-selector window -- restore scrollbar position after...
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveEventManagerEditor.cxx
1 // @(#)root/eve:$Id$
2 // Author: Matevz Tadel 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveEventManagerEditor.h"
11 #include "AliEveEventManager.h"
12
13 #include <AliESDEvent.h>
14
15 #include <TVirtualPad.h>
16 #include "TColor.h"
17
18 #include <TEveGValuators.h>
19 #include <TGButton.h>
20 #include <TGTextView.h>
21 #include <TGLabel.h>
22
23 //______________________________________________________________________________
24 // GUI editor for AliEveEventManager.
25 //
26
27 ClassImp(AliEveEventManagerEditor)
28
29 //______________________________________________________________________________
30 AliEveEventManagerEditor::AliEveEventManagerEditor(const TGWindow *p, Int_t width, Int_t height,
31                                                    UInt_t options, Pixel_t back) :
32   TGedFrame(p, width, height, options | kVerticalFrame, back),
33   fM(0),
34   fNextEvent(0),
35   fEventInfo(0)
36 {
37   // Constructor.
38
39   MakeTitle("AliEveEventManager");
40
41   {
42     TGHorizontalFrame* f = new TGHorizontalFrame(this);
43     fNextEvent = new TGTextButton(f, "Next Event");
44     fNextEvent->SetWidth(100);
45     fNextEvent->ChangeOptions(fNextEvent->GetOptions() | kFixedWidth);
46     f->AddFrame(fNextEvent, new TGLayoutHints(kLHintsNormal, 4,0,0,0));
47     fNextEvent->Connect("Clicked()",
48                         "AliEveEventManagerEditor", this, "DoNextEvent()");
49     AddFrame(f, new TGLayoutHints(kLHintsExpandX, 8,8,8,0));
50   }
51   {
52     TGVerticalFrame* f = new TGVerticalFrame(this);
53
54     TGLabel *eventInfoLabel = new TGLabel(f, "Event Information:");
55     f->AddFrame(eventInfoLabel, new TGLayoutHints(kLHintsNormal, 0,0,6,2));
56
57     fEventInfo = new TGTextView(f, 200, 300);
58     f->AddFrame(fEventInfo, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
59
60     AddFrame(f, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
61   }
62 }
63
64 /******************************************************************************/
65
66 //______________________________________________________________________________
67 void AliEveEventManagerEditor::SetModel(TObject* obj)
68 {
69   // Set model object.
70
71   fM = dynamic_cast<AliEveEventManager*>(obj);
72
73   fEventInfo->LoadBuffer(fM->GetEventInfoVertical());
74 }
75
76 /******************************************************************************/
77
78 //______________________________________________________________________________
79 void AliEveEventManagerEditor::DoNextEvent()
80 {
81   // Load next event
82
83   fM->NextEvent();
84 }
85
86
87 //==============================================================================
88 // AliEveEventManagerWindow
89 //==============================================================================
90
91 //______________________________________________________________________________
92 //
93 // Horizontal GUI for AliEveEventManager, to be placed in the
94 // bottom part of ROOT browser.
95
96 ClassImp(AliEveEventManagerWindow)
97
98 AliEveEventManagerWindow::AliEveEventManagerWindow(AliEveEventManager* mgr) :
99   TGMainFrame(gClient->GetRoot(), 400, 100, kVerticalFrame),
100   fM            (mgr),
101   fFirstEvent   (0),
102   fPrevEvent    (0),
103   fNextEvent    (0),
104   fLastEvent    (0),
105   fRefresh      (0),
106   fEventId      (0),
107   fInfoLabel    (0),
108   fAutoLoad     (0),
109   fAutoLoadTime (0),
110   fTrigSel      (0),
111   fEventInfo    (0)
112 {
113   // Constructor.
114
115   const TString cls("AliEveEventManagerWindow");
116   TGTextButton *b = 0;
117   {
118     Int_t width = 50;
119
120     TGHorizontalFrame* f = new TGHorizontalFrame(this);
121     AddFrame(f, new TGLayoutHints(kLHintsExpandX, 0,0,2,2));
122
123     fFirstEvent = b = MkTxtButton(f, "First", width);
124     b->Connect("Clicked()", cls, this, "DoFirstEvent()");
125     fPrevEvent = b = MkTxtButton(f, "Prev", width);
126     b->Connect("Clicked()", cls, this, "DoPrevEvent()");
127
128     fEventId = new TGNumberEntry(f, 0, 5, -1,TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative,
129                                  TGNumberFormat::kNELLimitMinMax, 0, 10000);
130     f->AddFrame(fEventId, new TGLayoutHints(kLHintsNormal, 10, 5, 0, 0));
131     fEventId->Connect("ValueSet(Long_t)", cls, this, "DoSetEvent()");
132     fInfoLabel = new TGLabel(f);
133     f->AddFrame(fInfoLabel, new TGLayoutHints(kLHintsNormal, 5, 10, 4, 0));
134
135     fNextEvent = b = MkTxtButton(f, "Next", width);
136     b->Connect("Clicked()", cls, this, "DoNextEvent()");
137     fLastEvent = b = MkTxtButton(f, "Last", width);
138     b->Connect("Clicked()", cls, this, "DoLastEvent()");
139
140     MkLabel(f, "||", 0, 8, 8);
141
142     fRefresh = b = MkTxtButton(f, "Refresh", width + 8);
143     b->Connect("Clicked()",cls, this, "DoRefresh()");
144
145     MkLabel(f, "||", 0, 8, 8);
146
147     fAutoLoad = new TGCheckButton(f, "Autoload");
148     f->AddFrame(fAutoLoad, new TGLayoutHints(kLHintsLeft, 0, 4, 3, 0));
149     fAutoLoad->SetToolTipText("Automatic event loading.");
150     fAutoLoad->Connect("Toggled(Bool_t)", cls, this, "DoSetAutoLoad()");
151
152     fAutoLoadTime = new TEveGValuator(f, "Time: ", 110, 0);
153     f->AddFrame(fAutoLoadTime);
154     fAutoLoadTime->SetShowSlider(kFALSE);
155     fAutoLoadTime->SetNELength(4);
156     fAutoLoadTime->Build();
157     fAutoLoadTime->SetLimits(0, 1000);
158     fAutoLoadTime->SetToolTip("Automatic event loading time in seconds.");
159     fAutoLoadTime->Connect("ValueSet(Double_t)", cls, this, "DoSetAutoLoadTime()");
160
161     fTrigSel = new TGComboBox(f);
162     fTrigSel->Resize(4*width,b->GetDefaultHeight());
163     fTrigSel->AddEntry("No trigger selection",-1);
164     fTrigSel->Select(-1,kFALSE);
165     f->AddFrame(fTrigSel, new TGLayoutHints(kLHintsNormal, 10, 5, 0, 0));
166     fTrigSel->Connect("Selected(char*)", cls, this, "DoSetTrigSel()");
167   }
168
169   fEventInfo = new TGTextView(this, 400, 600);
170   AddFrame(fEventInfo, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
171
172   fM->Connect("NewEventLoaded()", cls, this, "Update()");
173
174   SetCleanup(kDeepCleanup);
175   Layout();
176   MapSubwindows();
177   MapWindow();
178 }
179
180 //______________________________________________________________________________
181 AliEveEventManagerWindow::~AliEveEventManagerWindow()
182 {
183   // Destructor.
184
185   fM->Disconnect("NewEventLoaded()", this);
186 }
187
188 //______________________________________________________________________________
189 void AliEveEventManagerWindow::DoFirstEvent()
190 {
191   // Load previous event
192   fM->GotoEvent(0);
193 }
194
195 //______________________________________________________________________________
196 void AliEveEventManagerWindow::DoPrevEvent()
197 {
198   // Load previous event
199   fM->PrevEvent();
200 }
201
202 //______________________________________________________________________________
203 void AliEveEventManagerWindow::DoNextEvent()
204 {
205   // Load next event
206   fM->NextEvent();
207 }
208
209 //______________________________________________________________________________
210 void AliEveEventManagerWindow::DoLastEvent()
211 {
212   // Load previous event
213   fM->GotoEvent(-1);
214 }
215
216 //______________________________________________________________________________
217 void AliEveEventManagerWindow::DoSetEvent()
218 {
219   // Set current event
220   fM->GotoEvent((Int_t) fEventId->GetNumber());
221 }
222
223 //______________________________________________________________________________
224 void AliEveEventManagerWindow::DoRefresh()
225 {
226   // Refresh event status.
227
228   Int_t ev = fM->GetEventId();
229   fM->Close();
230   fM->Open();
231   fM->GotoEvent(ev);
232 }
233
234 //______________________________________________________________________________
235 void AliEveEventManagerWindow::DoSetAutoLoad()
236 {
237   // Set the auto-load flag
238
239   fM->SetAutoLoad(fAutoLoad->IsOn());
240   Update();
241 }
242
243 //______________________________________________________________________________
244 void AliEveEventManagerWindow::DoSetAutoLoadTime()
245 {
246   // Set the auto-load time in seconds
247
248   fM->SetAutoLoadTime(fAutoLoadTime->GetValue());
249 }
250
251 //______________________________________________________________________________
252 void AliEveEventManagerWindow::DoSetTrigSel()
253 {
254   // Set the trigger selection
255
256   fM->SetTrigSel(fTrigSel->GetSelectedEntry()->EntryId());
257 }
258
259 //______________________________________________________________________________
260 void AliEveEventManagerWindow::Update()
261 {
262   // Update current event, number of available events, list of active triggers
263
264   Bool_t autoLoad = fM->GetAutoLoad();
265   Bool_t extCtrl  = fM->IsUnderExternalControl();
266   Bool_t evNavOn  = !autoLoad && !extCtrl;
267
268   fFirstEvent->SetEnabled(evNavOn);
269   fPrevEvent ->SetEnabled(evNavOn);
270   fLastEvent ->SetEnabled(evNavOn);
271   fNextEvent ->SetEnabled(!autoLoad);
272   fRefresh   ->SetEnabled(evNavOn);
273
274   fEventId->SetNumber(fM->GetEventId());
275   fEventId->SetState(evNavOn);
276   fInfoLabel->SetText(Form("/ %d", fM->GetMaxEventId()));
277
278   fAutoLoad->SetState(fM->GetAutoLoad() ? kButtonDown : kButtonUp);
279   fAutoLoadTime->SetValue(fM->GetAutoLoadTime());
280
281   // Loop over active trigger classes
282   if (fM->GetESD()) {
283     for(Int_t iTrig = 0; iTrig < AliESDRun::kNTriggerClasses; iTrig++) {
284       TString trigName = fM->GetESD()->GetESDRun()->GetTriggerClass(iTrig);
285       if (trigName.IsNull()) {
286         if (fTrigSel->GetListBox()->GetEntry(iTrig)) {
287           if (fTrigSel->GetSelected() == iTrig) fTrigSel->Select(-1);
288           fTrigSel->RemoveEntry(iTrig);
289         }
290         continue;
291       }
292       if (!fTrigSel->FindEntry(trigName.Data()))
293         fTrigSel->AddEntry(trigName.Data(),iTrig);
294     }
295   }
296   fTrigSel->SetEnabled(!evNavOn);
297
298   fEventInfo->LoadBuffer(fM->GetEventInfoHorizontal());
299
300   Layout();
301 }
302
303 //------------------------------------------------------------------------------
304 // Protected methods
305 //------------------------------------------------------------------------------
306
307 //______________________________________________________________________________
308 TGTextButton* AliEveEventManagerWindow::MkTxtButton(TGCompositeFrame* p,
309                                                     const char* txt, Int_t width,
310                                                     Int_t lo, Int_t ro, Int_t to, Int_t bo)
311 {
312   // Create a standard button.
313   // If width is not zero, the fixed-width flag is set.
314
315   TGTextButton* b = new TGTextButton(p, txt);
316   if (width > 0) {
317     b->SetWidth(width);
318     b->ChangeOptions(b->GetOptions() | kFixedWidth);
319   }
320   p->AddFrame(b, new TGLayoutHints(kLHintsNormal, lo,ro,to,bo));
321   return b;
322 }
323
324 //______________________________________________________________________________
325 TGLabel* AliEveEventManagerWindow::MkLabel(TGCompositeFrame* p,
326                                            const char* txt, Int_t width,
327                                            Int_t lo, Int_t ro, Int_t to, Int_t bo)
328 {
329   // Create a standard button.
330   // If width is not zero, the fixed-width flag is set.
331
332   TGLabel* l = new TGLabel(p, txt);
333   if (width > 0) {
334     l->SetWidth(width);
335     l->ChangeOptions(l->GetOptions() | kFixedWidth);
336   }
337   p->AddFrame(l, new TGLayoutHints(kLHintsNormal, lo,ro,to,bo));
338   return l;
339 }
340