Remove obsolete comments about TTree::Refresh() not working.
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveMacroExecutorWindow.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 "AliEveMacroExecutorWindow.h"
11 #include "AliEveMacroExecutor.h"
12 #include "AliEveMacro.h"
13 #include "AliEveEventManager.h"
14
15 #include <TGedEditor.h>
16 #include <TGLabel.h>
17 #include <TGListBox.h>
18 #include <TGTextEntry.h>
19 #include <Buttons.h>
20
21 #include <TPRegexp.h>
22
23 class AliEveMEWListBox : public TGListBox
24 {
25 public:
26   AliEveMEWListBox(const TGWindow* p = 0, Int_t id = -1) : TGListBox(p, id)
27   {
28     if (gfGC == 0)
29     {
30       const TGGC& old = TGTextLBEntry::GetDefaultGC();
31
32       gfFont = gClient->GetFontPool()->GetFont("-*-lucidatypewriter-*-*-*-*-12-*-*-*-*-*-iso8859-1");
33       gfGC   = gClient->GetGCPool()->GetGC((GCValues_t*) old.GetAttributes(), kTRUE);
34       gfGC->SetFont(gVirtualX->GetFontHandle(gfFont->GetFontStruct()));
35     }
36   }
37
38   using TGListBox::AddEntry;
39   virtual void AddEntry(const char* s, Int_t id)
40   {
41     static const Pixel_t gkBackground[] = { 0x00ffffff, 0xf5f7f8 };
42
43     TGTextLBEntry *lbe = new TGTextLBEntry(fLbc, new TGString(s), id,
44                                            gfGC->GetGC(), gfFont->GetFontStruct());
45     fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
46     fLbc->AddEntry(lbe, new TGLayoutHints(kLHintsExpandX | kLHintsTop));
47     // Need to set it here as the above line sets it to white (for some strange reason).
48     lbe->SetBackgroundColor(gkBackground[id%2]);
49   }
50
51 protected:
52   static TGGC    *gfGC;
53   static TGFont  *gfFont;
54
55 private:
56   AliEveMEWListBox(const AliEveMEWListBox&);            // Not implemented
57   AliEveMEWListBox& operator=(const AliEveMEWListBox&); // Not implemented
58 };
59
60 TGGC   *AliEveMEWListBox::gfGC   = 0;
61 TGFont *AliEveMEWListBox::gfFont = 0;
62
63
64 class AliEveMEWEditor : public TGedEditor
65 {
66 public:
67   AliEveMEWEditor(AliEveMacroExecutorWindow* w) : TGedEditor(0), fMEW(w) {}
68   virtual ~AliEveMEWEditor() {}
69   virtual void Update(TGedFrame* gframe=0)
70   {
71     TGedEditor::Update(gframe);
72     fMEW->PopulateMacros();
73   }
74   virtual void Refresh()
75   {
76     SetModel(fPad, fModel, kButton1Down);
77   }
78 protected:
79   AliEveMacroExecutorWindow* fMEW;
80 private:
81   AliEveMEWEditor(const AliEveMEWEditor&);            // Not implemented
82   AliEveMEWEditor& operator=(const AliEveMEWEditor&); // Not implemented
83 };
84
85 //______________________________________________________________________________
86 // Full description of AliEveMacroExecutorWindow
87 //
88
89 ClassImp(AliEveMacroExecutorWindow)
90
91 //______________________________________________________________________________
92 AliEveMacroExecutorWindow::AliEveMacroExecutorWindow(AliEveMacroExecutor* master) :
93   TGMainFrame(gClient->GetRoot()), fM(master),
94   fMainFrame(0), fCtrlFrame(0), fListBox(0), fEditor(0),
95   fSelectTags(0),
96   fBoxContents()
97 {
98   // Constructor.
99
100   fMainFrame = new TGVerticalFrame(this);
101   AddFrame(fMainFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
102
103   // TGHorizontalFrame *f = 0;
104   TGButton          *b = 0;
105   {
106     fCtrlFrame = MkHFrame(fMainFrame);
107     fCtrlFrame->Resize(400, 22);
108
109     b = new TGTextButton(fCtrlFrame, "Reload event");
110     fCtrlFrame->AddFrame(b);
111     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
112                "DoReloadEvent()");
113
114     MkLabel(fCtrlFrame, "Select: ", 48);
115     fSelectTags = new TGTextEntry(fCtrlFrame);
116     fCtrlFrame->AddFrame(fSelectTags, new TGLayoutHints(kLHintsNormal));//|kLHintsExpandX));
117     fSelectTags->Connect("ReturnPressed()", "AliEveMacroExecutorWindow", this,
118                          "DoSelectTags()");
119     b = new TGTextButton(fCtrlFrame, "Select");
120     fCtrlFrame->AddFrame(b);
121     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
122                "DoSelectTags()");
123
124     b = new TGTextButton(fCtrlFrame, "Enable all");
125     fCtrlFrame->AddFrame(b);
126     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
127                "DoEnableAll()");
128
129     b = new TGTextButton(fCtrlFrame, "Disable all");
130     fCtrlFrame->AddFrame(b);
131     b->Connect("Clicked()", "AliEveMacroExecutorWindow", this,
132                "DoDisableAll()");
133   }
134
135   fListBox = new AliEveMEWListBox(fMainFrame);
136   fMainFrame->AddFrame(fListBox, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
137   fListBox->Resize(400, 400);
138   fListBox->Connect("Selected(Int_t)", "AliEveMacroExecutorWindow", this,
139                     "DoMacroSelected(Int_t)");
140
141   fMainFrame->SetEditDisabled(kEditEnable);
142   fMainFrame->SetEditable();
143   fEditor = new AliEveMEWEditor(this);
144   fEditor->SetGlobal(kFALSE);
145   fMainFrame->SetEditable(kEditDisable);
146   fMainFrame->SetEditable(kFALSE);
147   {
148     TGFrameElement *el = 0;
149     TIter next(fMainFrame->GetList());
150     while ((el = (TGFrameElement *) next())) {
151       if (el->fFrame == fEditor)
152         if (el->fLayout) {
153           el->fLayout->SetLayoutHints(kLHintsExpandX);
154           el->fLayout->SetPadLeft(1); el->fLayout->SetPadRight(1);
155           el->fLayout->SetPadTop(2);  el->fLayout->SetPadBottom(2);
156           break;
157         }
158     }
159   }
160   fEditor->Resize(400, 150);
161   fEditor->ChangeOptions(fEditor->GetOptions() | kFixedHeight);
162
163   Resize(400, 700);
164
165   SetCleanup(kDeepCleanup);
166   Layout();
167   MapSubwindows();
168   MapWindow();
169
170   AliEveEventManager::GetMaster()->Connect("NewEventLoaded()", "AliEveMacroExecutorWindow", this,
171                         "NewEventLoaded()");
172 }
173
174 AliEveMacroExecutorWindow::~AliEveMacroExecutorWindow()
175 {
176   // Destructor.
177
178   AliEveEventManager::GetMaster()->Disconnect("NewEventLoaded()", this);
179 }
180
181 /******************************************************************************/
182
183 void AliEveMacroExecutorWindow::PopulateMacros(Bool_t keep_selected)
184 {
185   // Populate list-box (or whatever will replace it) with all macros.
186   // prototype: no selection, sorting
187
188   // printf("AliEveMacroExecutorWindow::PopulateMacros()\n");
189
190   AliEveMacro* ex_sel = 0;
191   if (keep_selected && fListBox->GetSelected() != -1)
192     ex_sel = fBoxContents[fListBox->GetSelected()];
193
194   fListBox->RemoveAll();
195   fBoxContents.clear();
196
197   TPMERegexp *regexp = 0;
198   TString     select = fSelectTags->GetText();
199   if ( ! select.IsNull())
200   {
201     regexp = new TPMERegexp(select, "io");
202   }
203
204   TIter next(fM->fMacros);
205   AliEveMacro *mac;
206   Int_t        id =  0;
207   Int_t    sel_id = -1;
208   while ((mac = (AliEveMacro*) next()))
209   {
210     if (regexp && regexp->Match(mac->GetTags()) == 0)
211       continue;
212     if (mac == ex_sel)
213       sel_id = id;
214
215     fListBox->AddEntry(mac->FormForDisplay(), id++);
216     fBoxContents.push_back(mac);
217   }
218
219   if (sel_id != -1)
220     fListBox->Select(sel_id);
221
222   fListBox->MapSubwindows();
223   fListBox->Layout();
224 }
225
226 void AliEveMacroExecutorWindow::SetActiveStateOfShownMacros(Bool_t active)
227 {
228   // Set active-state of all shown macros to active.
229   // Automatically refreshes the list and editor.
230
231   for (std::vector<AliEveMacro*>::iterator m = fBoxContents.begin(); m != fBoxContents.end(); ++m)
232     (*m)->SetActive(active);
233   PopulateMacros();
234   fEditor->Refresh();
235 }
236
237 /******************************************************************************/
238
239 void AliEveMacroExecutorWindow::NewEventLoaded()
240 {
241   // Slot called after a new event has been loaded
242
243   // !!! Once we have exit status from the macro, can update GUI showing this.
244 }
245
246 void AliEveMacroExecutorWindow::DoReloadEvent()
247 {
248   // Slot for reload-event.
249
250   AliEveEventManager::GetMaster()->GotoEvent(AliEveEventManager::GetMaster()->GetEventId());
251 }
252
253 void AliEveMacroExecutorWindow::DoSelectTags()
254 {
255   // Slot for select-tags.
256
257   PopulateMacros();
258 }
259
260 void AliEveMacroExecutorWindow::DoMacroSelected(Int_t mid)
261 {
262   // Slot for macro-selected.
263
264   fEditor->SetModel(0, fBoxContents[mid], kButton1Down);
265 }
266
267 /******************************************************************************/
268
269 TGHorizontalFrame* AliEveMacroExecutorWindow::MkHFrame(TGCompositeFrame* p)
270 {
271   // Make standard horizontal frame.
272
273   if (p == 0)
274     p = this;
275   TGHorizontalFrame* f = new TGHorizontalFrame(p);
276   p->AddFrame(f, new TGLayoutHints(kLHintsNormal|kLHintsExpandX));
277   return f;
278 }
279
280 TGLabel* AliEveMacroExecutorWindow::MkLabel(TGCompositeFrame* p, const char* txt, Int_t width,
281                                             Int_t lo, Int_t ro, Int_t to, Int_t bo)
282 {
283   // Make standard label.
284
285   TGLabel *l = new TGLabel(p, txt);
286   p->AddFrame(l, new TGLayoutHints(kLHintsNormal, lo,ro,to,bo));
287   l->SetTextJustify(kTextRight);
288   l->SetWidth(width);
289   l->ChangeOptions(l->GetOptions() | kFixedWidth);
290   return l;
291 }