]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONPainterPlotSelector.cxx
First big commit of the mchview program and its accompanying library,
[u/mrichter/AliRoot.git] / MUON / AliMUONPainterPlotSelector.cxx
diff --git a/MUON/AliMUONPainterPlotSelector.cxx b/MUON/AliMUONPainterPlotSelector.cxx
new file mode 100644 (file)
index 0000000..c1f21ba
--- /dev/null
@@ -0,0 +1,585 @@
+/**************************************************************************
+* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+
+// $Id$
+
+/// \class AliMUONPainterPlotSelector
+/// 
+/// Widget to select which data to plot for painters
+/// 
+/// \author Laurent Aphecetche
+///
+/// See AliMUONPainterInterfaceHelper for an important implementation note
+/// about our use of TGButtonGroup
+///
+
+#include "AliMUONPainterPlotSelector.h"
+
+#include "AliMUONPainterGroup.h"
+#include "AliMUONPainterInterfaceHelper.h"
+#include "AliMUONPainterMatrix.h"
+#include "AliMUONPainterRegistry.h"
+#include "AliMUONVPainter.h"
+#include "AliMUONVTrackerData.h"
+#include "AliLog.h"
+#include <Riostream.h>
+#include <TGButton.h>
+#include <TGButtonGroup.h>
+#include <TObjArray.h>
+#include <TObjString.h>
+
+///\cond CLASSIMP
+ClassImp(AliMUONPainterPlotSelector)
+///\endcond
+
+const char* AliMUONPainterPlotSelector::fgkDefaultSourceName = "none";  
+
+//_____________________________________________________________________________
+AliMUONPainterPlotSelector::AliMUONPainterPlotSelector(const TGWindow* window, UInt_t w, UInt_t h)
+: TGCompositeFrame(window,w,h,kHorizontalFrame),
+fTypes(0x0),
+fDataSourceNames(0x0),
+fDataSourceDimensions(0x0),
+fDimensionButtonMap(new TMap),
+fCurrentType(""),
+fCurrentData(0x0),
+fCurrentDimension(-1)
+{
+  /// ctor
+  fTypes = new TGButtonGroup(this,"Plot");
+
+  fDataSourceNames = new TGButtonGroup(this,"Sources");
+      
+  AliMUONPainterRegistry* reg = AliMUONPainterRegistry::Instance();
+  
+  reg->Connect("DataSourceWasRegistered(AliMUONVTrackerData*)",
+               "AliMUONPainterPlotSelector",
+               this,
+               "DataSourceWasRegistered(AliMUONVTrackerData*)");
+  
+  reg->Connect("DataSourceWasUnregistered(AliMUONVTrackerData*)",
+               "AliMUONPainterPlotSelector",
+               this,
+               "DataSourceWasUnregistered(AliMUONVTrackerData*)");
+    
+  AliMUONPainterInterfaceHelper::AddRadioButton(*fDataSourceNames,
+                                                fgkDefaultSourceName,
+                                                0x0,
+                                                kTRUE);
+  
+  CreateDimensionButtons(fgkDefaultSourceName);
+  
+  fDataSourceDimensions = new TGButtonGroup(this,0,3,5,0,"Dimensions");
+  
+  for ( Int_t i = 0; i < reg->NumberOfDataSources(); ++i )
+  {
+    AliMUONVTrackerData* data = reg->DataSource(i);
+    DataSourceWasRegistered(data);
+  }
+  
+  fDataSourceNames->Connect("Clicked(Int_t)","AliMUONPainterPlotSelector",
+                            this,
+                            "SourceButtonWasClicked(Int_t)");
+
+  AddFrame(fTypes);
+  AddFrame(fDataSourceNames);
+  AddFrame(fDataSourceDimensions);
+}
+
+//_____________________________________________________________________________
+AliMUONPainterPlotSelector::~AliMUONPainterPlotSelector()
+{
+  /// dtor
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::BackupDimensionButtons()
+{
+  /// Backup the dimension button group
+  
+  TString name = fDataSourceDimensions->GetTitle();
+
+  AliDebug(1,Form("name %s",name.Data()));
+
+  if ( name !=  fgkDefaultSourceName )
+  {
+    TGButtonGroup* group = static_cast<TGButtonGroup*>(fDimensionButtonMap->GetValue(name));
+    if (!group) 
+    {
+      AliError(Form("Did not find group %s",name.Data()));
+    }
+    else
+    {
+      AliMUONPainterInterfaceHelper::Copy(*fDataSourceDimensions,*group);
+    }
+  
+  }
+  
+  fDataSourceDimensions->Disconnect("Clicked(Int_t)",
+                                    this,
+                                    "DimensionButtonWasClicked(Int_t)");  
+}
+
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::CreateDimensionButtons(const char* dataSourceName)
+{
+  /// Create the dimension button group for a given data source
+  
+  AliDebug(1,Form("Creating dimension buttons for dataSource %s",dataSourceName));
+  
+  AliMUONVTrackerData* data = AliMUONPainterRegistry::Instance()->FindDataSource(dataSourceName);
+
+  TGButtonGroup* bg = new TGButtonGroup(this,0,3,5,0,dataSourceName);
+  
+  if ( data ) 
+  {
+    for ( Int_t i = 0; i < data->NumberOfDimensions(); ++i ) 
+    {
+      AliMUONPainterInterfaceHelper::AddRadioButton(*bg,
+                                                    data->DimensionName(i),
+                                                    reinterpret_cast<void*>(i));
+    }
+  }
+  
+  fDimensionButtonMap->Add(new TObjString(dataSourceName),bg);
+  
+  AliDebug(1,Form("bg is %p Count=%d",bg,bg->GetCount()));
+  StdoutToAliDebug(1,AliMUONPainterInterfaceHelper::Dump(*bg));
+  
+  bg->Connect("Clicked(Int_t)","AliMUONPainterPlotSelector",this,
+                                "DimensionButtonWasClicked(Int_t)");
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::CreateTypeButtons(const TObjArray& types)
+{
+  /// Create the type button group
+  
+  AliMUONPainterInterfaceHelper::ClearButtons(*fTypes);
+
+  TIter nextType(&types);
+  TObjString* str;
+
+  while ( ( str = static_cast<TObjString*>(nextType()) ) )
+  {
+    AliMUONPainterInterfaceHelper::AddRadioButton(*fTypes,str->String());
+  }
+
+  fTypes->Connect("Clicked(Int_t)","AliMUONPainterPlotSelector",this,
+                  "TypeButtonWasClicked(Int_t)");
+  
+  fTypes->Show();
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::DataSourceWasChanged()
+{
+  /// Data source was changed
+  DataSourceWasChanged(fCurrentType.Data(),fCurrentData,fCurrentDimension);
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPainterPlotSelector::DataSourceWasChanged(const char* type, 
+                                                 AliMUONVTrackerData* data,
+                                                 Int_t dataIndex)
+{
+  /// Emit a signal to tell data source was changed
+  AliDebug(1,Form("type=%s data=%s (%s)",
+                  type,
+                  ( data ? data->GetName() : "" ),
+                  ( ( data && dataIndex >= 0 ) ? data->DimensionName(dataIndex).Data() :
+                    "")));
+  
+  Long_t param[] = { (Long_t)type, (Long_t)data,
+    (Long_t)dataIndex };
+  
+  Emit("DataSourceWasChanged(const char*,AliMUONVTrackerData*,Int_t)",param);
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::DataSourceWasRegistered(AliMUONVTrackerData* data)
+{
+  /// A new data source has been registered : add it to the interface
+  
+  AliDebug(1,Form("Registering %s",data->GetName()));
+  
+  AliMUONPainterInterfaceHelper::AddRadioButton(*fDataSourceNames,
+                                                data->GetName(),
+                                                data);
+  
+  data->Connect("NumberOfEventsChanged()",
+                "AliMUONPainterPlotSelector",
+                this,
+                "NumberOfEventsChanged()");
+  
+  CreateDimensionButtons(data->GetName());
+  
+  fDataSourceNames->Show();
+  
+  Layout();
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::NumberOfEventsChanged()
+{
+  /// Change the tool tip of the corresponding data source button
+
+  // find first the sender of the signal
+  
+  AliMUONVTrackerData* data = reinterpret_cast<AliMUONVTrackerData*>(gTQSender);
+  
+  TGButton* button = AliMUONPainterInterfaceHelper::FindButtonByUserData(*fDataSourceNames,data);
+  
+  if (button)
+  {
+    button->SetToolTipText(Form("%d events",data->NumberOfEvents()),250);
+  }
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::DataSourceWasUnregistered(AliMUONVTrackerData* data)
+{
+  /// A data source has been unregistered : remove it from the interface
+  
+  AliDebug(1,Form("Unregistering %s",data->GetName()));
+
+  TGButton* button = AliMUONPainterInterfaceHelper::FindButtonByName(*fDataSourceNames,
+                                                                     data->GetName());
+  AliMUONVTrackerData* check = reinterpret_cast<AliMUONVTrackerData*>(button->GetUserData());
+  if ( !button || check != data )
+  {
+    AliError("Something is seriously wrong. Please check");
+    return;
+  }
+  
+  fDataSourceNames->Remove(button);
+  delete button;
+  button->DestroyWindow();
+  
+  fDataSourceNames->Show();
+  
+  TObject* o = fDimensionButtonMap->Remove(new TObjString(data->GetName()));
+  
+  if (!o)
+  {
+    AliError("Remove failed. Please check");    
+  }
+  
+  Layout();
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPainterPlotSelector::DimensionButtonWasClicked(Int_t id)
+{
+  /// One dim button was clicked
+  
+  AliDebug(1,Form("id=%d",id));
+  
+  TGTextButton* button = (TGTextButton*)fDataSourceDimensions->GetButton(id);
+  
+  SetCurrentDimension(reinterpret_cast<Int_t>(button->GetUserData()));
+  
+  if ( fCurrentDimension >= 0 )
+  {
+    AliMUONPainterInterfaceHelper::SetState(*fTypes,kTRUE);
+    AliMUONPainterInterfaceHelper::Select(*fTypes,fCurrentType.Data(),kFALSE);
+    fTypes->Show();
+  }
+  
+  AliDebug(1,Form("fCurrentDimension=%d fCurrentData=%p fCurrentType=%s",
+                  fCurrentDimension,fCurrentData,fCurrentType.Data()));
+  
+  DataSourceWasChanged();
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::ResetDimensionButtonMap()
+{
+  /// Reset the button group map
+  
+  TIter next(fDimensionButtonMap);
+  TObjString* str;
+  
+  while ( ( str = static_cast<TObjString*>(next()) ) )
+  {
+    TGButtonGroup* bg = static_cast<TGButtonGroup*>(fDimensionButtonMap->GetValue(str->String()));
+    AliMUONPainterInterfaceHelper::Unselect(*bg,"*");
+  }
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::RestoreDimensionButtons(const char* dataSourceName,
+                                                    Bool_t updateCurrentDimension)
+{
+  /// Restore (i.e. contrary of Backup) a given dimension button group
+  
+  AliDebug(1,Form("name %s",dataSourceName));
+  TGButtonGroup* group = static_cast<TGButtonGroup*>(fDimensionButtonMap->GetValue(dataSourceName));
+  
+  AliMUONPainterInterfaceHelper::Copy(*group,*fDataSourceDimensions);
+  
+  fDataSourceDimensions->Connect("Clicked(Int_t)",
+                                 "AliMUONPainterPlotSelector",this,
+                                 "DimensionButtonWasClicked(Int_t)");    
+  
+  if ( updateCurrentDimension ) 
+  {
+    TGButton* button = AliMUONPainterInterfaceHelper::FindDownButton(*fDataSourceDimensions);
+    if ( button ) 
+    {
+      SetCurrentDimension(reinterpret_cast<Int_t>(button->GetUserData()));
+    }
+    else 
+    {
+      SetCurrentDimension(-1);
+    }
+  }
+  
+  fDataSourceDimensions->Show();
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPainterPlotSelector::SetCurrentData(AliMUONVTrackerData* data)
+{
+  /// Set the current data pointer
+  AliDebug(1,Form("fCurrentData %p -> %p",fCurrentData,data));
+  fCurrentData = data;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPainterPlotSelector::SetCurrentDimension(Int_t i)
+{
+  /// Set the current dimension
+  AliDebug(1,Form("fCurrentDimension %d -> %d",fCurrentDimension,i));
+  fCurrentDimension = i;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPainterPlotSelector::SetCurrentType(const char* type)
+{
+  /// Set the current type
+  AliDebug(1,Form("fCurrentType %s -> %s",fCurrentType.Data(),type));
+  fCurrentType = type;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::SourceButtonWasClicked(Int_t id)
+{
+  /// A source button was clicked
+  AliDebug(1,Form("BEGIN id %d fCurrentDimension=%d fCurrentData=%p fCurrentType=%s",
+                  id,
+                  fCurrentDimension,fCurrentData,fCurrentType.Data()));
+
+  BackupDimensionButtons();
+  
+  TGButton* button = fDataSourceNames->GetButton(id);
+  if ( !button ) 
+  {
+    AliError(Form("Could not get DataSource button id=%d",id));
+    StdoutToAliDebug(1,AliMUONPainterInterfaceHelper::Dump(*fDataSourceNames));
+    button->GetUserData(); // to trigger a crash so gdb is possible ;-)
+  }
+  
+  AliMUONVTrackerData* data = reinterpret_cast<AliMUONVTrackerData*>(button->GetUserData());
+
+  TString name =  data ? data->GetName() : fgkDefaultSourceName;
+
+  RestoreDimensionButtons(name,kTRUE);
+  
+  if ( data != 0 && 
+       fCurrentDimension >= 0 && 
+       fCurrentDimension < data->NumberOfDimensions() )
+  {
+    AliMUONPainterInterfaceHelper::SetState(*fTypes,kTRUE);
+  }
+  else
+  {
+    AliMUONPainterInterfaceHelper::SetState(*fTypes,kFALSE);
+  }
+  
+  SetCurrentData(data);
+  
+  UpdateTypeButton();
+  
+  fDataSourceNames->Show();
+  fDataSourceDimensions->Show();
+  fTypes->Show();
+  
+  Resize();
+  Layout();
+  
+  AliDebug(1,Form("END fCurrentDimension=%d fCurrentData=%p fCurrentType=%s",
+                  fCurrentDimension,fCurrentData,fCurrentType.Data()));
+
+  DataSourceWasChanged();
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::TypeButtonWasClicked(Int_t id)
+{
+  /// A type button was clicked
+  AliDebug(1,Form("fCurrentDimension=%d fCurrentData=%p",
+                  fCurrentDimension,fCurrentData));
+
+  TGTextButton* button = (TGTextButton*)fTypes->GetButton(id);
+  SetCurrentType(button->GetTitle());
+  
+  AliDebug(1,Form("fCurrentType=%s",fCurrentType.Data()));
+  
+  DataSourceWasChanged();
+}
+
+//_____________________________________________________________________________
+void AliMUONPainterPlotSelector::Update(const AliMUONPainterMatrix& painterMatrix)
+{
+  /// Update ourselves from a new painter matrix
+  
+  AliDebug(1,"BEGIN");
+
+  SetCurrentType("");
+  SetCurrentData(0x0);
+  SetCurrentDimension(-1);
+  
+  AliMUONPainterInterfaceHelper::Unselect(*fDataSourceNames,"*");
+  AliMUONPainterInterfaceHelper::Unselect(*fDataSourceDimensions,"*");
+  
+  ResetDimensionButtonMap();
+  
+  TObjArray types;
+  types.SetOwner(kTRUE);  
+  painterMatrix.GetTypes(types);  
+  CreateTypeButtons(types);
+  
+  if ( painterMatrix.Size() > 0 ) 
+  {
+    AliMUONVPainter* painter = painterMatrix.Painter(painterMatrix.Size()-1);
+    
+    AliMUONPainterGroup* plotterGroup = painter->PlotterGroup();
+    
+    if ( plotterGroup )
+    {
+      // the group have some data to plot, so update our internal pointers
+      // to reflect that
+      SetCurrentData(plotterGroup->Data());
+      SetCurrentDimension(plotterGroup->DataIndex());
+      SetCurrentType(plotterGroup->Type());
+    }
+  }
+  
+  AliDebug(1,Form("After update type=%s data=%p dim=%d",
+                  fCurrentType.Data(),fCurrentData,fCurrentDimension));
+
+  // the *order* of the 3 following lines is *very* important
+
+  AliDebug(1,"Will update source buttons");
+  UpdateSourceButton();
+  AliDebug(1,"Will update dimension buttons");
+  UpdateDimensionButton();
+  AliDebug(1,"Will update type buttons");
+  UpdateTypeButton();
+  
+  Resize();
+  Layout();
+  
+  AliDebug(1,Form("END fCurrentType=%s fCurrentData=%p fCurrentDimension=%d",
+                  fCurrentType.Data(),fCurrentData,
+                  fCurrentDimension));
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPainterPlotSelector::UpdateDimensionButton()
+{
+  /// Update the dim buttons
+  
+  TGTextButton* button = static_cast<TGTextButton*>
+  (AliMUONPainterInterfaceHelper::FindButtonByUserData(*fDataSourceDimensions,
+                                                       reinterpret_cast<void*>(fCurrentDimension)));
+  
+  if ( button ) 
+  {
+    // set this button as "ON"
+    AliMUONPainterInterfaceHelper::Select(*fDataSourceDimensions,button->GetTitle());
+  }
+  else
+  {
+    AliMUONPainterInterfaceHelper::Unselect(*fDataSourceDimensions,"*");
+  }
+  
+  fDataSourceDimensions->Show();
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::UpdateSourceButton()
+{
+  /// Update the source buttons
+  
+  TGTextButton* button = static_cast<TGTextButton*>
+  (AliMUONPainterInterfaceHelper::FindButtonByUserData(*fDataSourceNames,
+                                                       fCurrentData));
+  
+  AliMUONPainterInterfaceHelper::Select(*fDataSourceNames,button->GetTitle());
+  
+  RestoreDimensionButtons(button->GetTitle(),kFALSE);
+  
+  fDataSourceNames->Show();
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPainterPlotSelector::UpdateTypeButton()
+{
+  /// Update the type buttons
+  
+  AliDebug(1,Form("fCurrentType=%s",fCurrentType.Data()));
+  
+  TGTextButton* button = static_cast<TGTextButton*>
+  (AliMUONPainterInterfaceHelper::FindButtonByName(*fTypes,fCurrentType));
+
+  if ( button ) 
+  {
+    AliMUONPainterInterfaceHelper::Select(*fTypes,button->GetTitle());
+  }
+  else
+  {
+    AliMUONPainterInterfaceHelper::Unselect(*fTypes,"*");
+  }
+
+  if (!fCurrentData)
+  {
+    AliMUONPainterInterfaceHelper::SetState(*fTypes,kFALSE);
+  }
+  
+  fTypes->Show();
+}
+