PMD module
[u/mrichter/AliRoot.git] / MUON / MUONgraphics / AliMUONPainterPlotSelector.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 /// \class AliMUONPainterPlotSelector
19 /// 
20 /// Widget to select which data to plot for painters
21 /// 
22 /// \author Laurent Aphecetche
23 ///
24 /// See AliMUONPainterInterfaceHelper for an important implementation note
25 /// about our use of TGButtonGroup
26 ///
27
28 #include "AliMUONPainterPlotSelector.h"
29
30 #include "AliMUONPainterGroup.h"
31 #include "AliMUONPainterInterfaceHelper.h"
32 #include "AliMUONPainterMatrix.h"
33 #include "AliMUONPainterDataRegistry.h"
34 #include "AliMUONVPainter.h"
35 #include "AliMUONVTrackerData.h"
36 #include "AliLog.h"
37 #include <Riostream.h>
38 #include <TGButton.h>
39 #include <TGButtonGroup.h>
40 #include <TObjArray.h>
41 #include <TObjString.h>
42
43 ///\cond CLASSIMP
44 ClassImp(AliMUONPainterPlotSelector)
45 ///\endcond
46
47 const char* AliMUONPainterPlotSelector::fgkDefaultSourceName = "none";  
48
49 //_____________________________________________________________________________
50 AliMUONPainterPlotSelector::AliMUONPainterPlotSelector(const TGWindow* window, UInt_t w, UInt_t h)
51 : TGCompositeFrame(window,w,h,kHorizontalFrame),
52 fTypes(0x0),
53 fDataSourceNames(0x0),
54 fDataSourceDimensions(0x0),
55 fDimensionButtonMap(new TMap),
56 fCurrentType(""),
57 fCurrentData(0x0),
58 fCurrentDimension(-1)
59 {
60   /// ctor
61   fTypes = new TGButtonGroup(this,"Plot");
62
63   fDataSourceNames = new TGButtonGroup(this,"Sources");
64       
65   AliMUONPainterDataRegistry* reg = AliMUONPainterDataRegistry::Instance();
66   
67   reg->Connect("DataSourceWasRegistered(AliMUONVTrackerData*)",
68                "AliMUONPainterPlotSelector",
69                this,
70                "DataSourceWasRegistered(AliMUONVTrackerData*)");
71   
72   reg->Connect("DataSourceWasUnregistered(AliMUONVTrackerData*)",
73                "AliMUONPainterPlotSelector",
74                this,
75                "DataSourceWasUnregistered(AliMUONVTrackerData*)");
76     
77   AliMUONPainterInterfaceHelper::AddRadioButton(*fDataSourceNames,
78                                                 fgkDefaultSourceName,
79                                                 0x0,
80                                                 kTRUE);
81   
82   CreateDimensionButtons(fgkDefaultSourceName);
83   
84   fDataSourceDimensions = new TGButtonGroup(this,0,3,5,0,"Dimensions");
85   
86   for ( Int_t i = 0; i < reg->NumberOfDataSources(); ++i )
87   {
88     AliMUONVTrackerData* data = reg->DataSource(i);
89     DataSourceWasRegistered(data);
90   }
91   
92   fDataSourceNames->Connect("Clicked(Int_t)","AliMUONPainterPlotSelector",
93                             this,
94                             "SourceButtonWasClicked(Int_t)");
95
96   AddFrame(fTypes);
97   AddFrame(fDataSourceNames);
98   AddFrame(fDataSourceDimensions);
99 }
100
101 //_____________________________________________________________________________
102 AliMUONPainterPlotSelector::~AliMUONPainterPlotSelector()
103 {
104   /// dtor
105 }
106
107 //_____________________________________________________________________________
108 void
109 AliMUONPainterPlotSelector::BackupDimensionButtons()
110 {
111   /// Backup the dimension button group
112   
113   TString name = fDataSourceDimensions->GetTitle();
114
115   AliDebug(1,Form("name %s",name.Data()));
116
117   if ( name !=  fgkDefaultSourceName )
118   {
119     TGButtonGroup* group = static_cast<TGButtonGroup*>(fDimensionButtonMap->GetValue(name));
120     if (!group) 
121     {
122       AliError(Form("Did not find group %s",name.Data()));
123     }
124     else
125     {
126       AliMUONPainterInterfaceHelper::Copy(*fDataSourceDimensions,*group);
127     }
128   
129   }
130   
131   fDataSourceDimensions->Disconnect("Clicked(Int_t)",
132                                     this,
133                                     "DimensionButtonWasClicked(Int_t)");  
134 }
135
136
137 //_____________________________________________________________________________
138 void
139 AliMUONPainterPlotSelector::CreateDimensionButtons(const char* dataSourceName)
140 {
141   /// Create the dimension button group for a given data source
142   
143   AliDebug(1,Form("Creating dimension buttons for dataSource %s",dataSourceName));
144   
145   AliMUONVTrackerData* data = AliMUONPainterDataRegistry::Instance()->DataSource(dataSourceName);
146
147   TGButtonGroup* bg = new TGButtonGroup(this,0,3,5,0,dataSourceName);
148   
149   if ( data ) 
150   {
151     for ( Int_t i = 0; i < data->NumberOfDimensions(); ++i ) 
152     {
153       AliMUONPainterInterfaceHelper::AddRadioButton(*bg,
154                                                     data->DimensionName(i),
155                                                     reinterpret_cast<void*>(i));
156     }
157   }
158   
159   fDimensionButtonMap->Add(new TObjString(dataSourceName),bg);
160   
161   AliDebug(1,Form("bg is %p Count=%d",bg,bg->GetCount()));
162   StdoutToAliDebug(1,AliMUONPainterInterfaceHelper::Dump(*bg));
163   
164   bg->Connect("Clicked(Int_t)","AliMUONPainterPlotSelector",this,
165                                 "DimensionButtonWasClicked(Int_t)");
166 }
167
168 //_____________________________________________________________________________
169 void
170 AliMUONPainterPlotSelector::CreateTypeButtons(const TObjArray& types)
171 {
172   /// Create the type button group
173   
174   AliMUONPainterInterfaceHelper::ClearButtons(*fTypes);
175
176   TIter nextType(&types);
177   TObjString* str;
178
179   while ( ( str = static_cast<TObjString*>(nextType()) ) )
180   {
181     AliMUONPainterInterfaceHelper::AddRadioButton(*fTypes,str->String());
182   }
183
184   fTypes->Connect("Clicked(Int_t)","AliMUONPainterPlotSelector",this,
185                   "TypeButtonWasClicked(Int_t)");
186   
187   fTypes->Show();
188 }
189
190 //_____________________________________________________________________________
191 void
192 AliMUONPainterPlotSelector::DataSourceWasChanged()
193 {
194   /// Data source was changed
195   DataSourceWasChanged(fCurrentType.Data(),fCurrentData,fCurrentDimension);
196 }
197
198 //_____________________________________________________________________________
199 void 
200 AliMUONPainterPlotSelector::DataSourceWasChanged(const char* type, 
201                                                  AliMUONVTrackerData* data,
202                                                  Int_t dataIndex)
203 {
204   /// Emit a signal to tell data source was changed
205   AliDebug(1,Form("type=%s data=%s (%s)",
206                   type,
207                   ( data ? data->GetName() : "" ),
208                   ( ( data && dataIndex >= 0 ) ? data->DimensionName(dataIndex).Data() :
209                     "")));
210   
211         UpdateTypeButton();
212         
213   Long_t param[] = { (Long_t)type, (Long_t)data,
214     (Long_t)dataIndex };
215   
216   Emit("DataSourceWasChanged(const char*,AliMUONVTrackerData*,Int_t)",param);
217 }
218
219 //_____________________________________________________________________________
220 void
221 AliMUONPainterPlotSelector::DataSourceWasRegistered(AliMUONVTrackerData* data)
222 {
223   /// A new data source has been registered : add it to the interface
224   
225   AliDebug(1,Form("Registering %s",data->GetName()));
226   
227   AliMUONPainterInterfaceHelper::AddRadioButton(*fDataSourceNames,
228                                                 data->GetName(),
229                                                 data);
230   
231   data->Connect("NumberOfEventsChanged()",
232                 "AliMUONPainterPlotSelector",
233                 this,
234                 "NumberOfEventsChanged()");
235   
236   CreateDimensionButtons(data->GetName());
237   
238   fDataSourceNames->Show();
239   
240   Layout();
241 }
242
243 //_____________________________________________________________________________
244 void
245 AliMUONPainterPlotSelector::NumberOfEventsChanged()
246 {
247   /// Change the tool tip of the corresponding data source button
248
249   // find first the sender of the signal
250   
251 //  AliMUONVTrackerData* data = reinterpret_cast<AliMUONVTrackerData*>(gTQSender);
252 //  
253 //  TGButton* button = AliMUONPainterInterfaceHelper::FindButtonByUserData(*fDataSourceNames,data);
254 //  
255 //  if (button)
256 //  {
257 //    button->SetToolTipText(Form("%d events",data->NumberOfEvents()),250);
258 //  }
259 }
260
261 //_____________________________________________________________________________
262 void
263 AliMUONPainterPlotSelector::DataSourceWasUnregistered(AliMUONVTrackerData* data)
264 {
265   /// A data source has been unregistered : remove it from the interface
266   
267   TGButton* button = AliMUONPainterInterfaceHelper::FindButtonByUserData(*fDataSourceNames,data);
268
269   TGButton* bd = AliMUONPainterInterfaceHelper::FindDownButton(*fDataSourceNames);
270
271   if ( bd == button ) 
272   {
273     // selected data source is the one we are removing...
274     // revert to "none" before actually removing it.
275     SourceButtonWasClicked(1);
276   }
277   
278   AliMUONPainterInterfaceHelper::RemoveButton(*fDataSourceNames,button);
279
280   // do not forget to re-connect things
281   fDataSourceNames->Connect("Clicked(Int_t)","AliMUONPainterPlotSelector",
282                             this,
283                             "SourceButtonWasClicked(Int_t)");
284   
285
286   TObject* o = fDimensionButtonMap->Remove(new TObjString(data->GetName()));
287   
288   if (!o)
289   {
290     AliError("Remove failed. Please check");    
291   }
292
293   fDataSourceNames->Show();
294   
295   Layout();
296 }
297
298 //_____________________________________________________________________________
299 void 
300 AliMUONPainterPlotSelector::DimensionButtonWasClicked(Int_t id)
301 {
302   /// One dim button was clicked
303   
304   AliDebug(1,Form("id=%d",id));
305   
306   TGTextButton* button = (TGTextButton*)fDataSourceDimensions->GetButton(id);
307   
308   SetCurrentDimension(reinterpret_cast<Long_t>(button->GetUserData()));
309   
310   if ( fCurrentDimension >= 0 )
311   {
312     AliMUONPainterInterfaceHelper::SetState(*fTypes,kTRUE);
313     AliMUONPainterInterfaceHelper::Select(*fTypes,fCurrentType.Data(),kFALSE);
314     fTypes->Show();
315   }
316   
317   AliDebug(1,Form("fCurrentDimension=%ld fCurrentData=%p fCurrentType=%s",
318                   fCurrentDimension,fCurrentData,fCurrentType.Data()));
319   
320   DataSourceWasChanged();
321 }
322
323 //_____________________________________________________________________________
324 void
325 AliMUONPainterPlotSelector::ResetDimensionButtonMap()
326 {
327   /// Reset the button group map
328   
329   TIter next(fDimensionButtonMap);
330   TObjString* str;
331   
332   while ( ( str = static_cast<TObjString*>(next()) ) )
333   {
334     TGButtonGroup* bg = static_cast<TGButtonGroup*>(fDimensionButtonMap->GetValue(str->String()));
335     AliMUONPainterInterfaceHelper::Unselect(*bg,"*");
336   }
337 }
338
339 //_____________________________________________________________________________
340 void
341 AliMUONPainterPlotSelector::RestoreDimensionButtons(const char* dataSourceName,
342                                                     Bool_t updateCurrentDimension)
343 {
344   /// Restore (i.e. contrary of Backup) a given dimension button group
345   
346   AliDebug(1,Form("name %s",dataSourceName));
347   TGButtonGroup* group = static_cast<TGButtonGroup*>(fDimensionButtonMap->GetValue(dataSourceName));
348   
349   AliMUONPainterInterfaceHelper::Copy(*group,*fDataSourceDimensions);
350   
351   fDataSourceDimensions->Connect("Clicked(Int_t)",
352                                  "AliMUONPainterPlotSelector",this,
353                                  "DimensionButtonWasClicked(Int_t)");    
354   
355   if ( updateCurrentDimension ) 
356   {
357     TGButton* button = AliMUONPainterInterfaceHelper::FindDownButton(*fDataSourceDimensions);
358     if ( button ) 
359     {
360       SetCurrentDimension(reinterpret_cast<Long_t>(button->GetUserData()));
361     }
362     else 
363     {
364       SetCurrentDimension(-1);
365     }
366   }
367   
368   fDataSourceDimensions->Show();
369 }
370
371 //_____________________________________________________________________________
372 void 
373 AliMUONPainterPlotSelector::SetCurrentData(AliMUONVTrackerData* data)
374 {
375   /// Set the current data pointer
376   AliDebug(1,Form("fCurrentData %p -> %p",fCurrentData,data));
377   fCurrentData = data;
378 }
379
380 //_____________________________________________________________________________
381 void 
382 AliMUONPainterPlotSelector::SetCurrentDimension(Long_t i)
383 {
384   /// Set the current dimension
385   AliDebug(1,Form("fCurrentDimension %ld -> %ld",fCurrentDimension,i));
386   fCurrentDimension = i;
387 }
388
389 //_____________________________________________________________________________
390 void 
391 AliMUONPainterPlotSelector::SetCurrentType(const char* type)
392 {
393   /// Set the current type
394   AliDebug(1,Form("fCurrentType %s -> %s",fCurrentType.Data(),type));
395   fCurrentType = type;
396 }
397
398 //_____________________________________________________________________________
399 void
400 AliMUONPainterPlotSelector::SourceButtonWasClicked(Int_t id)
401 {
402   /// A source button was clicked
403   AliDebug(1,Form("BEGIN id %d fCurrentDimension=%ld fCurrentData=%p fCurrentType=%s",
404                   id,
405                   fCurrentDimension,fCurrentData,fCurrentType.Data()));
406
407   BackupDimensionButtons();
408   
409   TGButton* button = fDataSourceNames->GetButton(id);
410   if ( !button ) 
411   {
412     StdoutToAliDebug(1,AliMUONPainterInterfaceHelper::Dump(*fDataSourceNames));
413     AliFatal(Form("Could not get DataSource button id=%d",id));
414   }
415   
416   AliMUONVTrackerData* data = reinterpret_cast<AliMUONVTrackerData*>(button->GetUserData());
417
418   TString name =  data ? data->GetName() : fgkDefaultSourceName;
419
420   RestoreDimensionButtons(name,kTRUE);
421   
422   if ( data != 0 && 
423        fCurrentDimension >= 0 && 
424        fCurrentDimension < (Long_t)(data->NumberOfDimensions()) )
425   {
426     AliMUONPainterInterfaceHelper::SetState(*fTypes,kTRUE);
427   }
428   else
429   {
430     AliMUONPainterInterfaceHelper::SetState(*fTypes,kFALSE);
431   }
432   
433   SetCurrentData(data);
434   
435   UpdateTypeButton();
436   
437   fDataSourceNames->Show();
438   fDataSourceDimensions->Show();
439   fTypes->Show();
440   
441   Resize();
442   Layout();
443   
444   AliDebug(1,Form("END fCurrentDimension=%ld fCurrentData=%p fCurrentType=%s",
445                   fCurrentDimension,fCurrentData,fCurrentType.Data()));
446
447   DataSourceWasChanged();
448 }
449
450 //_____________________________________________________________________________
451 void
452 AliMUONPainterPlotSelector::TypeButtonWasClicked(Int_t id)
453 {
454   /// A type button was clicked
455   AliDebug(1,Form("fCurrentDimension=%ld fCurrentData=%p",
456                   fCurrentDimension,fCurrentData));
457
458   TGTextButton* button = (TGTextButton*)fTypes->GetButton(id);
459   SetCurrentType(button->GetTitle());
460   
461   AliDebug(1,Form("fCurrentType=%s",fCurrentType.Data()));
462   
463   DataSourceWasChanged();
464 }
465
466 //_____________________________________________________________________________
467 void AliMUONPainterPlotSelector::Update(const AliMUONPainterMatrix& painterMatrix)
468 {
469   /// Update ourselves from a new painter matrix
470   
471   AliDebug(1,"BEGIN");
472
473   SetCurrentType("");
474   SetCurrentData(0x0);
475   SetCurrentDimension(-1);
476   
477   AliMUONPainterInterfaceHelper::Unselect(*fDataSourceNames,"*");
478   AliMUONPainterInterfaceHelper::Unselect(*fDataSourceDimensions,"*");
479   
480   ResetDimensionButtonMap();
481   
482   TObjArray types;
483   types.SetOwner(kTRUE);  
484   painterMatrix.GetTypes(types);  
485   CreateTypeButtons(types);
486   
487   if ( painterMatrix.Size() > 0 ) 
488   {
489     AliMUONVPainter* painter = painterMatrix.Painter(painterMatrix.Size()-1);
490     
491     AliMUONPainterGroup* plotterGroup = painter->PlotterGroup();
492     
493     if ( plotterGroup )
494     {
495       // the group have some data to plot, so update our internal pointers
496       // to reflect that
497       SetCurrentData(plotterGroup->Data());
498       SetCurrentDimension(plotterGroup->DataIndex());
499       SetCurrentType(plotterGroup->Type());
500     }
501   }
502   
503   AliDebug(1,Form("After update type=%s data=%p dim=%ld",
504                   fCurrentType.Data(),fCurrentData,fCurrentDimension));
505
506   // the *order* of the 3 following lines is *very* important
507
508   AliDebug(1,"Will update source buttons");
509   UpdateSourceButton();
510   AliDebug(1,"Will update dimension buttons");
511   UpdateDimensionButton();
512   AliDebug(1,"Will update type buttons");
513   UpdateTypeButton();
514   
515   Resize();
516   Layout();
517   
518   AliDebug(1,Form("END fCurrentType=%s fCurrentData=%p fCurrentDimension=%ld",
519                   fCurrentType.Data(),fCurrentData,
520                   fCurrentDimension));
521 }
522
523 //_____________________________________________________________________________
524 void 
525 AliMUONPainterPlotSelector::UpdateDimensionButton()
526 {
527   /// Update the dim buttons
528   
529   TGTextButton* button = static_cast<TGTextButton*>
530   (AliMUONPainterInterfaceHelper::FindButtonByUserData(*fDataSourceDimensions,
531                                                        reinterpret_cast<void*>(fCurrentDimension)));
532   
533   if ( button ) 
534   {
535     // set this button as "ON"
536     AliMUONPainterInterfaceHelper::Select(*fDataSourceDimensions,button->GetTitle());
537   }
538   else
539   {
540     AliMUONPainterInterfaceHelper::Unselect(*fDataSourceDimensions,"*");
541   }
542   
543   fDataSourceDimensions->Show();
544 }
545
546 //_____________________________________________________________________________
547 void
548 AliMUONPainterPlotSelector::UpdateSourceButton()
549 {
550   /// Update the source buttons
551   
552   TGTextButton* button = static_cast<TGTextButton*>
553   (AliMUONPainterInterfaceHelper::FindButtonByUserData(*fDataSourceNames,
554                                                        fCurrentData));
555   
556   if ( button ) 
557   {
558     AliMUONPainterInterfaceHelper::Select(*fDataSourceNames,button->GetTitle());
559   
560     RestoreDimensionButtons(button->GetTitle(),kFALSE);
561   }
562   
563   fDataSourceNames->Show();
564 }
565
566 //_____________________________________________________________________________
567 void
568 AliMUONPainterPlotSelector::UpdateTypeButton()
569 {
570   /// Update the type buttons
571         
572   AliDebug(1,Form("fCurrentType=%s",fCurrentType.Data()));
573   
574         if (!fCurrentData)
575   {
576     AliMUONPainterInterfaceHelper::SetState(*fTypes,kFALSE);
577   }
578         else
579         {
580                 // disable levels that cannot be handled by this data
581                 TGTextButton* padButton = static_cast<TGTextButton*>
582                 (AliMUONPainterInterfaceHelper::FindButtonByName(*fTypes,"PAD"));
583                 if (padButton) 
584                 { 
585                         padButton->SetEnabled(fCurrentData->IsChannelLevelEnabled());
586                 }
587                 TGTextButton* manuButton = static_cast<TGTextButton*>
588                 (AliMUONPainterInterfaceHelper::FindButtonByName(*fTypes,"MANU"));
589                 if (manuButton) 
590                 { 
591                         manuButton->SetEnabled(fCurrentData->IsManuLevelEnabled());
592                 }
593                 TGTextButton* busPatchButton = static_cast<TGTextButton*>
594                 (AliMUONPainterInterfaceHelper::FindButtonByName(*fTypes,"BUSPATCH"));
595                 if (busPatchButton) 
596                 { 
597                         busPatchButton->SetEnabled(fCurrentData->IsBusPatchLevelEnabled());
598                 }
599                 TGTextButton* pcbButton = static_cast<TGTextButton*>
600                 (AliMUONPainterInterfaceHelper::FindButtonByName(*fTypes,"PCB"));
601                 if (pcbButton) 
602                 { 
603                         pcbButton->SetEnabled(fCurrentData->IsPCBLevelEnabled());
604                 }
605     
606         }
607         
608   TGTextButton* button = static_cast<TGTextButton*>
609   (AliMUONPainterInterfaceHelper::FindButtonByName(*fTypes,fCurrentType));
610
611   if ( button ) 
612   {
613     AliMUONPainterInterfaceHelper::Select(*fTypes,button->GetTitle());
614   }
615   else
616   {
617     AliMUONPainterInterfaceHelper::Unselect(*fTypes,"*");
618   }
619
620         
621   fTypes->Show();
622 }
623