    // @(#)root/gpad:$Name:  $:$Id: TDrawPanelHist.cxx,v 1.5 2001/09/28 12:34:50 brun Exp $
    // Author: Rene Brun   26/11/96

    /*************************************************************************
     * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
     * All rights reserved.                                                  *
     *                                                                       *
     * For the licensing terms see $ROOTSYS/LICENSE.                         *
     * For the list of contributors see $ROOTSYS/README/CREDITS.             *
     *************************************************************************/

    #include "TROOT.h"
    #include "TDrawPanelHist.h"
    #include "TGroupButton.h"
    #include "TSlider.h"
    #include "TText.h"
    #include "TH1.h"
    #include "TF1.h"

    #include <stdio.h>

    ClassImp(TDrawPanelHist)

    //______________________________________________________________________________
    //
    //  A TDrawPanelHist is a TDialogCanvas specialized to control
    //  histogram drawing options.
    //   With the mouse, the user can control:
    //     - the drawing range in X and Y
    //     - the drawing options
    //   When the DRAW button is executed, the selected histogram is drawn
    //   with the current parameters.
    //
    //   Use the slider to control the range of the histogram to be drawn.
    //
    //   The options are documented in TH1::Draw.
    //

/* */ //

// //______________________________________________________________________________ TDrawPanelHist::TDrawPanelHist() : TDialogCanvas() { // DrawPanelHist default constructor. } //_____________________________________________________________________________ TDrawPanelHist::TDrawPanelHist(const char *name, const char *title, UInt_t ww, UInt_t wh) : TDialogCanvas(name, title,ww,wh) { // DrawPanelHist constructor. TGroupButton *b; fOption = ""; fRefPad = (TPad*)gROOT->GetSelectedPad(); fRefObject = this; fHistogram = gROOT->GetSelectedPrimitive(); BuildStandardButtons(); // Range Slider fSlider = new TSlider("slider","X slider",.05,.11,.95,.17); fSlider->SetObject(this); if (fHistogram->InheritsFrom("TH1")) { TH1 *h = (TH1 *)fHistogram; Int_t nbins = h->GetXaxis()->GetNbins(); Int_t first = h->GetXaxis()->GetFirst(); Int_t last = h->GetXaxis()->GetLast(); Float_t xmin = 0; Float_t xmax = 1; if (first > 1) xmin = Float_t(first)/Float_t(nbins); if (last > 1) xmax = Float_t(last)/Float_t(nbins); fSlider->SetRange(xmin,xmax); } // Standard functions Int_t nlines = 14; Float_t x0 = 0.1; Float_t y = 0.98; Float_t dy = (y-0.18)/nlines; Float_t yb = 0.7*dy; y -= dy; b = new TGroupButton("DRAW","hist","AddOption("hist")",x0,y-yb,.27,y); b->Draw(); y -= dy; b = new TGroupButton("DRAW","lego1","AddOption("lego1")",x0,y-yb,.27,y); b->Draw(); b = new TGroupButton("DRAW","lego2","AddOption("lego2")",.3,y-yb,.47,y); b->Draw(); b = new TGroupButton("DRAW","lego3","AddOption("lego3")",.5,y-yb,.67,y); b->Draw(); y -= dy; b = new TGroupButton("DRAW","surf","AddOption("surf1")",x0,y-yb,.27,y); b->Draw(); b = new TGroupButton("DRAW","surf/colors","AddOption("surf2")",.3,y-yb,.47,y); b->Draw(); b = new TGroupButton("DRAW","surf/contour","AddOption("surf3")",.5,y-yb,.67,y); b->Draw(); b = new TGroupButton("DRAW","Gouraud","AddOption("surf4")",.7,y-yb,.87,y); b->Draw(); y -= dy; b = new TGroupButton("DRAW","cont0","AddOption("cont0")",x0,y-yb,.27,y); b->Draw(); b = new TGroupButton("DRAW","cont1","AddOption("cont1")",.3,y-yb,.47,y); b->Draw(); b = new TGroupButton("DRAW","cont2","AddOption("cont2")",.5,y-yb,.67,y); b->Draw(); b = new TGroupButton("DRAW","cont3","AddOption("cont3")",.7,y-yb,.87,y); b->Draw(); // Quiet/Verbose buttons y -= dy; b = new TGroupButton("SYSTEM","Cartesian","",x0,y-yb,.45,y); b->SetBorderMode(-1); b->SetFillColor(15); b->Draw(); b = new TGroupButton("SYSTEM","Polar","AddOption("pol")",.55,y-yb,.9,y); b->SetFillColor(15); b->Draw(); y -= dy; b = new TGroupButton("SYSTEM","Spheric","AddOption("sph")",x0,y-yb,.45,y); b->SetFillColor(15); b->Draw(); b = new TGroupButton("SYSTEM","Cylindric","AddOption("cyl")",.55,y-yb,.9,y); b->SetFillColor(15); b->Draw(); // Other buttons y -= dy; b = new TGroupButton("ERRORS","E1: errors/edges","AddOption("E1")",x0,y-yb,.48,y); b->SetFillColor(41); b->Draw(); b = new TGroupButton("ERRORS","E2: errors/rectangles","AddOption("E2")",.52,y-yb,.9,y); b->SetFillColor(41); b->Draw(); y -= dy; b = new TGroupButton("ERRORS","E3: errors/fill","AddOption("E3")",x0,y-yb,.48,y); b->SetFillColor(41); b->Draw(); b = new TGroupButton("ERRORS","E4: errors/contour","AddOption("E4")",.52,y-yb,.9,y); b->SetFillColor(41); b->Draw(); y -= dy; b = new TGroupButton("DRAW1","L : Lines","AddOption("L")",x0,y-yb,.48,y); b->SetFillColor(31); b->Draw(); b = new TGroupButton("DRAW2","P : markers","AddOption("P")",.52,y-yb,.9,y); b->SetFillColor(31); b->Draw(); y -= dy; b = new TGroupButton("DRAW","ARR : arrows","AddOption("ARR")",x0,y-yb,.48,y); b->SetFillColor(31); b->Draw(); b = new TGroupButton("DRAW","BOX : boxes","AddOption("BOX")",.52,y-yb,.9,y); b->SetFillColor(31); b->Draw(); y -= dy; b = new TGroupButton("DRAW","COL: colors","AddOption("COL")",x0,y-yb,.48,y); b->SetFillColor(31); b->Draw(); b = new TGroupButton("DRAW","TEXT : values","AddOption("TEXT")",.52,y-yb,.9,y); b->SetFillColor(31); b->Draw(); y -= dy; b = new TGroupButton("SAME","Same Picture","SetSame()",x0,y-yb,.48,y); b->SetFillColor(43); b->Draw(); char cmd[64]; if (fHistogram) { sprintf(cmd,"drawpanel: %s",fHistogram->GetName()); SetTitle(cmd); } Modified(kTRUE); Update(); SetEditable(kFALSE); //add this TDrawPanelHist to the list of cleanups such that in case //the referenced object is deleted, its pointer be reset gROOT->GetListOfCleanups()->Add(this); fRefPad->cd(); } //______________________________________________________________________________ TDrawPanelHist::~TDrawPanelHist() { // DrawPanelHist destructor. gROOT->GetListOfCleanups()->Remove(this); } //______________________________________________________________________________ void TDrawPanelHist::AddOption(Option_t *option) { // Add option to the current list of options. fOption += option; } //______________________________________________________________________________ void TDrawPanelHist::Apply(const char *action) { // Collect all options and draw histogram. if (!fHistogram) return; if (!fRefPad) return; fRefPad->cd(); SetCursor(kWatch); if (!strcmp(action,"Defaults")) { SetDefaults(); SetCursor(kCross); return; } // take into account slider to set the histogram range; TObject *obj; TGroupButton *button; TIter next(fPrimitives); while ((obj = next())) { if (obj->InheritsFrom(TGroupButton::Class())) { button = (TGroupButton*)obj; if (button->GetBorderMode() < 0) button->ExecuteAction(); } } TH1 *h1; if (fHistogram->InheritsFrom("TF1")) { h1 = (TH1*)((TF1*)fHistogram)->GetHistogram(); } else if (fHistogram->InheritsFrom("TH1")) { h1 = (TH1*)fHistogram; } else { h1 = 0; } if (h1) { Int_t nbins = h1->GetXaxis()->GetNbins(); Int_t first = 1 + Int_t(nbins*fSlider->GetMinimum()); Int_t last = Int_t(nbins*fSlider->GetMaximum()); h1->GetXaxis()->SetRange(first,last); } Int_t keep = fHistogram->TestBit(kCanDelete); fHistogram->SetBit(kCanDelete,0); fHistogram->Draw((char*)fOption.Data()); fHistogram->SetBit(kCanDelete,keep); fOption = ""; fRefPad->Update(); SetCursor(kCross); } //______________________________________________________________________________ void TDrawPanelHist::BuildStandardButtons() { // Create Draw, Defaults and Close buttons. TGroupButton *b = new TGroupButton("APPLY","Draw","",.05,.01,.3,.09); b->SetTextSize(0.55); b->SetBorderSize(3); b->SetFillColor(44); b->Draw(); b = new TGroupButton("APPLY","Defaults","",.375,.01,.625,.09); b->SetTextSize(0.55); b->SetBorderSize(3); b->SetFillColor(44); b->Draw(); b = new TGroupButton("APPLY","Close","",.70,.01,.95,.09); b->SetTextSize(0.55); b->SetBorderSize(3); b->SetFillColor(44); b->Draw(); } //______________________________________________________________________________ void TDrawPanelHist::ExecuteEvent(Int_t event, Int_t px, Int_t py) { // Control mousse events when slider is used in a drawpanel // // This function is called by TPad::ExecuteEvent or TSliderBox::ExecuteEvent // We return in the first case. // When called by the slider, px = 0 and py = 0 //if (event == kMouseLeave || event == kMouseEnter || (px && py)) { if (px && py) { SetCursor(kCross); return; } Float_t xpmin = fSlider->GetMinimum(); Float_t xpmax = fSlider->GetMaximum(); static TH1 *h1; static Bool_t done = kFALSE; static Int_t px1,py1,px2,py2,nbins; static Int_t pxmin,pxmax; static Float_t xmin,xmax,ymin,ymax,xleft,xright; Int_t first,last; if (!fRefPad) return; fRefPad->cd(); switch (event) { case kButton1Down: fRefPad->GetCanvas()->FeedbackMode(kTRUE); gVirtualX->SetLineWidth(2); gVirtualX->SetLineColor(-1); if (done) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); done = kTRUE; if (fHistogram->InheritsFrom("TF1")) { h1 = (TH1*)((TF1*)fHistogram)->GetHistogram(); } else if (fHistogram->InheritsFrom("TH1")) { h1 = (TH1*)fHistogram; } else { h1 = 0; break; } nbins = h1->GetXaxis()->GetNbins(); xmin = fRefPad->GetUxmin(); xmax = fRefPad->GetUxmax(); xleft = xmin+(xmax-xmin)*xpmin; xright= xmin+(xmax-xmin)*xpmax; ymin = fRefPad->GetUymin(); ymax = fRefPad->GetUymax(); px1 = fRefPad->XtoAbsPixel(xleft); py1 = fRefPad->YtoAbsPixel(ymin); px2 = fRefPad->XtoAbsPixel(xright); py2 = fRefPad->YtoAbsPixel(ymax); pxmin = fRefPad->XtoAbsPixel(xmin); pxmax = fRefPad->XtoAbsPixel(xmax); gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); break; case kMouseMotion: break; case kButton1Motion: if (h1 == 0) break; gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); first = 1 + Int_t(nbins*xpmin); last = Int_t(nbins*xpmax); xleft = fRefPad->XtoPad(h1->GetXaxis()->GetBinLowEdge(first)); xright = fRefPad->XtoPad(h1->GetXaxis()->GetBinLowEdge(last)+h1->GetXaxis()->GetBinWidth(last)); px1 = fRefPad->XtoAbsPixel(xleft); px2 = fRefPad->XtoAbsPixel(xright); if (px1 < pxmin) px1 = pxmin; if (px2 > pxmax) px2 = pxmax; gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); break; case kButton1Up: gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); done = kFALSE; fRefPad->GetCanvas()->FeedbackMode(kFALSE); gVirtualX->SetLineWidth(-1); break; } } //______________________________________________________________________________ void TDrawPanelHist::RecursiveRemove(TObject *obj) { // when obj is deleted, clear fHistogram if fHistogram=obj TDialogCanvas::RecursiveRemove(obj); if (obj == fHistogram) fHistogram = 0; } //______________________________________________________________________________ void TDrawPanelHist::SavePrimitive(ofstream &, Option_t *) { // Save this drawpanel in a macro. } //______________________________________________________________________________ void TDrawPanelHist::SetDefaults() { // Set default draw panel options. fOption = ""; fRefPad = (TPad*)gROOT->GetSelectedPad(); fRefObject = this; fHistogram = gROOT->GetSelectedPrimitive(); TIter next(fPrimitives); TObject *obj; TGroupButton *button; while ((obj = next())) { if (obj == this) continue; if (obj->InheritsFrom(TGroupButton::Class())) { button = (TGroupButton*)obj; if (button->GetBorderMode() < 0) { button->SetBorderMode(1); button->Modified(); } } } fSlider->SetRange(0,1); char cmd[64]; if (fHistogram) { sprintf(cmd,"drawpanel: %s",fHistogram->GetName()); SetTitle(cmd); } Modified(); Update(); } //______________________________________________________________________________ void TDrawPanelHist::SetSame() { // Set graphics option "same". AddOption("same"); }