1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include "AliMUONPainterMatrixFrame.h"
20 #include "AliMUONPainterColorSlider.h"
21 #include "AliMUONPainterMatrix.h"
22 #include "AliMUONPainterGroup.h"
23 #include "AliMUONPainterHighlighter.h"
24 #include "AliMUONPainterInterfaceHelper.h"
25 #include "AliMUONPainterPlotSelector.h"
26 #include "AliMUONPainterRegistry.h"
27 #include "AliMUONVTrackerData.h"
28 #include "AliMUONVPainter.h"
30 #include <Riostream.h>
34 #include <TGButtonGroup.h>
36 #include <TGListBox.h>
37 #include <TObjArray.h>
38 #include <TObjString.h>
39 #include <TRootEmbeddedCanvas.h>
44 /// \class AliMUONPainterMatrixFrame
46 /// A widget to draw a painter matrix, and the corresponding interface
47 /// to select what to outline or paint, and which part of the painter
48 /// is responding to mouse events
50 /// \author Laurent Aphecetche, Subatech
53 ClassImp(AliMUONPainterMatrixFrame)
56 //_____________________________________________________________________________
57 AliMUONPainterMatrixFrame::AliMUONPainterMatrixFrame(const TGWindow* window,
59 : TGCompositeFrame(window,w,h,kVerticalFrame|kDoubleBorder),
63 fResponderButtons(0x0),
66 fPainterHighlighter(new AliMUONPainterHighlighter),
73 const Int_t kBorderSize = 10;
75 UInt_t wi = w - kBorderSize*0;
76 UInt_t hi = h - kBorderSize*1;
79 fCanvasHeight = (UInt_t)(hi*0.75);
81 fMainFrame = new TGHorizontalFrame(this,fCanvasWidth,hi);
83 const Int_t kColorWidth = 100;
85 fColorSlider = new AliMUONPainterColorSlider(fMainFrame,kColorWidth,fCanvasHeight);
87 fView = new TRootEmbeddedCanvas("ec",fMainFrame,fCanvasWidth-kColorWidth,fCanvasHeight,kChildFrame);
89 fInterface = new TGHorizontalFrame(this,fCanvasWidth);
91 fMainFrame->AddFrame(fView, new TGLayoutHints(kLHintsExpandX));
92 fMainFrame->AddFrame(fColorSlider,new TGLayoutHints(kLHintsTop|kLHintsRight|kLHintsCenterY,kBorderSize/2));
94 AliMUONPainterInterfaceHelper::SetBackgroundColor("MatrixFrame.ColorSlider",*fColorSlider);
96 fResponderButtons = new TGButtonGroup(fInterface,"Responder");
98 fOutlineButtons = new TGButtonGroup(fInterface,"Outline");
100 fInterface->AddFrame(fResponderButtons);
101 fInterface->AddFrame(fOutlineButtons);
104 new AliMUONPainterPlotSelector(fInterface);//,wi,interfaceHeight);
106 fInterface->AddFrame(fPlotSelector);//,new TGLayoutHints(kLHintsRight|kLHintsExpandX));
108 fOutlineButtons->Show();
109 fResponderButtons->Show();
111 AddFrame(fMainFrame,new TGLayoutHints(kLHintsExpandX|kLHintsTop,
114 AddFrame(fInterface,new TGLayoutHints(kLHintsExpandX|kLHintsBottom,
118 // Set the connections
120 fPlotSelector->Connect("DataSourceWasChanged(const char*,AliMUONVTrackerData*,Int_t)",
121 "AliMUONPainterMatrixFrame",
123 "DataSourceWasChanged(const char*,AliMUONVTrackerData*,Int_t)");
125 fColorSlider->Connect("DataRangeWasChanged(Double_t*)",
126 "AliMUONPainterMatrixFrame",
128 "DataRangeWasChanged(Double_t*)");
130 fColorSlider->Connect("DataRangeAutoRequested()",
131 "AliMUONPainterMatrixFrame",
133 "DataRangeAutoRequested()");
135 // Set the colors (mainly for debugging frame layout)
137 AliMUONPainterInterfaceHelper::SetBackgroundColor("MatrixFrame.Main",*this);
139 fMainFrame->HideFrame(fColorSlider);
141 fMainFrame->Resize();
144 //_____________________________________________________________________________
145 AliMUONPainterMatrixFrame::~AliMUONPainterMatrixFrame()
148 delete fPainterHighlighter;
149 AliError("Please write a decent dtor for this class !");
152 //_____________________________________________________________________________
154 AliMUONPainterMatrixFrame::ChangeTitle(const TString& title)
158 TitleHasChanged(title.Data());
161 //_____________________________________________________________________________
163 AliMUONPainterMatrixFrame::ChangeTitle(AliMUONVPainter* painter,
164 const char* basename,
165 Double_t x, Double_t y)
167 /// Change the title according to painter
174 if ( basename ) name = basename;
175 else name = painter->PathName();
177 AliMUONVPainter* master = painter->Master();
179 AliMUONPainterGroup* group = master->PlotterGroup();
181 AliDebug(1,Form("Painter is %s plotterGroup is %p %s",
182 painter->PathName().Data(),
184 ( group ? group->Type() : "")));
187 if ( group && group->Data() )
190 name += painter->Describe(*(group->Data()),group->DataIndex(),x,y);
195 name = fPainterMatrix->Name();
198 TitleHasChanged(name.Data());
201 //_____________________________________________________________________________
203 AliMUONPainterMatrixFrame::Clear(Option_t*)
205 /// Clear the view(s)
207 fPainterMatrix = 0x0;
209 AliMUONPainterInterfaceHelper::ClearButtons(*fOutlineButtons);
210 AliMUONPainterInterfaceHelper::ClearButtons(*fResponderButtons);
212 fView->GetCanvas()->SetEditable(kTRUE);
213 fView->GetCanvas()->Clear();
214 fView->GetCanvas()->Modified();
215 fView->GetCanvas()->Update();
216 fView->GetCanvas()->SetEditable(kFALSE);
221 //_____________________________________________________________________________
223 AliMUONPainterMatrixFrame::CreateButtons()
225 /// Create the interface buttons
229 // AliMUONVPainter* painter = fPainterMatrix->Painter(0);
234 fPainterMatrix->GetTypes(types);
236 TIter nextType(&types);
239 while ( ( str = static_cast<TObjString*>(nextType()) ) )
241 AliMUONPainterInterfaceHelper::AddRadioButton(*fResponderButtons,str->String());
242 AliMUONPainterInterfaceHelper::AddCheckButton(*fOutlineButtons,str->String());
245 fOutlineButtons->Connect("Clicked(Int_t)","AliMUONPainterMatrixFrame",
246 this,"OutlineButtonWasClicked(Int_t)");
248 fResponderButtons->Connect("Clicked(Int_t)","AliMUONPainterMatrixFrame",
249 this,"ResponderButtonWasClicked(Int_t)");
252 //_____________________________________________________________________________
254 AliMUONPainterMatrixFrame::DataRangeAutoRequested()
256 /// Get there when the "Auto" button below the color slider is clicked,
257 /// to compute the data range actually painted.
259 Double_t dataMin, dataMax;
263 fPainterMatrix->ComputeDataRange();
265 fPainterMatrix->GetDataRange(dataMin,dataMax);
267 AliDebug(1,Form("dataMin,Max for SetRange=%e,%e",dataMin,dataMax));
271 fColorSlider->SetRange(dataMin,dataMax,emit);
276 //_____________________________________________________________________________
278 AliMUONPainterMatrixFrame::DataRangeWasChanged(Double_t* range)
280 /// Get there when the data range is changed
282 AliDebug(1,Form("range=%e,%e",range[0],range[1]));
284 fPainterMatrix->SetDataRange(range[0],range[1]);
286 if ( !fColorSlider->IsLocked() )
292 //_____________________________________________________________________________
294 AliMUONPainterMatrixFrame::DataSourceWasChanged(const char* type,
295 AliMUONVTrackerData* data,
298 /// Update what to plot
300 TString pattern(type);
302 AliDebug(1,Form("type=%s data=%s index=%d",type,
303 (data ? data->GetName() : "null"),indexInData));
305 AliMUONVTrackerData* d = data;
307 if ( !d || !data || indexInData < 0 || pattern == "" )
314 fPainterMatrix->SetData(pattern,d,indexInData);
318 ChangeTitle(fPainterMatrix->Painter(0));
321 //_____________________________________________________________________________
323 AliMUONPainterMatrixFrame::EventInfo(Int_t event, Int_t px ,Int_t py, TObject* object)
325 /// Used to detect entering/leaving a given painter
327 if (!gPad || !object) return;
329 // cout << "EventInfo : event " << event << " px " << px << " py " << py
330 // << " object " << object << " " << object->GetName() << endl;
334 if ( object->InheritsFrom("AliMUONVPainter") )
336 AliMUONVPainter* p = static_cast<AliMUONVPainter*>(object);
337 p->ExecuteEvent(7,px,py);
342 if ( event == kMouseLeave )
344 if ( object->InheritsFrom("AliMUONVPainter") )
346 AliMUONVPainter* p = static_cast<AliMUONVPainter*>(object);
348 fPainterHighlighter->SetPainter(0x0);
354 if ( event == kMouseEnter )
356 if ( object->InheritsFrom("AliMUONVPainter") )
358 AliMUONVPainter* painter = static_cast<AliMUONVPainter*>(object);
359 if ( painter->IsResponder() && !painter->HandleMouseMotion() )
361 MouseEnter(static_cast<AliMUONVPainter*>(object));
362 fPainterHighlighter->SetPainter(painter);
366 else if ( !painter->HandleMouseMotion() )
368 MouseEnter(static_cast<AliMUONVPainter*>(object));
373 if ( event == kMouseMotion )
375 if ( object->InheritsFrom("AliMUONVPainter") )
377 AliMUONVPainter* painter = static_cast<AliMUONVPainter*>(object);
379 if ( painter->HandleMouseMotion() && painter->IsResponder() )
382 TVirtualPad* padsave = gPad;
383 painter->Pad()->cd();
384 painter->PixelToPad(px,py,pos[0],pos[1]);
385 MouseMotion(static_cast<AliMUONVPainter*>(object),pos);
386 fPainterHighlighter->SetPainter(painter,pos[0],pos[1]);
395 //_____________________________________________________________________________
397 AliMUONPainterMatrixFrame::MouseEnter(AliMUONVPainter* painter)
399 /// Emit a signal to notify that mouse pointer is entering a given painter
401 AliDebug(1,Form("painter=%p %s",painter,painter->PathName().Data()));
403 ChangeTitle(painter);
405 Long_t params[] = { (Long_t)painter };
407 Emit("MouseEnter(AliMUONVPainter*)",params);
411 //_____________________________________________________________________________
413 AliMUONPainterMatrixFrame::MouseLeave(const AliMUONVPainter* painter)
415 /// Emit a signal to notify that mouse pointer is leaving a given painter
417 ChangeTitle(fPainterMatrix->Name());
419 Long_t params[] = { (Long_t)painter };
421 Emit("MouseLeave(AliMUONVPainter*)",params);
424 //_____________________________________________________________________________
426 AliMUONPainterMatrixFrame::MouseMotion(AliMUONVPainter* painter, Double_t* position)
428 /// Emit a signal to notify that mouse pointer is moving within a given painter
430 ChangeTitle(painter,painter->NameAtPosition(position[0],position[1]),
431 position[0],position[1]);
433 Long_t params[] = { (Long_t)painter, (Long_t)position };
435 Emit("MouseMotion(AliMUONVPainter*,Double_t*)",params);
439 //_____________________________________________________________________________
441 AliMUONPainterMatrixFrame::ResponderButtonWasClicked(Int_t id)
443 /// One responder button was clicked
445 TGTextButton* button = static_cast<TGTextButton*>(fResponderButtons->GetButton(id));
446 TString pattern = button->GetString();
448 // AliInfo(Form("id=%d button=%d %s",id,button->IsOn(),pattern.Data()));
450 assert(button->IsOn()==1);
452 fPainterMatrix->SetResponder(pattern.Data());
455 //_____________________________________________________________________________
457 AliMUONPainterMatrixFrame::OutlineButtonWasClicked(Int_t id)
459 /// One outline button was clicked
461 TGTextButton* button = static_cast<TGTextButton*>(fOutlineButtons->GetButton(id));
462 TString pattern = button->GetString();
464 fPainterMatrix->SetOutlined(pattern.Data(),button->IsOn());
467 fView->GetCanvas()->Update();
469 // Update the interface (e.g. list of possible responders can have
470 // changed due to visibility change)
471 UpdateInterface(kFALSE);
474 //_____________________________________________________________________________
476 AliMUONPainterMatrixFrame::SaveAs(const char* filename, Option_t* option) const
478 /// Save painter matrix (in the sense of "print") in filename
480 TCanvas* d = fPainterMatrix->CreateCanvas();
482 d->SaveAs(filename,option);
487 //_____________________________________________________________________________
489 AliMUONPainterMatrixFrame::TitleHasChanged(const char* title)
491 /// Emit the TitleHasChanged signal
493 Long_t params[] = { (Long_t)title };
494 Emit("TitleHasChanged(const char*)",params);
498 //_____________________________________________________________________________
500 AliMUONPainterMatrixFrame::Update()
502 /// Force update of all canvases
506 fView->GetCanvas()->SetEditable(kTRUE);
508 Bool_t colorSlider = ( fPainterMatrix->Data() != 0x0 );
512 fView->GetCanvas()->SetEditable(kFALSE);
514 AliDebug(1,Form("colorSlider=%d",colorSlider));
518 fMainFrame->ShowFrame(fColorSlider);
522 fMainFrame->HideFrame(fColorSlider);
525 fMainFrame->Layout();
529 //_____________________________________________________________________________
531 AliMUONPainterMatrixFrame::UpdateDataRange()
533 /// Update the data range
535 if ( fColorSlider->IsLocked() )
537 fColorSlider->SetRange(0,0,kTRUE);
543 fPainterMatrix->GetDataRange(min,max);
545 AliDebug(1,Form("min %e max %e",min,max));
549 fPainterMatrix->ComputeDataRange();
550 fPainterMatrix->GetDataRange(min,max);
553 fColorSlider->SetRange(min,max,kFALSE);
556 //_____________________________________________________________________________
558 AliMUONPainterMatrixFrame::UpdateInterface(Bool_t fromScratch)
560 /// Update the full interface
562 if ( fromScratch || fOutlineButtons->GetCount() == 0 )
567 AliMUONPainterInterfaceHelper::Unselect(*fResponderButtons,"*");
568 AliMUONPainterInterfaceHelper::Unselect(*fOutlineButtons,"*");
570 AliMUONVPainter* painter = fPainterMatrix->Painter(0);
573 types.SetOwner(kTRUE);
575 fPainterMatrix->GetTypes(types);
577 // update button states
581 TString theResponder;
583 while ( ( otype = static_cast<TObjString*>(next()) ) )
585 AliMUONPainterGroup* group = painter->Group(otype->String());
587 if ( group && group->IsOutlined() )
589 AliMUONPainterInterfaceHelper::Select(*fOutlineButtons,otype->String().Data());
595 AliMUONPainterGroup* responderGroup = painter->ResponderGroup();
599 AliMUONPainterInterfaceHelper::Select(*fResponderButtons,responderGroup->Type());
603 // update data source view
605 fPlotSelector->Update(*fPainterMatrix);
607 fResponderButtons->Show();
608 fOutlineButtons->Show();
613 //_____________________________________________________________________________
615 AliMUONPainterMatrixFrame::Use(AliMUONPainterMatrix* group)
617 /// Change the matrix used
621 fPainterMatrix = group;
623 fView->GetCanvas()->SetEditable(kTRUE);
625 fView->GetCanvas()->Divide(fPainterMatrix->Nx(),fPainterMatrix->Ny());
627 for ( Int_t i = 0; i < fPainterMatrix->Size(); ++i )
629 AliMUONVPainter* painter = fPainterMatrix->Painter(i);
630 fView->GetCanvas()->cd(i+1);
632 fPainterHighlighter->SetPainter(0x0);
633 fPainterHighlighter->Draw();
638 UpdateInterface(kTRUE);
640 ChangeTitle(fPainterMatrix->Name());
642 fView->GetCanvas()->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
643 "AliMUONPainterMatrixFrame",this,
644 "EventInfo(Int_t,Int_t,Int_t,TObject*)");
648 //_____________________________________________________________________________
650 AliMUONPainterMatrixFrame::ViewModified()
652 /// Update our canvas
654 for ( Int_t i = 0; i < fPainterMatrix->Size(); ++i )
656 fView->GetCanvas()->GetPad(i+1)->Modified();
658 fView->GetCanvas()->Modified();
659 fView->GetCanvas()->Update();