First big commit of the mchview program and its accompanying library,
[u/mrichter/AliRoot.git] / MUON / AliMUONPainterMasterFrame.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 // $Id$
17
18 #include "AliMUONPainterMasterFrame.h"
19
20 #include "AliMUONChamberPainter.h"
21 #include "AliMUONPainterGroup.h"
22 #include "AliMUONPainterMatrix.h"
23 #include "AliMUONPainterMatrixFrame.h"
24 #include "AliMUONPainterInterfaceHelper.h"
25 #include "AliMUONPainterRegistry.h"
26 #include "AliMUONAttPainterSelectorFrame.h"
27 #include "AliMUONVPainter.h"
28 #include "AliCodeTimer.h"
29 #include "AliLog.h"
30 #include <Riostream.h>
31 #include <TApplication.h>
32 #include <TCanvas.h>
33 #include <TEnv.h>
34 #include <TGComboBox.h>
35 #include <TGLabel.h>
36 #include <TObjArray.h>
37 #include <TObjString.h>
38 #include <TGButtonGroup.h>
39 #include <TGMsgBox.h>
40
41 /// \class AliMUONPainterMasterFrame
42 ///
43 /// Main window of the 2D display
44 ///
45 /// \author Laurent Aphecetche, Subatech
46
47 ///\cond CLASSIMP
48 ClassImp(AliMUONPainterMasterFrame)
49 ///\endcond
50
51 namespace
52 {
53   UInt_t UniqueID(Int_t nx, Int_t ny)
54   {
55     return ny | (nx << 8);
56   }
57   
58   Int_t Nx(UInt_t uniqueID)
59   {
60     return ( uniqueID & 0xFF00 ) >> 8;
61   }
62
63   Int_t Ny(UInt_t uniqueID)
64   {
65     return uniqueID & 0xFF;
66   }
67
68 }
69
70 const Int_t AliMUONPainterMasterFrame::fgkBorderSize = 10;
71
72 //_____________________________________________________________________________
73 AliMUONPainterMasterFrame::AliMUONPainterMasterFrame(const TGWindow* p, 
74                                                      UInt_t w, UInt_t h)
75 : TGCompositeFrame(p,w,h,kVerticalFrame),
76   fNavigationFrame(0x0),
77   fPainterMatrixFrame(0x0),
78   fBackButton(0x0),
79   fForwardButton(0x0),
80   fGroupTitle(0x0),
81   fNavigation(),
82   fCurrentNavigationPosition(-1),
83   fAttPainterSelectorFrame(0x0)
84 {  
85   /// ctor
86     
87   UInt_t wi = w - fgkBorderSize*2;
88   UInt_t hi = h - fgkBorderSize*3;
89   
90   fNavigationFrame = new TGHorizontalFrame(this,wi);
91   
92   AddFrame(fNavigationFrame,new TGLayoutHints(kLHintsExpandX|kLHintsTop,
93                                               fgkBorderSize,fgkBorderSize,
94                                               fgkBorderSize,fgkBorderSize));
95     
96   fBackButton = new TGPictureButton(fNavigationFrame,
97                                        gClient->GetPicture("tb_back.xpm"));
98   
99   fForwardButton = new TGPictureButton(fNavigationFrame,
100                                        gClient->GetPicture("tb_forw.xpm"));
101
102   fAttPainterSelectorFrame = new AliMUONAttPainterSelectorFrame(fNavigationFrame,w/2,20);
103   
104   fGroupTitle = new TGLabel(fNavigationFrame,"");
105   
106   fNavigationFrame->AddFrame(fBackButton,new TGLayoutHints(kLHintsCenterY));
107   fNavigationFrame->AddFrame(fForwardButton,new TGLayoutHints(kLHintsCenterY));
108   
109   fNavigationFrame->AddFrame(fAttPainterSelectorFrame,new TGLayoutHints(kLHintsCenterY,10));
110   
111   fAttPainterSelectorFrame->Connect("Clicked(AliMUONAttPainter*)",
112                                     "AliMUONPainterMasterFrame",
113                                     this,
114                                     "AttributesChanged(AliMUONAttPainter*)");
115   
116   fNavigationFrame->AddFrame(fGroupTitle,new TGLayoutHints(kLHintsExpandX|kLHintsCenterX|kLHintsCenterY,10));
117   
118   fForwardButton->Connect("Clicked()","AliMUONPainterMasterFrame",
119                           this,
120                           "Forward()");
121
122   fBackButton->Connect("Clicked()","AliMUONPainterMasterFrame",
123                           this,
124                           "Backward()");
125     
126   
127                                                                    
128   UInt_t w1 = wi;
129   UInt_t h1 = hi - fNavigationFrame->GetHeight() - 3*fgkBorderSize;
130   
131   MakeTopPainterMatrix(w1,h1);
132
133   AddFrame(fPainterMatrixFrame,new TGLayoutHints(kLHintsExpandX,
134                                                 fgkBorderSize,fgkBorderSize,
135                                                 0,fgkBorderSize));
136   
137   AliMUONPainterInterfaceHelper::SetBackgroundColor("MasterFrame.Navigation",*fNavigationFrame);
138   AliMUONPainterInterfaceHelper::SetBackgroundColor("MasterFrame.Main",*this);
139   
140   AliDebug(1,Form("fNavigation=%p",&fNavigation));
141   
142   AliMUONPainterRegistry::Instance()->Connect("PainterMatrixWantToShow(AliMUONPainterMatrix*)",
143                                               "AliMUONPainterMasterFrame",
144                                               this,
145                                               "PainterMatrixWantToShow(AliMUONPainterMatrix*)");
146   
147   fPainterMatrixFrame->DataSourceWasChanged("*",0x0,-1);
148 }
149
150 //_____________________________________________________________________________
151 AliMUONPainterMasterFrame::~AliMUONPainterMasterFrame()
152 {
153   /// dtor
154   Cleanup();
155 }
156
157 //_____________________________________________________________________________
158 void
159 AliMUONPainterMasterFrame::AddPainterMatrix(AliMUONPainterMatrix* painterMatrix)
160 {
161   /// array is adopted (by the registry)
162
163   AliDebug(1,Form("matrix=%x %s",painterMatrix,painterMatrix->GetName()));
164   
165   Int_t i = AliMUONPainterRegistry::Instance()->Register(painterMatrix);
166
167   SetNavigation(i);
168 }
169
170 //_____________________________________________________________________________
171 void
172 AliMUONPainterMasterFrame::PainterMatrixWantToShow(AliMUONPainterMatrix* group)
173 {
174   // FIXME: should check whether we are the active window before
175   // responding to this message
176
177   AliDebug(1,Form("group=%x %s",group,group->GetName()));
178   
179   Int_t i = AliMUONPainterRegistry::Instance()->FindIndexOf(group);
180
181   Int_t alreadyThere(-1);
182   
183   for ( Int_t j = 0; j < fNavigation.GetSize(); ++j )
184   {
185     if ( fNavigation[j] == i ) alreadyThere = j;
186   }
187   
188   if (alreadyThere<0) 
189   {
190     SetNavigation(i);
191   }
192   else
193   {
194     fCurrentNavigationPosition = alreadyThere;
195   }
196   
197   ShowPainterMatrix(group);  
198 }
199                                                 
200 //_____________________________________________________________________________
201 void
202 AliMUONPainterMasterFrame::SetNavigation(Int_t i)
203 {
204   /// Change navigation position
205   
206   ++fCurrentNavigationPosition;
207   fNavigation.Set(fCurrentNavigationPosition+1);
208   fNavigation[fCurrentNavigationPosition] = i;
209 }
210
211 //_____________________________________________________________________________
212 void
213 AliMUONPainterMasterFrame::ShowPainterMatrix(AliMUONPainterMatrix* painterMatrix)
214 {
215   /// Change the painter matrix we show
216   
217   fPainterMatrixFrame->Use(painterMatrix);
218   
219   painterMatrix->Connect("Clicked(AliMUONVPainter*,Double_t*)",
220                          "AliMUONPainterMasterFrame",this,
221                          "Clicked(AliMUONVPainter*,Double_t*)");
222
223   painterMatrix->Connect("ShiftClicked(AliMUONVPainter*,Double_t*)",
224                          "AliMUONPainterMasterFrame",this,
225                          "ShiftClicked(AliMUONVPainter*,Double_t*)");
226   
227   fPainterMatrixFrame->Connect("TitleHasChanged(const char*)",
228                               "AliMUONPainterMasterFrame",this,
229                               "ChangeTitle(const char*)");
230   UpdateNavigation();
231   
232   UpdateAttributes(*(fPainterMatrixFrame->Matrix()));
233   
234   AliMUONPainterRegistry::Instance()->AddToHistory(painterMatrix);
235   
236   Layout();
237 }
238
239 //_____________________________________________________________________________
240 void
241 AliMUONPainterMasterFrame::ChangeTitle(const char* newTitle)
242 {
243   /// Change the top title
244   
245   fGroupTitle->SetText(newTitle);
246   fGroupTitle->Resize();
247   Layout();
248 }
249
250 //_____________________________________________________________________________
251 void
252 AliMUONPainterMasterFrame::Backward()
253 {
254   /// Move back one step in the history
255   --fCurrentNavigationPosition;
256   
257   AliMUONPainterMatrix* group = 
258     AliMUONPainterRegistry::Instance()->PainterMatrix(fNavigation[fCurrentNavigationPosition]);
259   
260   ShowPainterMatrix(group);
261   
262   UpdateNavigation();
263 }
264
265 //_____________________________________________________________________________
266 void
267 AliMUONPainterMasterFrame::Forward()
268 {
269   /// Move forward one step in history
270   
271   ++fCurrentNavigationPosition;
272   
273   AliMUONPainterMatrix* group = 
274     AliMUONPainterRegistry::Instance()->PainterMatrix(fNavigation[fCurrentNavigationPosition]);
275   
276   ShowPainterMatrix(group);
277   
278   UpdateNavigation();
279 }
280
281 //_____________________________________________________________________________
282 void 
283 AliMUONPainterMasterFrame::Clicked(AliMUONVPainter* painter, Double_t* values)
284 {
285   /// A given painter was (singly) clicked
286   
287   AliDebug(1,Form("%s x %7.3f y %7.3f",painter->GetName(),values[0],values[1]));
288
289   AliCodeTimerAuto("")
290   
291   fPainterMatrixFrame->MouseLeave(painter);
292   
293   AliMUONPainterMatrix* matrix = new AliMUONPainterMatrix(painter->Name().Data());
294
295   AliMUONVPainter* p = painter->Detach();
296
297   p->SetResponder(1);
298
299   matrix->Adopt(p);
300   
301   AddPainterMatrix(matrix);
302   ShowPainterMatrix(matrix);
303 }
304
305 //_____________________________________________________________________________
306 void 
307 AliMUONPainterMasterFrame::ShiftClicked(AliMUONVPainter* painter, Double_t*)
308 {
309   /// A given painter was shift-clicked
310   
311   AliMUONPainterMatrix* currentMatrix = fPainterMatrixFrame->Matrix();
312   
313   AliMUONAttPainter a = painter->Attributes();
314   
315   TString basename(Form("%s-DUAL",painter->GetName()));
316   
317   TString newName = AliMUONPainterMatrix::NameIt(basename.Data(),a);
318   
319   AliMUONPainterMatrix* matrix = 
320     AliMUONPainterRegistry::Instance()->FindPainterMatrix(newName.Data());
321   
322   if (!matrix)
323   {
324     // No. So we must make a new matrix painter from the existing one,
325     // and add to this new matrix the painters of the other one, but
326     // using the new attributes...
327     
328     // create "opposite" attributes
329     AliMUONAttPainter a1(a);
330     AliMUONAttPainter a2(a);
331     
332     if ( a.IsCathodeDefined() ) 
333     {
334       a2.SetCathode(!a.IsCathode0(),!a.IsCathode1());
335     }
336     
337     if ( a.IsPlaneDefined() ) 
338     {
339       a2.SetPlane(!a.IsBendingPlane(),!a.IsNonBendingPlane());
340     }
341     
342     a1.SetCathodeAndPlaneDisabled(kTRUE);
343     a2.SetCathodeAndPlaneDisabled(kTRUE);
344
345     AliMUONVPainter* p1 = AliMUONVPainter::CreatePainter(painter->ClassName(),
346                                                          a1,
347                                                          painter->ID0(),
348                                                          painter->ID1());
349     
350     AliMUONVPainter* p2 = AliMUONVPainter::CreatePainter(painter->ClassName(),
351                                                         a2,
352                                                         painter->ID0(),
353                                                         painter->ID1());
354     
355     if (!p1 || !p2)
356     {
357       Int_t ret;
358       new TGMsgBox(gClient->GetRoot(), this,
359                    "Invalid combination", "Cannot create 2 views from this painter",
360                    kMBIconExclamation, kMBOk, &ret);
361       PainterMatrixWantToShow(currentMatrix);
362       delete p1;
363       delete p2;
364       return;
365     }
366     
367     AliInfo(Form("Starting from %s will generate %s and %s",
368                  a.GetName(),
369                  a1.GetName(),
370                  a2.GetName()));
371     
372     p1->UpdateGroupsFrom(*(painter->Master()));
373     p2->UpdateGroupsFrom(*(painter->Master()));
374     
375     p1->SetResponder(1);
376     p2->SetResponder(1);
377     
378     Int_t nx(2);
379     Int_t ny(1);
380     
381     AliMpArea area(painter->Area());
382
383     if ( area.Dimensions().X() > 1.2*area.Dimensions().Y() ) 
384     {
385       nx = 1;
386       ny = 2;
387     }
388     
389     matrix = new AliMUONPainterMatrix(basename.Data(),nx,ny);
390     
391     matrix->Adopt(p1);
392     matrix->Adopt(p2);
393     
394     AddPainterMatrix(matrix);
395   }
396   
397   matrix->SetData(currentMatrix->DataPattern(),
398                   currentMatrix->Data(),
399                   currentMatrix->DataIndex());
400   
401   fPainterMatrixFrame->MouseLeave(painter);
402   
403   PainterMatrixWantToShow(matrix);
404 }
405
406 //_____________________________________________________________________________
407 void
408 AliMUONPainterMasterFrame::Update()
409 {
410   /// Update ourselves
411   
412   fPainterMatrixFrame->Update();
413 }
414
415 //_____________________________________________________________________________
416 void
417 AliMUONPainterMasterFrame::UpdateAttributes(const AliMUONPainterMatrix& painterMatrix)
418 {
419   /// Update the view buttons from the matrix we actually plot
420   
421   fAttPainterSelectorFrame->Update(painterMatrix.Attributes());
422 }
423
424 //_____________________________________________________________________________
425 void
426 AliMUONPainterMasterFrame::MakeTopPainterMatrix(UInt_t w, UInt_t h)
427 {
428   /// Create the first painter matrix that appears when we are create
429   /// FIXME: how to make this more flexible ?
430   
431   fPainterMatrixFrame = new AliMUONPainterMatrixFrame(this,w,h);
432
433   AliMUONAttPainter att;
434   
435   att.SetCathode(kTRUE,kFALSE);
436   att.SetViewPoint(kTRUE,kFALSE);
437     
438   TString name = AliMUONPainterMatrix::NameIt("Tracker",att);
439   
440   AliMUONPainterMatrix* painterMatrix = AliMUONPainterRegistry::Instance()->FindPainterMatrix(name);
441   
442   if (!painterMatrix)
443   {
444     AliError(Form("Could not get pre-defined painter matrix %s : check that !",name.Data()));
445   }
446   else
447   {
448     PainterMatrixWantToShow(painterMatrix);
449 //    fPainterMatrixFrame->Use(painterMatrix);
450 //    ShowPainterMatrix(painterMatrix);
451   }
452 }
453
454 //_____________________________________________________________________________
455 void
456 AliMUONPainterMasterFrame::UpdateNavigation()
457 {
458   /// Update navigation frame
459
460   fBackButton->SetEnabled(kTRUE);
461   fForwardButton->SetEnabled(kTRUE);
462
463   if ( fCurrentNavigationPosition == 0 ) 
464   {
465     fBackButton->SetEnabled(kFALSE);
466   }
467   if ( fCurrentNavigationPosition == fNavigation.GetSize()-1 ) 
468   {
469     fForwardButton->SetEnabled(kFALSE);
470   }
471 }
472
473 //_____________________________________________________________________________
474 void
475 AliMUONPainterMasterFrame::AttributesChanged(AliMUONAttPainter* newValues)
476 {
477   /// Attributes changed (e.g. from cath0 to cath1 or bending to nonbending, etc...)
478   
479   AliMUONPainterMatrix* currentMatrix = fPainterMatrixFrame->Matrix();
480   
481   AliMUONAttPainter a = currentMatrix->Validate(*newValues);
482   
483   if (!a.IsValid())
484   {
485     Int_t ret;
486     new TGMsgBox(gClient->GetRoot(), this,
487                  "Invalid combination", "Change of attributes not possible for this object",
488                  kMBIconExclamation, kMBOk, &ret);
489     PainterMatrixWantToShow(currentMatrix);
490     return;
491   }
492   
493   // First check if we already have this matrix available
494   
495   TString newName = AliMUONPainterMatrix::NameIt(currentMatrix->Basename(),a);
496   
497   AliMUONPainterMatrix* matrix = 
498     AliMUONPainterRegistry::Instance()->FindPainterMatrix(newName.Data());
499
500   if (!matrix)
501   {
502     // No. So we must make a new matrix painter from the existing one,
503     // and add to this new matrix the painters of the other one, but
504     // using the new attributes...
505     
506     matrix = currentMatrix->Clone(a);
507   
508     AddPainterMatrix(matrix);
509   }
510   
511   matrix->SetData(currentMatrix->DataPattern(),
512                   currentMatrix->Data(),
513                   currentMatrix->DataIndex());
514   
515   PainterMatrixWantToShow(matrix);
516 }