Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TH2Editor.cxx
Go to the documentation of this file.
1 // @(#)root/ged:$Id$
2 // Author: Carsten Hof 09/08/04
3 // Authors mail: Carsten_Hof@web.de
4 
5 /*************************************************************************
6  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
7  * All rights reserved. *
8  * *
9  * For the licensing terms see $ROOTSYS/LICENSE. *
10  * For the list of contributors see $ROOTSYS/README/CREDITS. *
11  *************************************************************************/
12 
13 //////////////////////////////////////////////////////////////////////////
14 // //
15 // TH2Editor //
16 // Editor for changing TH2 histogram attributes, rebinning & fitting. //
17 // For all possible draw options (there are a few which are not imple- //
18 // mentable in a graphical user interface) see THistPainter::Paint in //
19 // root/histpainter/THistPainter.cxx //
20 //
21 //Begin_Html
22 /*
23 <img src="gif/TH2Editor_1.gif">
24 */
25 //End_Html
26 //Begin_Html
27 /*
28 <img src="gif/TH2Editor_2.gif">
29 */
30 //End_Html
31 // These changes can be made via the TH2Editor: //
32 // Style Tab: //
33 // 'Line' : change Line attributes (color, thickness) //
34 // see TAttLineEditor //
35 // 'Fill' : change Fill attributes (color, pattern) //
36 // see TAttFillEditor //
37 // 'Title' : TextEntry: set the title of the histogram //
38 // 'Histogram': change the draw options of the histogram //
39 // 'Plot' : Radiobutton: draw a 2D or 3D plot of the histogram //
40 // according to the Plot dimension there will be //
41 // different drawing possibilities (ComboBoxes/ //
42 // CheckBoxes) //
43 // 2d Plot: //
44 // 'Contour' : ComboBox: draw a contour plot (None, Cont0..4) //
45 // 'Cont #' : TGNumberEntry: set the number of Contours //
46 // 2d Plot checkboxes: //
47 // 'Arrow' : arrow mode. Shows gradient between adjacent cells //
48 // 'Col' : a box is drawn for each cell with a color scale //
49 // varying with contents //
50 // 'Text' : Draw bin contents as text //
51 // 'Box' : a box is drawn for each cell with surface //
52 // proportional to contents //
53 // 'Scat' : Draw a scatter-plot (default) //
54 // 'Palette' : the color palette is drawn //
55 // //
56 // 3d Plot: //
57 // 'Type' : ComboBox: set histogram type Lego or Surface-Plot //
58 // draw(Lego, Lego1..4, Surf, Surf1..5) //
59 // see THistPainter::Paint //
60 // 'Coords' : ComboBox: set the coordinate system (Cartesian, .. //
61 // Spheric) see THistPainter::Paint //
62 // 'Cont #' : TGNumberEntry: set the number of Contours (for e.g. //
63 // Lego2 drawoption //
64 // 3d Plot checkboxes: //
65 // 'Errors' : draw errors in a cartesian lego plot //
66 // 'Palette' : the color palette is drawn //
67 // 'Front' : draw the front box of a cartesian lego plot //
68 // 'Back' : draw the back box of a cartesian lego plot //
69 // Available for a 3D lego plot: //
70 // 'Bar' : change the bar attributes //
71 // 'W' : change Bar Width //
72 // 'O' : change Bar Offset //
73 // Further Editor: //
74 // 'Marker' : change the Marker attributes (color, appearance, //
75 // thickness) see TAttMarkerEditor //
76 // //
77 //Begin_Html
78 /*
79 <img src="gif/TH2Editor1_1.gif">
80 */
81 //End_Html
82 //Begin_Html
83 /*
84 <img src="gif/TH2Editor1_2.gif">
85 */
86 //End_Html
87 // //
88 // Rebinning Tab: //
89 // This Tab has two different layouts. One is for a histogram which//
90 // is not drawn from an ntuple. The other one is available for a //
91 // histogram which is drawn from an ntuple. In this case the rebin //
92 // algorithm can create a rebinned histogram from the original data//
93 // i.e. the ntuple. //
94 // To see te differences do for example: //
95 // TFile f("hsimple.root"); //
96 // hpxpy->Draw("Lego2"); // non ntuple histogram //
97 // ntuple->Draw("px:py","","Lego2"); // ntuple histogram //
98 // Non ntuple histogram: //
99 // 'Rebin': with the Sliders (one for the x, one for the y axis) //
100 // the number of bins (shown in the field below the //
101 // Slider) can be changed to any number which divides //
102 // the number of bins of the original histogram. //
103 // Pushing 'Apply' will delete the origin histogram and //
104 // replace it by the rebinned one on the screen. //
105 // Pushing 'Ignore' the origin histogram will be restored//
106 // Histogram drawn from an ntuple: //
107 // 'Rebin' with the sliders the number of bins can be enlarged by//
108 // a factor of 2,3,4,5 (moving to the right) or reduced //
109 // by a factor of 1/2, 1/3, 1/4, 1/5 //
110 // 'BinOffset': with the BinOffset slider the origin of the //
111 // histogram can be changed within one binwidth //
112 // Using this slider the effect of binning the data into //
113 // bins can be made visible => statistical fluctuations //
114 // 'Axis Range': with the DoubleSlider it is possible to zoom into//
115 // the specified axis range. It is also possible to set //
116 // the upper and lower limit in fields below the slider //
117 // 'Delayed drawing': all the Binning sliders can be set to delay //
118 // draw mode. Then the changes on the histogram are only //
119 // updated, when the Slider is released. This should be //
120 // activated if the redrawing of the histogram is too //
121 // time consuming. //
122 //////////////////////////////////////////////////////////////////////////
123 
124 
125 #include "TH2Editor.h"
126 #include "TGedEditor.h"
127 #include "TGComboBox.h"
128 #include "TGTextEntry.h"
129 #include "TGToolTip.h"
130 #include "TGLabel.h"
131 #include "TVirtualPad.h"
132 #include "TStyle.h"
133 #include "TString.h"
134 #include "TGButtonGroup.h"
135 #include "TGNumberEntry.h"
136 #include "TG3DLine.h"
137 #include "TGDoubleSlider.h"
138 #include "TGSlider.h"
139 #include "TView.h"
140 #include "TCanvas.h"
141 #include "TGedPatternSelect.h"
142 #include "TGColorSelect.h"
143 #include "TColor.h"
144 #include "TTreePlayer.h"
145 #include "TSelectorDraw.h"
146 #include "TGTab.h"
147 #include "TGMsgBox.h"
148 #include "TH2.h"
149 #include "TROOT.h"
150 
151 
152 ClassImp(TH2Editor);
153 
154 enum ETH2Wid {
155  kTH2_TITLE,
156  kDIM_SIMPLE, kDIM_COMPLEX, kHIST_TYPE,
157  kTYPE_LEGO, kTYPE_LEGO1, kTYPE_LEGO2, kTYPE_LEGO3, kTYPE_LEGO4,
158  kTYPE_SURF, kTYPE_SURF1, kTYPE_SURF2, kTYPE_SURF3, kTYPE_SURF4, kTYPE_SURF5,
159  kCOORD_TYPE, kCOORDS_CAR, kCOORDS_CYL, kCOORDS_POL, kCOORDS_PSR, kCOORDS_SPH,
160  kCONT_TYPE, kERROR_ONOFF, kPALETTE_ONOFF, kPALETTE_ONOFF1,
161  kARROW_ONOFF,kBOX_ONOFF, kSCAT_ONOFF, kCOL_ONOFF, kTEXT_ONOFF,
162  kFRONTBOX_ONOFF, kBACKBOX_ONOFF,
163  kBAR_WIDTH, kBAR_OFFSET,
164  kCONT_NONE, kCONT_0, kCONT_1, kCONT_2, kCONT_3, kCONT_4,
165  kCONT_LEVELS, kCONT_LEVELS1,
166  kSLIDERX_MIN, kSLIDERX_MAX, kSLIDERY_MIN, kSLIDERY_MAX,
167  kDELAYED_DRAWING, kCOLOR, kPATTERN,
168  kBINXSLIDER, kBINYSLIDER, kBINXSLIDER1, kBINYSLIDER1,
169  kXBINOFFSET, kYBINOFFSET
170 };
171 
172 ////////////////////////////////////////////////////////////////////////////////
173 /// Constructor of histogram attribute GUI.
174 
175 TH2Editor::TH2Editor(const TGWindow *p, Int_t width,
176  Int_t height, UInt_t options, Pixel_t back)
177  : TGedFrame(p, width, height, options | kVerticalFrame, back),
178  fHist(0),
179  fBin(0),
180  fBinHist(0)
181 {
182  MakeTitle("Title");
183 
184  // Histogram title
185  fTitlePrec = 2;
186  fTitle = new TGTextEntry(this, new TGTextBuffer(50), kTH2_TITLE);
187  fTitle->Resize(135, fTitle->GetDefaultHeight());
188  fTitle->SetToolTipText("Enter the histogram title string");
189  AddFrame(fTitle, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 5));
190 
191 
192  // 2D or 3D Plot?
193  TGCompositeFrame *f2 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame);
194  fDimGroup = new TGHButtonGroup(f2,"Plot");
195  fDim = new TGRadioButton(fDimGroup,"2-D",kDIM_SIMPLE);
196  fDim->SetToolTipText("A 2-d plot of the histogram is dawn");
197  fDim0 = new TGRadioButton(fDimGroup,"3-D",kDIM_COMPLEX);
198  fDim0->SetToolTipText("A 3-d plot of the histogram is dawn");
199  fDimGroup->SetLayoutHints(fDimlh=new TGLayoutHints(kLHintsLeft ,-2,3,3,-7),fDim);
200  fDimGroup->SetLayoutHints(fDim0lh=new TGLayoutHints(kLHintsLeft ,16,-1,3,-7),fDim0);
201  fDimGroup->Show();
202  fDimGroup->ChangeOptions(kFitWidth|kChildFrame|kHorizontalFrame);
203  f2->AddFrame(fDimGroup, new TGLayoutHints(kLHintsTop, 4, 1, 0, 0));
204  AddFrame(f2, new TGLayoutHints(kLHintsTop, 1, 1, 2, 5));
205 
206  // 2D Plot drawoptions
207  f6 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame);
208  AddFrame(f6, new TGLayoutHints(kLHintsTop, 3, 1, 4, 2));
209 
210  TGCompositeFrame *f7 = new TGCompositeFrame(f6, 40, 20);
211  f6->AddFrame(f7, new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
212 
213  TGLabel *fAddLabel = new TGLabel(f7, "Contour:");
214  f7->AddFrame(fAddLabel, new TGLayoutHints(kLHintsLeft, 6, 4, 4, 4));
215 
216  fColContLbl = new TGLabel(f7, "Cont #:");
217  f7->AddFrame(fColContLbl, new TGLayoutHints( kLHintsLeft, 6, 4, 4, 4));
218 
219  fAddArr = new TGCheckButton(f7, "Arrow", kARROW_ONOFF);
220  fAddArr ->SetToolTipText("Shows gradient between adjacent cells");
221  f7->AddFrame(fAddArr, new TGLayoutHints(kLHintsLeft, 6, 1, 2, 0));
222 
223  fAddCol = new TGCheckButton(f7, "Col", kCOL_ONOFF);
224  fAddCol ->SetToolTipText("A box is drawn for each cell with a color scale varying with contents");
225  f7->AddFrame(fAddCol, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0));
226 
227  fAddText = new TGCheckButton(f7, "Text", kTEXT_ONOFF);
228  fAddText ->SetToolTipText("Draw bin contents as text");
229  f7->AddFrame(fAddText, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 3));
230 
231  TGCompositeFrame *f8 = new TGCompositeFrame(f6, 40, 20, kVerticalFrame);
232  f6->AddFrame(f8, new TGLayoutHints(kLHintsLeft, 5, 1, 0, 0));
233 
234  fContCombo = BuildHistContComboBox(f8, kCONT_TYPE);
235  f8->AddFrame(fContCombo, new TGLayoutHints(kLHintsLeft, 6, 1, 2, 1));
236  fContCombo->Resize(61, 20);
237  fContCombo->Associate(this);
238 
239  fContLevels = new TGNumberEntry(f8, 20, 0, kCONT_LEVELS,
240  TGNumberFormat::kNESInteger,
241  TGNumberFormat::kNEANonNegative,
242  TGNumberFormat::kNELLimitMinMax, 1, 99);
243  f8->AddFrame(fContLevels, new TGLayoutHints(kLHintsLeft, 6, 1, 3, 1));
244  fContLevels->GetNumberEntry()->SetToolTipText("Set number of contours (1..99)");
245  fContLevels->Resize(60,20);
246 
247  fAddBox = new TGCheckButton(f8, "Box", kBOX_ONOFF);
248  fAddBox ->SetToolTipText("A box is drawn for each cell with surface proportional to contents");
249  f8->AddFrame(fAddBox, new TGLayoutHints(kLHintsLeft, 6, 1, 3, 0));
250 
251  fAddScat = new TGCheckButton(f8, "Scat", kSCAT_ONOFF);
252  fAddScat ->SetToolTipText("Draw a scatter-plot");
253  f8->AddFrame(fAddScat, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0));
254 
255  fAddPalette = new TGCheckButton(f8, "Palette", kPALETTE_ONOFF);
256  fAddPalette ->SetToolTipText("Add color palette beside the histogram");
257  f8->AddFrame(fAddPalette, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0));
258 
259  f9 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame);
260  AddFrame(f9, new TGLayoutHints(kLHintsTop, 3, 1, 2, 0));
261 
262  TGCompositeFrame *f10 = new TGCompositeFrame(f9, 40, 20);
263  f9->AddFrame(f10, new TGLayoutHints(kLHintsLeft, 0, 0, 3, 0));
264 
265  TGLabel *fType = new TGLabel(f10, "Type:");
266  f10->AddFrame(fType, new TGLayoutHints(kLHintsNormal, 1, 1, 1, 1));
267 
268  TGLabel *fCoords = new TGLabel(f10, "Coords:");
269  f10->AddFrame(fCoords, new TGLayoutHints(kLHintsLeft, 1, 1, 5, 1));
270 
271  fColContLbl1 = new TGLabel(f10, "Cont #:");
272  f10->AddFrame(fColContLbl1, new TGLayoutHints( kLHintsLeft, 1, 1, 5, 3));
273 
274  fAddFB = new TGCheckButton(f10, "Front", kFRONTBOX_ONOFF);
275  fAddFB ->SetToolTipText("Supress the drawing of the front box");
276  f10->AddFrame(fAddFB, new TGLayoutHints(kLHintsLeft, 0, 1, 6, 0));
277  fAddBB = new TGCheckButton(f10, "Back", kBACKBOX_ONOFF);
278  fAddBB ->SetToolTipText("Supress the drawing of the back box");
279  f10->AddFrame(fAddBB, new TGLayoutHints(kLHintsLeft, 0, 1, 3, 0));
280 
281  TGCompositeFrame *f11 = new TGCompositeFrame(f9, 40, 20);
282  f9->AddFrame(f11, new TGLayoutHints(kLHintsLeft, 5, 1, 0, 0));
283 
284  fTypeCombo = BuildHistTypeComboBox(f11, kHIST_TYPE);
285  f11->AddFrame(fTypeCombo, new TGLayoutHints(kLHintsLeft, 0, 1, 2, 1));
286  fTypeCombo->Resize(80, 20);
287  fTypeCombo->Associate(this);
288 
289  fCoordsCombo = BuildHistCoordsComboBox(f11, kCOORD_TYPE);
290  f11->AddFrame(fCoordsCombo, new TGLayoutHints(kLHintsLeft, 0, 1, 2, 1));
291  fCoordsCombo->Resize(80, 20);
292  fCoordsCombo->Associate(this);
293 
294  fContLevels1 = new TGNumberEntry(f11, 20, 0, kCONT_LEVELS1,
295  TGNumberFormat::kNESInteger,
296  TGNumberFormat::kNEANonNegative,
297  TGNumberFormat::kNELLimitMinMax, 1, 99);
298  fContLevels1->GetNumberEntry()->SetToolTipText("Set number of contours (1..99)");
299  fContLevels1->Resize(78,20);
300  f11->AddFrame(fContLevels1, new TGLayoutHints(kLHintsLeft, 0, 1, 2, 1));
301 
302  fAddError = new TGCheckButton(f11, "Errors", kERROR_ONOFF);
303  fAddError ->SetToolTipText("Add color palette beside the histogram");
304  f11->AddFrame(fAddError, new TGLayoutHints(kLHintsLeft, 0, 1, 4, 0));
305  fAddPalette1 = new TGCheckButton(f11, "Palette", kPALETTE_ONOFF1);
306  fAddPalette1 ->SetToolTipText("Add color palette beside the histogram");
307  f11->AddFrame(fAddPalette1, new TGLayoutHints(kLHintsLeft, 0, 1, 3, 0));
308 
309 
310  // Bin bar settings
311  f12 = new TGCompositeFrame(this, 145, 10, kHorizontalFrame |
312  kLHintsExpandX |
313  kFixedWidth |
314  kOwnBackground);
315  f12->AddFrame(new TGLabel(f12,"Bar"),
316  new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
317  f12->AddFrame(new TGHorizontal3DLine(f12),
318  new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
319  AddFrame(f12, new TGLayoutHints(kLHintsTop,0,0,6,4));
320 
321  f13 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame);
322  TGLabel *fWidthLbl = new TGLabel(f13, "W:");
323  f13->AddFrame(fWidthLbl, new TGLayoutHints( kLHintsLeft, 1, 3, 4, 1));
324  fBarWidth = new TGNumberEntry(f13, 1.00, 6, kBAR_WIDTH,
325  TGNumberFormat::kNESRealTwo,
326  TGNumberFormat::kNEANonNegative,
327  TGNumberFormat::kNELLimitMinMax, 0.01, 1.);
328  fBarWidth->GetNumberEntry()->SetToolTipText("Set bar chart width");
329  fBarWidth->Resize(45,20);
330  f13->AddFrame(fBarWidth, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 1));
331 
332  TGLabel *fOffsetLbl = new TGLabel(f13, "O:");
333  f13->AddFrame(fOffsetLbl, new TGLayoutHints(kLHintsLeft, 6,3, 4, 1));
334  fBarOffset = new TGNumberEntry(f13, 0.00, 5, kBAR_OFFSET,
335  TGNumberFormat::kNESRealTwo,
336  TGNumberFormat::kNEAAnyNumber,
337  TGNumberFormat::kNELLimitMinMax, -1., 1.);
338  fBarOffset->GetNumberEntry()->SetToolTipText("Set bar chart offset");
339  fBarOffset->Resize(50,20);
340  f13->AddFrame(fBarOffset, new TGLayoutHints(kLHintsLeft, 1, 1, 2, 1));
341  AddFrame(f13, new TGLayoutHints(kLHintsTop, 1, 1, 0, 4));
342 
343 
344  // Set the color and pattern of the Frame (only for Cartesian 3D plot).
345  f38 = new TGCompositeFrame(this, 80, 20, kVerticalFrame);
346  TGCompositeFrame *f39 = new TGCompositeFrame(f38, 145, 10, kHorizontalFrame |
347  kLHintsExpandX |
348  kFixedWidth |
349  kOwnBackground);
350  f39->AddFrame(new TGLabel(f39,"Frame Fill"),
351  new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
352  f39->AddFrame(new TGHorizontal3DLine(f39),
353  new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
354  f38->AddFrame(f39, new TGLayoutHints(kLHintsTop,0,0,6,1));
355 
356  TGCompositeFrame *f21 = new TGCompositeFrame(f38, 80, 20, kHorizontalFrame);
357  fFrameColor = new TGColorSelect(f21, 0, kCOLOR);
358  f21->AddFrame(fFrameColor, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 0));
359  fFrameColor->Associate(f38);
360  fFramePattern = new TGedPatternSelect(f21, 1, kPATTERN);
361  f21->AddFrame(fFramePattern, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 0));
362  fFramePattern->Associate(f38);
363  f38->AddFrame(f21, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0));
364  AddFrame(f38, new TGLayoutHints(kLHintsTop));
365 
366  fCutString = "";
367 
368  CreateBinTab();
369 
370  // add itself in the least of cleanups to be notified when attached histogram is deleted
371  gROOT->GetListOfCleanups()->Add(this);
372 }
373 
374 ////////////////////////////////////////////////////////////////////////////////
375 /// Create the Binning tab.
376 
377 void TH2Editor::CreateBinTab()
378 {
379  fBin = CreateEditorTabSubFrame("Binning");
380 
381  // Editor for rebinning a histogram which does NOT derive from an Ntuple
382  fBinXCont = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame);
383  TGCompositeFrame *title1 = new TGCompositeFrame(fBinXCont, 145, 10,
384  kHorizontalFrame |
385  kLHintsExpandX |
386  kFixedWidth |
387  kOwnBackground);
388  title1->AddFrame(new TGLabel(title1, "Rebin"),
389  new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
390  title1->AddFrame(new TGHorizontal3DLine(title1),
391  new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
392  fBinXCont->AddFrame(title1, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0));
393 
394  TGCompositeFrame *f22 = new TGCompositeFrame(fBinXCont, 80, 20,
395  kHorizontalFrame);
396  TGLabel *binSliderXLbl = new TGLabel(f22,"x:");
397  f22->AddFrame(binSliderXLbl,
398  new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,0, 4, 1));
399  fBinXSlider = new TGHSlider(f22, 100, kSlider1 | kScaleBoth);
400  fBinXSlider->Resize(107,20);
401  f22->AddFrame(fBinXSlider, new TGLayoutHints(kLHintsLeft, 2,0,0,3));
402  fBinXCont->AddFrame(f22, new TGLayoutHints(kLHintsTop, 3, 7, 3, 5));
403 
404  TGCompositeFrame *f23 = new TGCompositeFrame(fBinXCont, 80, 20,
405  kHorizontalFrame);
406  TGLabel *binXLabel1 = new TGLabel(f23, "# of Bins:");
407  f23->AddFrame(binXLabel1, new TGLayoutHints(kLHintsLeft, 20, 1, 2, 1));
408  fBinXNumberEntry = new TGNumberEntryField(f23, kBINXSLIDER, 0.0,
409  TGNumberFormat::kNESInteger);
410  ((TGTextEntry*)fBinXNumberEntry)->SetToolTipText("Set the number of x axis bins in the rebinned histogram");
411  fBinXNumberEntry->Resize(57,20);
412  f23->AddFrame(fBinXNumberEntry, new TGLayoutHints(kLHintsRight, 8, 0, 0, 0));
413  fBinXCont->AddFrame(f23, new TGLayoutHints(kLHintsTop, 0, 7, 3, 4));
414 
415  TGCompositeFrame *f37 = new TGCompositeFrame(fBinXCont, 80, 20,
416  kHorizontalFrame);
417  TGLabel *binSliderYLbl = new TGLabel(f37,"y:");
418  f37->AddFrame(binSliderYLbl,
419  new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,0, 4, 1));
420  fBinYSlider = new TGHSlider(f37, 100, kSlider1 | kScaleBoth);
421  fBinYSlider->Resize(107,20);
422  f37->AddFrame(fBinYSlider, new TGLayoutHints(kLHintsLeft, 1,0,0,3));
423  fBinXCont->AddFrame(f37, new TGLayoutHints(kLHintsTop, 3, 7, 3, 5));
424 
425  TGCompositeFrame *f36 = new TGCompositeFrame(fBinXCont, 80, 20,
426  kHorizontalFrame);
427  TGLabel *binYLabel1 = new TGLabel(f36, "# of Bins:");
428  f36->AddFrame(binYLabel1, new TGLayoutHints(kLHintsLeft, 20, 1, 2, 1));
429  fBinYNumberEntry = new TGNumberEntryField(f36, kBINYSLIDER, 0.0,
430  TGNumberFormat::kNESInteger);
431  ((TGTextEntry*)fBinYNumberEntry)->SetToolTipText("Set the number of y axis bins in the rebinned histogram");
432  fBinYNumberEntry->Resize(57,20);
433  f36->AddFrame(fBinYNumberEntry, new TGLayoutHints(kLHintsRight, 8, 0, 0, 0));
434  fBinXCont->AddFrame(f36, new TGLayoutHints(kLHintsTop, 0, 7, 3, 4));
435 
436  // Text buttons Apply & Ignore for rebinned histogram shown on the screen.
437  TGCompositeFrame *f24 = new TGCompositeFrame(fBinXCont, 118, 20,
438  kHorizontalFrame |
439  kFixedWidth);
440  fApply = new TGTextButton(f24, " &Apply ");
441  f24->AddFrame(fApply,
442  new TGLayoutHints(kLHintsExpandX | kLHintsLeft ,0, 3, 4, 4));
443  fCancel = new TGTextButton(f24, " &Ignore ");
444  f24->AddFrame(fCancel,
445  new TGLayoutHints(kLHintsExpandX | kLHintsLeft, 3, 0, 4, 4));
446  fBinXCont->AddFrame(f24, new TGLayoutHints(kLHintsTop, 20, 3, 3, 4));
447  fBin->AddFrame(fBinXCont,new TGLayoutHints(kLHintsTop));
448 
449  // Widgets for rebinning a histogram which derives from an Ntuple
450 
451  fBinXCont1 = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame);
452  TGCompositeFrame *title2 = new TGCompositeFrame(fBinXCont1, 145, 10,
453  kHorizontalFrame |
454  kLHintsExpandX |
455  kFixedWidth |
456  kOwnBackground);
457  title2->AddFrame(new TGLabel(title2, "X-Axis"),
458  new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
459  title2->AddFrame(new TGHorizontal3DLine(title2),
460  new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
461  fBinXCont1->AddFrame(title2, new TGLayoutHints(kLHintsTop, 0, 0, 2, 0));
462 
463  TGCompositeFrame *f26 = new TGCompositeFrame(fBinXCont1, 80, 20,
464  kHorizontalFrame);
465  fBinXSlider1 = new TGHSlider(f26, 100, kSlider1 | kScaleBoth);
466  fBinXSlider1->Resize(120,20);
467  fBinXSlider1->SetRange(1,9);
468  fBinXSlider1->SetScale(14);
469  fBinXSlider1->SetPosition(5);
470  f26->AddFrame(fBinXSlider1, new TGLayoutHints(kLHintsLeft, 2,0,0,0));
471  fBinXCont1->AddFrame(f26, new TGLayoutHints(kLHintsTop, 3, 7, 3, 0));
472 
473  // Lettering of the Rebin Slider
474  TGCompositeFrame *f27 = new TGCompositeFrame(fBinXCont1, 80, 20,
475  kHorizontalFrame);
476  TGLabel *l1 = new TGLabel(f27, "-5");
477  f27->AddFrame(l1, new TGLayoutHints(kLHintsLeft, 5, 1, -1, 0));
478  TGLabel *l2 = new TGLabel(f27, "-2");
479  f27->AddFrame(l2, new TGLayoutHints(kLHintsLeft, 31, 2, -1, 0));
480  TGLabel *l3 = new TGLabel(f27, "2");
481  f27->AddFrame(l3, new TGLayoutHints(kLHintsLeft, 21, 2, -1, 0));
482  TGLabel *l4 = new TGLabel(f27, "5");
483  f27->AddFrame(l4, new TGLayoutHints(kLHintsLeft, 36, 3, -1, 0));
484  fBinXCont1->AddFrame(f27, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0));
485 
486  TGCompositeFrame *f28 = new TGCompositeFrame(fBinXCont1, 140, 20,
487  kHorizontalFrame);
488  TGLabel *binXLabel2 = new TGLabel(f28, "# of Bins:");
489  f28->AddFrame(binXLabel2, new TGLayoutHints(kLHintsLeft, 8, 1, 4, 1));
490 
491  fBinXNumberEntry1 = new TGNumberEntryField(f28, kBINXSLIDER1, 0.0,
492  TGNumberFormat::kNESInteger);
493  ((TGTextEntry*)fBinXNumberEntry1)->SetToolTipText("Set the number of x axis bins in the rebinned histogram");
494  fBinXNumberEntry1->Resize(57,20);
495  f28->AddFrame(fBinXNumberEntry1,
496  new TGLayoutHints(kLHintsLeft, 21, 0, 2, 0));
497  fBinXCont1->AddFrame(f28, new TGLayoutHints(kLHintsTop, 0, 7, 2, 4));
498 
499  TGCompositeFrame *f29 = new TGCompositeFrame(fBinXCont1, 80, 20,
500  kHorizontalFrame);
501  TGLabel *xOffsetLbl = new TGLabel(f29, "BinOffset:");
502  f29->AddFrame(xOffsetLbl, new TGLayoutHints(kLHintsLeft, 7, 1, 2, 1));
503  fXOffsetNumberEntry = new TGNumberEntryField(f29, kXBINOFFSET, 0.0,
504  TGNumberFormat::kNESRealFour,
505  TGNumberFormat::kNEAAnyNumber,
506  TGNumberFormat::kNELLimitMinMax,
507  0., 1.);
508  ((TGTextEntry*)fXOffsetNumberEntry)->SetToolTipText("Add an x-offset to the origin of the histogram");
509  fXOffsetNumberEntry->Resize(57,20);
510  f29->AddFrame(fXOffsetNumberEntry,
511  new TGLayoutHints(kLHintsRight, 21, 0, 0, 0));
512  fBinXCont1->AddFrame(f29, new TGLayoutHints(kLHintsTop, 0, 7, 3, 1));
513 
514  TGCompositeFrame *f30 = new TGCompositeFrame(fBinXCont1, 80, 20,
515  kHorizontalFrame);
516  fXBinOffsetSld = new TGHSlider(f30, 100, kSlider1 | kScaleBoth);
517  fXBinOffsetSld->Resize(120,20);
518  f30->AddFrame(fXBinOffsetSld, new TGLayoutHints(kLHintsLeft, 2,0,0,0));
519  fBinXCont1->AddFrame(f30, new TGLayoutHints(kLHintsTop, 3, 7, 3, 3));
520  fBin->AddFrame(fBinXCont1, new TGLayoutHints(kLHintsTop));
521 
522  // Same for Y-Axis:
523  // Widgets for rebinning a histogram which derives from an Ntuple
524 
525  fBinYCont1 = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame);
526  TGCompositeFrame *title3 = new TGCompositeFrame(fBinYCont1, 145, 10,
527  kHorizontalFrame |
528  kLHintsExpandX |
529  kFixedWidth |
530  kOwnBackground);
531  title3->AddFrame(new TGLabel(title3, "Y-Axis"),
532  new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
533  title3->AddFrame(new TGHorizontal3DLine(title3),
534  new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
535  fBinYCont1->AddFrame(title3, new TGLayoutHints(kLHintsTop, 0, 0, 7, 0));
536 
537  TGCompositeFrame *f31 = new TGCompositeFrame(fBinYCont1, 80, 20,
538  kHorizontalFrame);
539  fBinYSlider1 = new TGHSlider(f31, 100, kSlider1 | kScaleBoth);
540  fBinYSlider1->Resize(120,20);
541  fBinYSlider1->SetRange(1,9);
542  fBinYSlider1->SetScale(14);
543  fBinYSlider1->SetPosition(5);
544  f31->AddFrame(fBinYSlider1, new TGLayoutHints(kLHintsLeft, 2,0,0,0));
545  fBinYCont1->AddFrame(f31, new TGLayoutHints(kLHintsTop, 3, 7, 3, 0));
546 
547  // Lettering of the Rebin Slider
548  TGCompositeFrame *f32 = new TGCompositeFrame(fBinYCont1, 80, 20,
549  kHorizontalFrame);
550  TGLabel *l5 = new TGLabel(f32, "-5");
551  f32->AddFrame(l5, new TGLayoutHints(kLHintsLeft, 5, 1, -1, 0));
552  TGLabel *l6 = new TGLabel(f32, "-2");
553  f32->AddFrame(l6, new TGLayoutHints(kLHintsLeft, 31, 2, -1, 0));
554  TGLabel *l7 = new TGLabel(f32, "2");
555  f32->AddFrame(l7, new TGLayoutHints(kLHintsLeft, 21, 2, -1, 0));
556  TGLabel *l8 = new TGLabel(f32, "5");
557  f32->AddFrame(l8, new TGLayoutHints(kLHintsLeft, 36, 3, -1, 0));
558  fBinYCont1->AddFrame(f32, new TGLayoutHints(kLHintsTop, 0, 0, 0, 0));
559 
560  TGCompositeFrame *f33 = new TGCompositeFrame(fBinYCont1, 140, 20,
561  kHorizontalFrame);
562  TGLabel *binYLabel2 = new TGLabel(f33, "# of Bins:");
563  f33->AddFrame(binYLabel2, new TGLayoutHints(kLHintsLeft, 8, 1, 4, 1));
564 
565  fBinYNumberEntry1 = new TGNumberEntryField(f33, kBINYSLIDER1, 0.0,
566  TGNumberFormat::kNESInteger);
567  ((TGTextEntry*)fBinYNumberEntry1)->SetToolTipText("Set the number of Y axis bins in the rebinned histogram");
568  fBinYNumberEntry1->Resize(57,20);
569  f33->AddFrame(fBinYNumberEntry1,
570  new TGLayoutHints(kLHintsLeft, 21, 0, 2, 0));
571  fBinYCont1->AddFrame(f33, new TGLayoutHints(kLHintsTop, 0, 7, 2, 4));
572 
573  TGCompositeFrame *f34 = new TGCompositeFrame(fBinYCont1, 80, 20,
574  kHorizontalFrame);
575  TGLabel *yOffsetLbl = new TGLabel(f34, "BinOffset:");
576  f34->AddFrame(yOffsetLbl, new TGLayoutHints(kLHintsLeft, 7, 1, 2, 1));
577  fYOffsetNumberEntry = new TGNumberEntryField(f34, kYBINOFFSET, 0.0,
578  TGNumberFormat::kNESRealFour,
579  TGNumberFormat::kNEAAnyNumber,
580  TGNumberFormat::kNELLimitMinMax,
581  0., 1.);
582  ((TGTextEntry*)fYOffsetNumberEntry)->SetToolTipText("Add an Y-offset to the origin of the histogram");
583  fYOffsetNumberEntry->Resize(57,20);
584  f34->AddFrame(fYOffsetNumberEntry,
585  new TGLayoutHints(kLHintsRight, 21, 0, 0, 0));
586  fBinYCont1->AddFrame(f34, new TGLayoutHints(kLHintsTop, 0, 7, 3, 1));
587 
588  TGCompositeFrame *f35 = new TGCompositeFrame(fBinYCont1, 80, 20,
589  kHorizontalFrame);
590  fYBinOffsetSld = new TGHSlider(f35, 100, kSlider1 | kScaleBoth);
591  fYBinOffsetSld->Resize(120,20);
592  fYBinOffsetSld->Associate(f35);
593  f35->AddFrame(fYBinOffsetSld, new TGLayoutHints(kLHintsLeft, 2,0,0,0));
594  fBinYCont1->AddFrame(f35, new TGLayoutHints(kLHintsTop, 3, 7, 3, 3));
595  fBin->AddFrame(fBinYCont1, new TGLayoutHints(kLHintsTop));
596 
597  // Axis ranges
598  TGCompositeFrame *title4 = new TGCompositeFrame(fBin, 145, 10,
599  kHorizontalFrame |
600  kLHintsExpandX |
601  kFixedWidth |
602  kOwnBackground);
603  title4->AddFrame(new TGLabel(title4, "Axis Range"),
604  new TGLayoutHints(kLHintsLeft, 1, 1, 0, 0));
605  title4->AddFrame(new TGHorizontal3DLine(title4),
606  new TGLayoutHints(kLHintsExpandX, 5, 5, 7, 7));
607  fBin->AddFrame(title4, new TGLayoutHints(kLHintsTop, 0, 0, 5, 0));
608 
609  TGCompositeFrame *f14 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame);
610  TGLabel *fSliderXLbl = new TGLabel(f14,"x:");
611  f14->AddFrame(fSliderXLbl,
612  new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,3, 2, 1));
613  fSliderX = new TGDoubleHSlider(f14, 1, 2);
614  fSliderX->Resize(119,20);
615  f14->AddFrame(fSliderX, new TGLayoutHints(kLHintsLeft));
616  fBin->AddFrame(f14, new TGLayoutHints(kLHintsTop, 3, 7, 4, 1));
617 
618  TGCompositeFrame *f17 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame);
619  fSldXMin = new TGNumberEntryField(f17, kSLIDERX_MIN, 0.0,
620  TGNumberFormat::kNESRealTwo,
621  TGNumberFormat::kNEAAnyNumber);
622  ((TGTextEntry*)fSldXMin)->SetToolTipText("Set the minimum value of the x-axis");
623  fSldXMin->Resize(57,20);
624  f17->AddFrame(fSldXMin, new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0));
625  fSldXMax = new TGNumberEntryField(f17, kSLIDERX_MAX, 0.0,
626  TGNumberFormat::kNESRealTwo,
627  TGNumberFormat::kNEAAnyNumber);
628  ((TGTextEntry*)fSldXMax)->SetToolTipText("Set the maximum value of the x-axis");
629  fSldXMax->Resize(57,20);
630  f17->AddFrame(fSldXMax, new TGLayoutHints(kLHintsLeft, 4, 0, 0, 0));
631  fBin->AddFrame(f17, new TGLayoutHints(kLHintsTop, 20, 3, 5, 0));
632 
633  TGCompositeFrame *f15 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame);
634  TGLabel *fSliderYLbl = new TGLabel(f15,"y:");
635  f15->AddFrame(fSliderYLbl,
636  new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 4,2, 4, 1));
637  fSliderY = new TGDoubleHSlider(f15, 1, 2);
638  fSliderY->Resize(119,20);
639  f15->AddFrame(fSliderY, new TGLayoutHints(kLHintsLeft));
640  fBin->AddFrame(f15, new TGLayoutHints(kLHintsTop, 3, 7, 4, 1));
641 
642  TGCompositeFrame *f18 = new TGCompositeFrame(fBin, 80, 20, kHorizontalFrame);
643  fSldYMin = new TGNumberEntryField(f18, kSLIDERY_MIN, 0.0,
644  TGNumberFormat::kNESRealTwo,
645  TGNumberFormat::kNEAAnyNumber);
646  ((TGTextEntry*)fSldYMin)->SetToolTipText("Set the minimum value of the y-axis");
647  fSldYMin->Resize(57,20);
648  f18->AddFrame(fSldYMin, new TGLayoutHints(kLHintsLeft, 0, 0, 0, 0));
649  fSldYMax = new TGNumberEntryField(f18, kSLIDERY_MAX, 0.0,
650  TGNumberFormat::kNESRealTwo,
651  TGNumberFormat::kNEAAnyNumber);
652  ((TGTextEntry*)fSldYMax)->SetToolTipText("Set the maximum value of the y-axis");
653  fSldYMax->Resize(57,20);
654  f18->AddFrame(fSldYMax, new TGLayoutHints(kLHintsLeft, 4, 0, 0, 0));
655  fBin->AddFrame(f18, new TGLayoutHints(kLHintsTop, 20, 3, 5, 0));
656 
657  TGCompositeFrame *f20 = new TGCompositeFrame(fBin, 80, 20, kVerticalFrame);
658  fDelaydraw = new TGCheckButton(f20, "Delayed drawing", kDELAYED_DRAWING);
659  fDelaydraw ->SetToolTipText("Draw the new axis range when the Slider is released");
660  f20->AddFrame(fDelaydraw, new TGLayoutHints(kLHintsLeft, 6, 1, 1, 0));
661  fBin->AddFrame(f20, new TGLayoutHints(kLHintsTop, 2, 1, 5, 3));
662 
663  fXBinOffsetSld->SetRange(0,100);
664  fXBinOffsetSld->SetPosition(0);
665  fXOffsetNumberEntry->SetNumber(0.0000);
666 
667  fYBinOffsetSld->SetRange(0,100);
668  fYBinOffsetSld->SetPosition(0);
669  fYOffsetNumberEntry->SetNumber(0.0000);
670 
671  fCancel->SetState(kButtonDisabled);
672  fApply->SetState(kButtonDisabled);
673 
674 }
675 
676 ////////////////////////////////////////////////////////////////////////////////
677 /// Destructor.
678 
679 TH2Editor::~TH2Editor()
680 {
681  // remove itselef from the list of cleanups
682  gROOT->GetListOfCleanups()->Remove(this);
683 
684  // children of TGButonGroup are not deleted
685  delete fDim;
686  delete fDim0;
687  delete fDimlh;
688  delete fDim0lh;
689 
690  if (fBinHist) delete fBinHist;
691  fBinHist = 0;
692 }
693 
694 ////////////////////////////////////////////////////////////////////////////////
695 /// Connect signals to slots.
696 
697 void TH2Editor::ConnectSignals2Slots()
698 {
699  fTitle->Connect("TextChanged(const char *)", "TH2Editor", this, "DoTitle(const char *)");
700  fDimGroup->Connect("Clicked(Int_t)","TH2Editor",this,"DoHistView()");
701  fTypeCombo->Connect("Selected(Int_t)", "TH2Editor", this, "DoHistChanges()");
702  fCoordsCombo->Connect("Selected(Int_t)", "TH2Editor", this, "DoHistChanges()");
703  fContCombo->Connect("Selected(Int_t)", "TH2Editor", this, "DoHistChanges()");
704  fAddArr->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddArr(Bool_t)");
705  fAddBox->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddBox(Bool_t)");
706  fAddCol->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddCol(Bool_t)");
707  fAddScat->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddScat(Bool_t)");
708  fAddText->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddText(Bool_t)");
709  fAddError->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddError(Bool_t)");
710  fAddPalette->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddPalette(Bool_t)");
711  fAddPalette1->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddPalette(Bool_t)");
712  fAddFB->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddFB()");
713  fAddBB->Connect("Toggled(Bool_t)", "TH2Editor", this, "DoAddBB()");
714  fContLevels->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoContLevel()");
715  (fContLevels->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor",
716  this,"DoContLevel()");
717  fContLevels1->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoContLevel1()");
718  (fContLevels1->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor",
719  this,"DoContLevel1()");
720  fBarWidth->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoBarWidth()");
721  (fBarWidth->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor",
722  this, "DoBarWidth()");
723  fBarOffset->Connect("ValueSet(Long_t)", "TH2Editor", this, "DoBarOffset()");
724  (fBarOffset->GetNumberEntry())->Connect("ReturnPressed()", "TH2Editor",
725  this, "DoBarOffset()");
726  fBinXSlider->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved()");
727  fBinXSlider->Connect("Released()","TH2Editor",this, "DoBinReleased()");
728  fBinXSlider->Connect("Pressed()","TH2Editor",this, "DoBinPressed()");
729  fBinYSlider->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved()");
730  fBinYSlider->Connect("Released()","TH2Editor",this, "DoBinReleased()");
731  fBinYSlider->Connect("Pressed()","TH2Editor",this, "DoBinPressed()");
732  fBinXNumberEntry->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel()");
733  fBinYNumberEntry->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel()");
734  fApply->Connect("Clicked()", "TH2Editor", this, "DoApply()");
735  fCancel->Connect("Pressed()", "TH2Editor", this, "DoCancel()");
736  fBinXSlider1->Connect("Released()","TH2Editor",this, "DoBinReleased1()");
737  fBinXSlider1->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved1()");
738  fBinXNumberEntry1->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel1()");
739  fXBinOffsetSld->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoOffsetMoved()");
740  fXBinOffsetSld->Connect("Released()","TH2Editor",this, "DoOffsetReleased()");
741  fXBinOffsetSld->Connect("Pressed()","TH2Editor",this, "DoOffsetPressed()");
742  fXOffsetNumberEntry->Connect("ReturnPressed()", "TH2Editor", this, "DoBinOffset()");
743  fBinYSlider1->Connect("Released()","TH2Editor",this, "DoBinReleased1()");
744  fBinYSlider1->Connect("PositionChanged(Int_t)","TH2Editor",this, "DoBinMoved1()");
745  fBinYNumberEntry1->Connect("ReturnPressed()", "TH2Editor", this, "DoBinLabel1()");
746  fYBinOffsetSld->Connect("PositionChanged(Int_t)","TH2Editor",this,"DoOffsetMoved()");
747  fYBinOffsetSld->Connect("Released()","TH2Editor",this, "DoOffsetReleased()");
748  fYBinOffsetSld->Connect("Pressed()","TH2Editor",this, "DoOffsetPressed()");
749  fYOffsetNumberEntry->Connect("ReturnPressed()", "TH2Editor", this,"DoBinOffset()");
750  fSliderX->Connect("PositionChanged()","TH2Editor",this, "DoSliderXMoved()");
751  fSliderX->Connect("Pressed()","TH2Editor",this, "DoSliderXPressed()");
752  fSliderX->Connect("Released()","TH2Editor",this, "DoSliderXReleased()");
753  fSldXMin->Connect("ReturnPressed()", "TH2Editor", this, "DoXAxisRange()");
754  fSldXMax->Connect("ReturnPressed()", "TH2Editor", this, "DoXAxisRange()");
755  fSliderY->Connect("PositionChanged()","TH2Editor",this, "DoSliderYMoved()");
756  fSliderY->Connect("Pressed()","TH2Editor",this, "DoSliderYPressed()");
757  fSliderY->Connect("Released()","TH2Editor",this, "DoSliderYReleased()");
758  fSldYMin->Connect("ReturnPressed()", "TH2Editor", this, "DoYAxisRange()");
759  fSldYMax->Connect("ReturnPressed()", "TH2Editor", this, "DoYAxisRange()");
760  fFrameColor->Connect("ColorSelected(Pixel_t)", "TH2Editor", this, "DoFillColor(Pixel_t)");
761  fFramePattern->Connect("PatternSelected(Style_t)", "TH2Editor", this, "DoFillPattern(Style_t)");
762 
763  fInit = kFALSE;
764 }
765 
766 ////////////////////////////////////////////////////////////////////////////////
767 /// Check if object is able to configure with this editor.
768 
769 Bool_t TH2Editor::AcceptModel(TObject* obj)
770 {
771  if (obj == 0 || !obj->InheritsFrom(TH2::Class()) ||
772  (!strcmp(((TH2 *)obj)->GetName(),"htemp") &&
773  ((TH2*)obj)->GetEntries() == 0)) { // htemp is an empty histogram
774  return kFALSE;
775  }
776  return kTRUE;
777 }
778 
779 ////////////////////////////////////////////////////////////////////////////////
780 /// Pick up the values of current histogram attributes.
781 
782 void TH2Editor::SetModel(TObject* obj)
783 {
784  fAvoidSignal = kTRUE;
785  if (fBinHist && (obj != fHist)) {
786  //we have probably moved to a different pad.
787  //let's restore the original histogram
788  if (fHist) {
789  fHist->Reset();
790  fHist->SetBins(fBinHist->GetXaxis()->GetNbins(),
791  fBinHist->GetXaxis()->GetXmin(),
792  fBinHist->GetXaxis()->GetXmax(),
793  fBinHist->GetYaxis()->GetNbins(),
794  fBinHist->GetYaxis()->GetXmin(),
795  fBinHist->GetYaxis()->GetXmax());
796  fHist->Add(fBinHist);
797  }
798  // delete in anycase fBinHist also when fHist is zero (i.e when it has been deleted)
799  delete fBinHist;
800  fBinHist = 0;
801  if (fGedEditor->GetPad()) {
802  fGedEditor->GetPad()->Modified();
803  fGedEditor->GetPad()->Update();
804  }
805  }
806 
807  fHist = (TH2*) obj;
808 
809  const char *text = fHist->GetTitle();
810  fTitle->SetText(text);
811  TString str = GetDrawOption();
812  fCutString = GetCutOptionString();
813  str.ToUpper();
814 
815  if (str == "") {
816  // default options = Scatter-Plot
817  ShowFrame(f6);
818  HideFrame(f9);
819  HideFrame(f12);
820  HideFrame(f13);
821  HideFrame(f38);
822  fDimGroup->SetButton(kDIM_SIMPLE, kTRUE);
823  fDimGroup->SetButton(kDIM_COMPLEX, kFALSE);
824  if (fTypeCombo->GetSelected()==-1) fTypeCombo->Select(kTYPE_LEGO);
825  if (fCoordsCombo->GetSelected()==-1) fCoordsCombo->Select(kCOORDS_CAR);
826  if (fContCombo->GetSelected()==-1) fContCombo->Select(kCONT_NONE);
827 
828  fAddArr->SetState(kButtonUp);
829  fAddBox->SetState(kButtonUp);
830  fAddCol->SetState(kButtonUp);
831  fAddScat->SetState(kButtonDisabled);
832  fAddText->SetState(kButtonUp);
833  fAddError->SetState(kButtonUp);
834  fAddPalette->SetState(kButtonDisabled);
835  fAddPalette1->SetState(kButtonUp);
836  fAddFB->SetState(kButtonDown);
837  fAddBB->SetState(kButtonDown);
838  } else if (!str.Contains("LEGO") && !str.Contains("SURF")) {
839  ShowFrame(f6);
840  HideFrame(f9);
841  HideFrame(f12);
842  HideFrame(f13);
843  HideFrame(f38);
844  fDimGroup->SetButton(kDIM_SIMPLE, kTRUE);
845  fDimGroup->SetButton(kDIM_COMPLEX, kFALSE);
846  if (fTypeCombo->GetSelected()==-1) fTypeCombo->Select(kTYPE_LEGO);
847  if (fCoordsCombo->GetSelected()==-1) fCoordsCombo->Select(kCOORDS_CAR);
848  if (str.Contains("CONT")){
849  if (str.Contains("CONT1")) fContCombo->Select(kCONT_1);
850  else if (str.Contains("CONT2")) fContCombo->Select(kCONT_2);
851  else if (str.Contains("CONT3")) fContCombo->Select(kCONT_3);
852  else if (str.Contains("CONT4")) fContCombo->Select(kCONT_4);
853  else if (str.Contains("CONT0") || str.Contains("CONT"))
854  fContCombo->Select(kCONT_0);
855  } else fContCombo->Select(kCONT_NONE);
856 
857  if (str.Contains("ARR")) fAddArr->SetState(kButtonDown);
858  else fAddArr->SetState(kButtonUp);
859  if (str.Contains("BOX")) fAddBox->SetState(kButtonDown);
860  else fAddBox->SetState(kButtonUp);
861  if (str.Contains("COL")) fAddCol->SetState(kButtonDown);
862  else fAddCol->SetState(kButtonUp);
863  if (str.Contains("SCAT")) {
864  if (str=="SCAT") fAddScat->SetState(kButtonDisabled);
865  else fAddScat->SetState(kButtonDown);
866  } else fAddScat->SetState(kButtonUp);
867  if (str.Contains("TEXT")) fAddText->SetState(kButtonDown);
868  else fAddText->SetState(kButtonUp);
869 
870  fAddError->SetState(kButtonUp);
871  if (str.Contains("COL") || (str.Contains("CONT") &&
872  !str.Contains("CONT2") && !str.Contains("CONT3"))) {
873  if (str.Contains("Z")) fAddPalette->SetState(kButtonDown);
874  else fAddPalette->SetState(kButtonUp);
875  } else fAddPalette->SetState(kButtonDisabled);
876  fAddPalette1->SetState(kButtonUp);
877  fAddFB->SetState(kButtonDown);
878  fAddBB->SetState(kButtonDown);
879 
880  } else if (str.Contains("LEGO") || str.Contains("SURF")) {
881  HideFrame(f6);
882  ShowFrame(f9);
883  ShowFrame(f12);
884  ShowFrame(f13);
885  ShowFrame(f38);
886  fDimGroup->SetButton(kDIM_COMPLEX, kTRUE);
887  fDimGroup->SetButton(kDIM_SIMPLE, kFALSE);
888  if (str.Contains("LEGO4")) fTypeCombo->Select(kTYPE_LEGO4);
889  else if (str.Contains("LEGO3")) fTypeCombo->Select(kTYPE_LEGO3);
890  else if (str.Contains("LEGO2")) fTypeCombo->Select(kTYPE_LEGO2);
891  else if (str.Contains("LEGO1")) fTypeCombo->Select(kTYPE_LEGO1);
892  else if (str.Contains("LEGO")) fTypeCombo->Select(kTYPE_LEGO);
893  else if (str.Contains("SURF5")) fTypeCombo->Select(kTYPE_SURF5);
894  else if (str.Contains("SURF4")) fTypeCombo->Select(kTYPE_SURF4);
895  else if (str.Contains("SURF3")) fTypeCombo->Select(kTYPE_SURF3);
896  else if (str.Contains("SURF2")) fTypeCombo->Select(kTYPE_SURF2);
897  else if (str.Contains("SURF1")) fTypeCombo->Select(kTYPE_SURF1);
898  else if (str.Contains("SURF")) fTypeCombo->Select(kTYPE_SURF);
899 
900 
901  if (str.Contains("CYL")) fCoordsCombo->Select(kCOORDS_CYL);
902  else if (str.Contains("POL")) fCoordsCombo->Select(kCOORDS_POL);
903  else if (str.Contains("SPH")) fCoordsCombo->Select(kCOORDS_SPH);
904  else if (str.Contains("PSR")) fCoordsCombo->Select(kCOORDS_PSR);
905  else fCoordsCombo->Select(kCOORDS_CAR); //default
906 
907  if (fContCombo->GetSelected()==-1) fContCombo->Select(kCONT_NONE);
908  fAddArr->SetState(kButtonUp);
909  fAddBox->SetState(kButtonUp);
910  fAddCol->SetState(kButtonUp);
911  fAddScat->SetState(kButtonDisabled);
912  fAddText->SetState(kButtonUp);
913 
914  if (fCoordsCombo->GetSelected()!=kCOORDS_CAR) {
915  if (fAddFB->GetState()!=kButtonDisabled)
916  fAddFB->SetState(kButtonDisabled);
917  if (fAddBB->GetState()!=kButtonDisabled)
918  fAddBB->SetState(kButtonDisabled);
919  if (fAddError->GetState()!=kButtonDisabled)
920  fAddError->SetState(kButtonDisabled);
921  } else {
922  if (str.Contains("FB")) fAddFB->SetState(kButtonUp);
923  else fAddFB->SetState(kButtonDown);
924  if (str.Contains("BB")) fAddBB->SetState(kButtonUp);
925  else fAddBB->SetState(kButtonDown);
926  if (str.Contains("E")){
927  TString dum = str;
928  if (str.Contains("LEGO"))
929  dum.Remove(strstr(dum.Data(),"LEGO")-dum.Data(),4);
930  if (str.Contains("TEXT"))
931  dum.Remove(strstr(dum.Data(),"TEXT")-dum.Data(),4);
932  if (dum.Contains("E")) fAddError->SetState(kButtonDown);
933  else fAddError->SetState(kButtonUp);
934  } else fAddError->SetState(kButtonUp);
935  }
936  if ((fTypeCombo->GetSelected()==kTYPE_LEGO) ||
937  (fTypeCombo->GetSelected()==kTYPE_LEGO1)||
938  (fTypeCombo->GetSelected()==kTYPE_LEGO3)||
939  (fTypeCombo->GetSelected()==kTYPE_LEGO4)||
940  (fTypeCombo->GetSelected()==kTYPE_SURF) ||
941  (fTypeCombo->GetSelected()==kTYPE_SURF4))
942  fAddPalette1->SetState(kButtonDisabled);
943  else if (str.Contains("Z")) fAddPalette1->SetState(kButtonDown);
944  else fAddPalette1->SetState(kButtonUp);
945  }
946 
947  fBarWidth->SetNumber(fHist->GetBarWidth());
948  fBarOffset->SetNumber(fHist->GetBarOffset());
949 
950  Int_t nx = fHist -> GetXaxis() -> GetNbins();
951  Int_t nxbinmin = fHist -> GetXaxis() -> GetFirst();
952  Int_t nxbinmax = fHist -> GetXaxis() -> GetLast();
953  fSliderX->SetRange(1,nx);
954  fSliderX->SetPosition((Double_t)nxbinmin,(Double_t)nxbinmax);
955  fSldXMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge(nxbinmin));
956  fSldXMax->SetNumber(fHist->GetXaxis()->GetBinUpEdge(nxbinmax));
957 
958  Int_t ny = fHist -> GetYaxis() -> GetNbins();
959  Int_t nybinmin = fHist -> GetYaxis() -> GetFirst();
960  Int_t nybinmax = fHist -> GetYaxis() -> GetLast();
961  fSliderY->SetRange(1,ny);
962  fSliderY->SetPosition((Double_t)nybinmin,(Double_t)nybinmax);
963  fSldYMin->SetNumber(fHist->GetYaxis()->GetBinLowEdge(nybinmin));
964  fSldYMax->SetNumber(fHist->GetYaxis()->GetBinUpEdge(nybinmax));
965 
966  if (fDelaydraw->GetState()!=kButtonDown) fDelaydraw->SetState(kButtonUp);
967 
968  if (str.Contains("COL") || fContCombo->GetSelected()!= kCONT_NONE)
969  fColContLbl->Enable() ;
970  else fColContLbl->Disable();
971 
972  if (str.Contains("LEGO2") || str.Contains("SURF1") ||
973  str.Contains("SURF2") || str.Contains("SURF3") ||
974  str.Contains("SURF5")) fColContLbl1->Enable();
975  else fColContLbl1->Disable();
976 
977  fContLevels->SetIntNumber(fHist->GetContour());
978  fContLevels1->SetIntNumber(fHist->GetContour());
979 
980  fFrameColor->SetColor(TColor::Number2Pixel(fGedEditor->GetPad()->GetFrameFillColor()));
981  fFramePattern->SetPattern(fGedEditor->GetPad()->GetFrameFillStyle());
982 
983  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
984 
985 
986  // Check if histogram is from ntupla/tree or not.
987  // If it is a standard histogram or a ntupla based histogram
988  // show a different frame in case of rebinning (fBinCont) with sliders and bin number entries
989  // connected to different methods.
990  // For example the entry field fBinXNumberEntry is connected to
991  // the method DoBinLabel in case of non-ntupla histograms which just call Th1::Rebin
992  // In csae of a tree based histogram the entry field fBinNumberEntry1 is used which is connected to
993  // TH1Editor::DoBinLabel1 which is re-filling the histograms with the cached values from the TTreePlayer.
994  // Since the actual number of histogram entry can be larger than the cache size of the TTreePlayer
995  // (see JIRA ROOT-5900 or http://root.cern.ch/phpBB3/viewtopic.php?f=3&t=17107 )
996  // the GUI frame based on a non-tupla histogram is used when the number of entries of the histogram is
997  // not the same as the number of filled entries in the TTreePlayer object.
998 
999  if (!player || player->GetHistogram()!=fHist ||
1000  fHist->GetEntries() != player->GetNfill()) {
1001  Int_t n1 = 0, n2 =0;
1002  Int_t upx =0, upy =0;
1003  if (fBinHist) n1 = fBinHist->GetXaxis()->GetNbins();
1004  else n1 = nx;
1005  if (fBinHist) n2 = fBinHist->GetYaxis()->GetNbins();
1006  else n2 = ny;
1007  fBin->HideFrame(fBinXCont1);
1008  fBin->ShowFrame(fBinXCont);
1009  fBin->HideFrame(fBinYCont1);
1010  if (n1 < 1) n1 = 1;
1011  if (n2 < 1) n2 = 1;
1012  Int_t* divx = Dividers(n1);
1013  Int_t* divy = Dividers(n2);
1014  if (divx[0]-1 <= 1) upx = 2;
1015  else upx = divx[0]-1;
1016  fBinXSlider->SetRange(1,upx);
1017  if (divy[0]-1 <= 1) upy = 2;
1018  else upy = divy[0]-1;
1019  fBinYSlider->SetRange(1,upy);
1020  Int_t i = 1; Int_t j = 1;
1021  if (fBinXSlider->GetMaxPosition()==2 && fBinXSlider->GetPosition()==2)
1022  fBinXSlider->SetPosition(2);
1023  else {
1024  while ( divx[i] != nx) i ++;
1025  fBinXSlider->SetPosition(divx[0] - i + 1);
1026  }
1027  if (fBinYSlider->GetMaxPosition()==2 && fBinYSlider->GetPosition()==2)
1028  fBinYSlider->SetPosition(2);
1029  else {
1030  while ( divy [j] != ny) j ++;
1031  fBinYSlider->SetPosition(divy[0] - j + 1);
1032  }
1033  fBinXNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 2, n1);
1034  fBinXNumberEntry->SetIntNumber(nx);
1035  fBinYNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 2, n2);
1036  fBinYNumberEntry->SetIntNumber(ny);
1037  delete [] divx;
1038  delete [] divy;
1039  }
1040  else if (player && fHist==player->GetHistogram() && fHist->GetEntries() == player->GetNfill()) {
1041  fBin->HideFrame(fBinXCont);
1042  fBin->ShowFrame(fBinXCont1);
1043  fBin->ShowFrame(fBinYCont1);
1044  fBinXSlider1->SetPosition(5);
1045  fBinXNumberEntry1->SetLimits(TGNumberFormat::kNELLimitMinMax, 1, 1000);
1046  fBinXNumberEntry1->SetIntNumber(nxbinmax-nxbinmin+1);
1047  fBinYSlider1->SetPosition(5);
1048  fBinYNumberEntry1->SetLimits(TGNumberFormat::kNELLimitMinMax, 1, 1000);
1049  fBinYNumberEntry1->SetIntNumber(nybinmax-nybinmin+1);
1050  }
1051 
1052  fXOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0,
1053  fHist->GetXaxis()->GetBinWidth(1));
1054  fYOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0,
1055  fHist->GetYaxis()->GetBinWidth(1));
1056  if (!fGedEditor->GetTab()->IsEnabled(fGedEditor->GetTab()->GetCurrent())) fGedEditor->GetTab()->SetTab(0);
1057 
1058  if (fInit) ConnectSignals2Slots();
1059  fGedEditor->GetTab()->SetEnabled(1, kTRUE);
1060  fAvoidSignal = kFALSE;
1061 
1062 }
1063 
1064 ////////////////////////////////////////////////////////////////////////////////
1065 /// Slot connected to the histogram title setting.
1066 
1067 void TH2Editor::DoTitle(const char *text)
1068 {
1069  if (fAvoidSignal) return;
1070  fHist->SetTitle(text);
1071  Update();
1072 }
1073 
1074 ////////////////////////////////////////////////////////////////////////////////
1075 /// Slot connected to the 'Plot' button group.
1076 
1077 void TH2Editor::DoHistView()
1078 {
1079  if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kWatch);
1080  gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
1081 
1082  if (fDim->GetState() == kButtonDown)
1083  DoHistSimple();
1084  else
1085  DoHistComplex();
1086 
1087  if (gPad && gPad->GetVirtCanvas()) gPad->GetVirtCanvas()->SetCursor(kPointer);
1088  gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
1089 }
1090 
1091 ////////////////////////////////////////////////////////////////////////////////
1092 /// Slot connected to the 2D-Plot radio button.
1093 
1094 void TH2Editor::DoHistSimple()
1095 {
1096  if (fAvoidSignal) return;
1097  TString str = "";
1098  ShowFrame(f6);
1099  HideFrame(f9);
1100  HideFrame(f12);
1101  HideFrame(f13);
1102  HideFrame(f38);
1103  if (fContCombo->GetSelected()==-1)
1104  fContCombo->Select(kCONT_NONE);
1105  if ((fContCombo->GetSelected()!= kCONT_NONE) &&
1106  fAddPalette->GetState()==kButtonDisabled)
1107  fAddPalette->SetState(kButtonUp);
1108 
1109  str = GetHistContLabel()+GetHistAdditiveLabel();
1110  if (str=="" || str=="SCAT" || str==fCutString) {
1111  fAddScat->SetState(kButtonDisabled);
1112  fAddPalette->SetState(kButtonDisabled);
1113  } else if (fAddScat->GetState()==kButtonDisabled)
1114  fAddScat->SetState(kButtonUp);
1115  if (str.Contains("COL") || fContCombo->GetSelected()!= kCONT_NONE)
1116  fColContLbl->Enable();
1117  else fColContLbl->Disable();
1118 
1119  ((TGMainFrame*)GetMainFrame())->Layout();
1120 
1121  TString ocut = fCutString;
1122  ocut.ToUpper();
1123  if (!str.Contains(fCutString) && !str.Contains(ocut))
1124  str+=fCutString;
1125  SetDrawOption(str);
1126  Update();
1127 }
1128 
1129 ////////////////////////////////////////////////////////////////////////////////
1130 /// Slot connected to the 3D-Plot radio button.
1131 
1132 void TH2Editor::DoHistComplex()
1133 {
1134  if (fAvoidSignal) return;
1135  TString str = "";
1136  HideFrame(f6);
1137  ShowFrame(f9);
1138  ShowFrame(f38);
1139  if (GetHistTypeLabel().Contains("LEGO")) {
1140  ShowFrame(f12);
1141  ShowFrame(f13);
1142  } else {
1143  HideFrame(f12);
1144  HideFrame(f13);
1145  }
1146  if (fTypeCombo->GetSelected()==-1) fTypeCombo->Select(kTYPE_LEGO);
1147  if (fCoordsCombo->GetSelected()==-1) fCoordsCombo->Select(kCOORDS_CAR);
1148 
1149  str = GetHistTypeLabel()+GetHistCoordsLabel()+GetHistAdditiveLabel();
1150 
1151  if (str.Contains("LEGO2") || str.Contains("SURF1") ||
1152  str.Contains("SURF2") || str.Contains("SURF3") ||
1153  str.Contains("SURF5")) {
1154  fColContLbl1->Enable();
1155  if (fAddPalette1->GetState()==kButtonDisabled)
1156  fAddPalette1->SetState(kButtonUp);
1157  } else {
1158  fColContLbl1->Disable();
1159  fAddPalette1->SetState(kButtonDisabled);
1160  }
1161 
1162  ((TGMainFrame*)GetMainFrame())->Layout();
1163 
1164  TString ocut = fCutString;
1165  ocut.ToUpper();
1166  if (!str.Contains(fCutString) && !str.Contains(ocut))
1167  str+=fCutString;
1168  SetDrawOption(str);
1169  Update();
1170 }
1171 
1172 ////////////////////////////////////////////////////////////////////////////////
1173 /// Slot connected to histogram type, coordinate system, contour combo box.
1174 
1175 void TH2Editor::DoHistChanges()
1176 {
1177  if (fAvoidSignal) return;
1178  TString str = "";
1179  if (fDim->GetState() == kButtonDown) {
1180  str = GetHistContLabel()+GetHistAdditiveLabel();
1181  if ((fContCombo->GetSelected()!=kCONT_NONE &&
1182  fContCombo->GetSelected()!=kCONT_2 &&
1183  fContCombo->GetSelected()!=kCONT_3) || str.Contains("COL")) {
1184 
1185  if (str.Contains("Z")) fAddPalette->SetState(kButtonDown);
1186  else fAddPalette->SetState(kButtonUp);
1187  } else fAddPalette->SetState(kButtonDisabled);
1188  if (str=="" || str=="SCAT" || str==fCutString) {
1189  fAddScat->SetState(kButtonDisabled);
1190  fAddPalette->SetState(kButtonDisabled);
1191  } else if (fAddScat->GetState()==kButtonDisabled)
1192  fAddScat->SetState(kButtonUp);
1193  str = GetHistContLabel()+GetHistAdditiveLabel();
1194  if (str.Contains("COL") || fContCombo->GetSelected()!= kCONT_NONE)
1195  fColContLbl->Enable();
1196  else
1197  fColContLbl->Disable();
1198 
1199  } else if (fDim0->GetState() == kButtonDown) {
1200  if (fCoordsCombo->GetSelected()!=kCOORDS_CAR) {
1201  if (fAddFB->GetState()!=kButtonDisabled)
1202  fAddFB->SetState(kButtonDisabled);
1203  if (fAddBB->GetState()!=kButtonDisabled)
1204  fAddBB->SetState(kButtonDisabled);
1205  if (fAddError->GetState()!=kButtonDisabled)
1206  fAddError->SetState(kButtonDisabled);
1207  } else {
1208  if (fAddFB->GetState()==kButtonDisabled)
1209  fAddFB->SetState(kButtonDown);
1210  if (fAddBB->GetState()==kButtonDisabled)
1211  fAddBB->SetState(kButtonDown);
1212  if (fAddError->GetState()==kButtonDisabled)
1213  fAddError->SetState(kButtonUp);
1214  }
1215  if ((fTypeCombo->GetSelected()==kTYPE_LEGO) ||
1216  (fTypeCombo->GetSelected()==kTYPE_LEGO1)||
1217  (fTypeCombo->GetSelected()==kTYPE_LEGO3)||
1218  (fTypeCombo->GetSelected()==kTYPE_LEGO4)||
1219  (fTypeCombo->GetSelected()==kTYPE_SURF) ||
1220  (fTypeCombo->GetSelected()==kTYPE_SURF4))
1221  fAddPalette1->SetState(kButtonDisabled);
1222  else if (fAddPalette1->GetState()==kButtonDisabled)
1223  fAddPalette1->SetState(kButtonUp);
1224  if (GetHistTypeLabel().Contains("LEGO")) {
1225  ShowFrame(f12);
1226  ShowFrame(f13);
1227  } else {
1228  HideFrame(f12);
1229  HideFrame(f13);
1230  }
1231  ((TGMainFrame*)GetMainFrame())->Layout();
1232  str = GetHistTypeLabel()+GetHistCoordsLabel()+GetHistAdditiveLabel();
1233  if (str.Contains("LEGO2") || str.Contains("SURF1") ||
1234  str.Contains("SURF2") || str.Contains("SURF3") ||
1235  str.Contains("SURF5"))
1236  fColContLbl1->Enable();
1237  else
1238  fColContLbl1->Disable() ;
1239  }
1240 
1241  TString ocut = fCutString;
1242  ocut.ToUpper();
1243  if (!str.Contains(fCutString) && !str.Contains(ocut))
1244  str+=fCutString;
1245  SetDrawOption(str);
1246  Update();
1247 }
1248 
1249 ////////////////////////////////////////////////////////////////////////////////
1250 /// Slot connected to the "Arrow draw option" check button.
1251 
1252 void TH2Editor::DoAddArr(Bool_t on)
1253 {
1254  if (fAvoidSignal) return;
1255  Bool_t make=kFALSE;
1256  TString str = GetDrawOption();
1257  str.ToUpper();
1258 
1259  if (on) {
1260  if (!str.Contains("ARR")) {
1261  str += "ARR";
1262  if (fAddScat->GetState()==kButtonDisabled)
1263  fAddScat->SetState(kButtonUp);
1264  make=kTRUE;
1265  }
1266  } else if (fAddArr->GetState()==kButtonUp) {
1267  if (str.Contains("ARR")) {
1268  str.Remove(strstr(str.Data(),"ARR")-str.Data(),3);
1269  if (str=="" || str=="SCAT" || str==fCutString) {
1270  fAddScat->SetState(kButtonDisabled);
1271  fAddPalette->SetState(kButtonDisabled);
1272  }
1273  make=kTRUE;
1274  }
1275  }
1276  if (make) {
1277  DoHistChanges();
1278  }
1279 }
1280 
1281 ////////////////////////////////////////////////////////////////////////////////
1282 /// Slot connected to the "Box draw option" check button.
1283 
1284 void TH2Editor::DoAddBox(Bool_t on)
1285 {
1286  if (fAvoidSignal) return;
1287  Bool_t make=kFALSE;
1288  TString str = GetDrawOption();
1289  str.ToUpper();
1290 
1291  if (on) {
1292  if (!str.Contains("BOX")) {
1293  str += "BOX";
1294  if (fAddScat->GetState()==kButtonDisabled)
1295  fAddScat->SetState(kButtonUp);
1296  make=kTRUE;
1297  }
1298  } else if (fAddBox->GetState()==kButtonUp) {
1299  if (str.Contains("BOX")) {
1300  str.Remove(strstr(str.Data(),"BOX")-str.Data(),3);
1301  if (str=="" || str=="SCAT" || str==fCutString) {
1302  fAddScat->SetState(kButtonDisabled);
1303  fAddPalette->SetState(kButtonDisabled);
1304  }
1305  make=kTRUE;
1306  }
1307  }
1308  if (make) {
1309  DoHistChanges();
1310  }
1311 }
1312 
1313 ////////////////////////////////////////////////////////////////////////////////
1314 /// Slot connected to the "Col draw option" check button.
1315 
1316 void TH2Editor::DoAddCol(Bool_t on)
1317 {
1318  if (fAvoidSignal) return;
1319  Bool_t make=kFALSE;
1320  TString str = GetDrawOption();
1321  str.ToUpper();
1322 
1323  if (on) {
1324  if (!str.Contains("COL")) {
1325  str += "COL";
1326  fColContLbl->Enable() ;
1327  if (fAddScat->GetState()==kButtonDisabled)
1328  fAddScat->SetState(kButtonUp);
1329  if (fAddPalette->GetState()==kButtonDisabled)
1330  fAddPalette->SetState(kButtonUp);
1331  make=kTRUE;
1332  }
1333  } else if (fAddCol->GetState()==kButtonUp) {
1334  if (str.Contains("COL")) {
1335  str.Remove(strstr(str.Data(),"COL")-str.Data(),3);
1336  if (fAddBox->GetState()==kButtonDisabled)
1337  fAddBox->SetState(kButtonUp);
1338  if (fContCombo->GetSelected()==kCONT_NONE) {
1339  fAddPalette->SetState(kButtonDisabled);
1340  if (str.Contains("Z"))
1341  str.Remove(strstr(str.Data(),"Z")-str.Data(),1);
1342  }
1343  if (str=="" || str=="SCAT" || str==fCutString)
1344  fAddScat->SetState(kButtonDisabled);
1345  if (fContCombo->GetSelected()!= kCONT_NONE)
1346  fColContLbl->Enable() ;
1347  else fColContLbl->Disable();
1348  make=kTRUE;
1349  }
1350  }
1351  if (make) {
1352  DoHistChanges();
1353  }
1354 }
1355 
1356 ////////////////////////////////////////////////////////////////////////////////
1357 /// Slot connected to the "Scat draw option" check button.
1358 
1359 void TH2Editor::DoAddScat(Bool_t on)
1360 {
1361  if (fAvoidSignal) return;
1362  Bool_t make=kFALSE;
1363  TString str = GetDrawOption();
1364  str.ToUpper();
1365 
1366  if (on) {
1367  if (!str.Contains("SCAT")) {
1368  str += "SCAT";
1369  make=kTRUE;
1370  }
1371  } else if (fAddScat->GetState()==kButtonUp) {
1372  if (str.Contains("SCAT")) {
1373  str.Remove(strstr(str.Data(),"SCAT")-str.Data(),4);
1374  make=kTRUE;
1375  }
1376  }
1377  if (make) {
1378  DoHistChanges();
1379  }
1380 }
1381 
1382 ////////////////////////////////////////////////////////////////////////////////
1383 /// Slot connected to the "Text draw option" check button.
1384 
1385 void TH2Editor::DoAddText(Bool_t on)
1386 {
1387  if (fAvoidSignal) return;
1388  Bool_t make=kFALSE;
1389  TString str = GetDrawOption();
1390  str.ToUpper();
1391 
1392  if (on) {
1393  if (!str.Contains("TEXT")) {
1394  str += "TEXT";
1395  if (fAddScat->GetState()==kButtonDisabled)
1396  fAddScat->SetState(kButtonUp);
1397  make=kTRUE;
1398  }
1399  } else if (fAddText->GetState()==kButtonUp) {
1400  if (str.Contains("TEXT")) {
1401  str.Remove(strstr(str.Data(),"TEXT")-str.Data(),4);
1402  if (str=="" || str=="SCAT" || str==fCutString)
1403  fAddScat->SetState(kButtonDisabled);
1404  make=kTRUE;
1405  }
1406  }
1407  if (make) {
1408  DoHistChanges();
1409  // next line is needed for marker editor refresh
1410  fGedEditor->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 1);
1411  }
1412 }
1413 
1414 ////////////////////////////////////////////////////////////////////////////////
1415 /// Slot connected to the "Error" check button.
1416 
1417 void TH2Editor::DoAddError(Bool_t on)
1418 {
1419  if (fAvoidSignal) return;
1420  Bool_t make=kFALSE;
1421  TString str = GetDrawOption();
1422  str.ToUpper();
1423 
1424  TString dum = str;
1425  if (str.Contains("LEGO"))
1426  dum.Remove(strstr(dum.Data(),"LEGO")-dum.Data(),4);
1427  if (str.Contains("TEXT"))
1428  dum.Remove(strstr(dum.Data(),"TEXT")-dum.Data(),4);
1429  if (on) {
1430  if (!dum.Contains("E")) {
1431  str += "E";
1432  make=kTRUE;
1433  }
1434  } else if (fAddError->GetState() == kButtonUp) {
1435  if (str.Contains("E")) {
1436  if (fDim->GetState() == kButtonDown)
1437  str = GetHistContLabel()+GetHistAdditiveLabel();
1438  else
1439  str= GetHistTypeLabel()+GetHistCoordsLabel()+
1440  GetHistAdditiveLabel();
1441  make=kTRUE;
1442  }
1443  }
1444  if (make) {
1445  DoHistChanges();
1446  }
1447 }
1448 
1449 ////////////////////////////////////////////////////////////////////////////////
1450 /// Slot connected to the color palette check button.
1451 
1452 void TH2Editor::DoAddPalette(Bool_t on)
1453 {
1454  if (fAvoidSignal) return;
1455  Bool_t make=kFALSE;
1456  TString str = GetDrawOption();
1457  str.ToUpper();
1458 
1459  if (on) {
1460  if (!str.Contains("Z")) {
1461  str += "Z";
1462  make=kTRUE;
1463  }
1464  } else if (fAddPalette->GetState()==kButtonUp ||
1465  fAddPalette1->GetState()==kButtonUp) {
1466  if (str.Contains("Z")) {
1467  str.Remove(strstr(str.Data(),"Z")-str.Data(),1);
1468  make=kTRUE;
1469  }
1470  }
1471  if (make) {
1472  DoHistChanges();
1473  }
1474 }
1475 
1476 ////////////////////////////////////////////////////////////////////////////////
1477 /// Slot connected to the "FB front-box draw option" check button.
1478 
1479 void TH2Editor::DoAddFB()
1480 {
1481  if (fAvoidSignal) return;
1482  Bool_t make=kFALSE;
1483  TString str = GetDrawOption();
1484  str.ToUpper();
1485 
1486  if (fAddFB->GetState()==kButtonDown) {
1487  if (str.Contains("FB")) {
1488  if (str.Contains("SURF") && !(str.Contains("1") ||
1489  str.Contains("2") || str.Contains("3") ||
1490  str.Contains("4") || str.Contains("5"))) {
1491  TString dum = str;
1492  dum.Remove(strstr(dum.Data(),"SURF")-dum.Data(),4);
1493  if (dum.Contains("FB"))
1494  dum.Remove(strstr(dum.Data(),"FB")-dum.Data(),2);
1495  str = "SURF" + dum;
1496  } else str.Remove(strstr(str.Data(),"FB")-str.Data(),2);
1497  make = kTRUE;
1498  }
1499  } else if (fAddFB->GetState()==kButtonUp){
1500  if (!str.Contains("FB")) {
1501  str += "FB";
1502  make=kTRUE;
1503  }
1504  }
1505  if (make) {
1506  DoHistChanges();
1507  }
1508 }
1509 
1510 ////////////////////////////////////////////////////////////////////////////////
1511 /// Slot connected to the "BB back-box draw option" check button.
1512 
1513 void TH2Editor::DoAddBB()
1514 {
1515  if (fAvoidSignal) return;
1516  Bool_t make=kFALSE;
1517  TString str = GetDrawOption();
1518  str.ToUpper();
1519 
1520  if (fAddBB->GetState()==kButtonDown) {
1521  if (str.Contains("BB")) {
1522  if (str.Contains("FB")) {
1523  TString dum = str;
1524  dum.Remove(strstr(dum.Data(),"FB")-dum.Data(),2);
1525  dum.Remove(strstr(dum.Data(),"BB")-dum.Data(),2);
1526  str=dum+"FB";
1527  } else str.Remove(strstr(str.Data(),"BB")-str.Data(),2);
1528  make = kTRUE;
1529  }
1530  } else if (fAddBB->GetState()==kButtonUp){
1531  if (!str.Contains("BB")) {
1532  str += "BB";
1533  make=kTRUE;
1534  }
1535  }
1536  if (make) {
1537  DoHistChanges();
1538  }
1539 }
1540 
1541 ////////////////////////////////////////////////////////////////////////////////
1542 /// Slot connected to the contour level number entry fContLevels.
1543 
1544 void TH2Editor::DoContLevel()
1545 {
1546  if (fAvoidSignal) return;
1547  fHist->SetContour((Int_t)fContLevels->GetNumber());
1548  fContLevels1->SetNumber((Int_t)fContLevels->GetNumber());
1549  Update();
1550 }
1551 
1552 ////////////////////////////////////////////////////////////////////////////////
1553 /// Slot connected to the contour level number entry fContLevels1.
1554 
1555 void TH2Editor::DoContLevel1()
1556 {
1557  if (fAvoidSignal) return;
1558  fHist->SetContour((Int_t)fContLevels1->GetNumber());
1559  fContLevels->SetNumber((Int_t)fContLevels1->GetNumber());
1560  Update();
1561 }
1562 
1563 ////////////////////////////////////////////////////////////////////////////////
1564 /// Slot connected to the bar width of the bar chart.
1565 
1566 void TH2Editor::DoBarWidth()
1567 {
1568  if (fAvoidSignal) return;
1569  fHist->SetBarWidth(fBarWidth->GetNumber());
1570  Update();
1571 }
1572 
1573 ////////////////////////////////////////////////////////////////////////////////
1574 /// Slot connected to the bar offset of the bar chart.
1575 
1576 void TH2Editor::DoBarOffset()
1577 {
1578  if (fAvoidSignal) return;
1579  fHist->SetBarOffset((Float_t)fBarOffset->GetNumber());
1580  Update();
1581 }
1582 
1583 ////////////////////////////////////////////////////////////////////////////////
1584 /// Slot connected to the rebin slider in case of no ntuple histogram.
1585 /// It updates some other widgets related to the rebin slider.
1586 
1587 void TH2Editor::DoBinReleased()
1588 {
1589  // Draw the rebinned histogram in case of the delay draw mode
1590  if (fAvoidSignal) return;
1591  if (fDelaydraw->GetState()==kButtonDown){
1592  if (!fBinHist) {
1593  fBinHist = (TH2*)fHist->Clone("BinHist");
1594  fBinHist->SetDirectory(0); // TH2Editor manages this histogram
1595  }
1596  Int_t nx = fBinHist->GetXaxis()->GetNbins();
1597  Int_t ny = fBinHist->GetYaxis()->GetNbins();
1598  Int_t numx = fBinXSlider->GetPosition();
1599  Int_t numy = fBinYSlider->GetPosition();
1600  Int_t* divx = Dividers(nx);
1601  Int_t* divy = Dividers(ny);
1602  if (divx[0]==2) fBinXSlider->SetPosition(2);
1603  if (divy[0]==2) fBinYSlider->SetPosition(2);
1604  if (divx[0]==2 && divy[0]==2) {
1605  delete [] divx;
1606  delete [] divy;
1607  return;
1608  }
1609  // delete the histogram which is on the screen
1610  fGedEditor->GetPad()->cd();
1611  fHist->Reset();
1612  fHist->SetBins(nx,fBinHist->GetXaxis()->GetXmin(),
1613  fBinHist->GetXaxis()->GetXmax(),
1614  ny,fBinHist->GetYaxis()->GetXmin(),
1615  fBinHist->GetYaxis()->GetXmax());
1616  fHist->Add(fBinHist);
1617  fHist->SetCanExtend(TH1::kNoAxis);
1618  fHist->Rebin2D(divx[numx], divy[numy]);
1619 
1620  //fModel=fHist;
1621 
1622  if (divx[0]!=2) {
1623  TAxis* xaxis = fHist->GetXaxis();
1624  Double_t xBinWidth = xaxis->GetBinWidth(1);
1625  xaxis->SetRangeUser(fSldXMin->GetNumber()+xBinWidth/2,
1626  fSldXMax->GetNumber()-xBinWidth/2);
1627  fSliderX->SetRange(1,(Int_t)nx/divx[numx]);
1628  fSliderX->SetPosition(xaxis->FindBin(fSldXMin->GetNumber()+xBinWidth/2),
1629  xaxis->FindBin(fSldXMax->GetNumber()-xBinWidth/2));
1630  // the axis range could be changed a little bit by the Rebin algorithm
1631  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
1632  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
1633  }
1634  if (divy[0]!=2) {
1635  TAxis* yaxis = fHist->GetYaxis();
1636  Double_t yBinWidth = yaxis->GetBinWidth(1);
1637  yaxis->SetRangeUser(fSldYMin->GetNumber()+yBinWidth/2,
1638  fSldYMax->GetNumber()-yBinWidth/2);
1639  fSliderY->SetRange(1,(Int_t)ny/divy[numy]);
1640  fSliderY->SetPosition(yaxis->FindBin(fSldYMin->GetNumber()+yBinWidth/2),
1641  yaxis->FindBin(fSldYMax->GetNumber()-yBinWidth/2));
1642  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
1643  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
1644  }
1645  if (fCancel->GetState()==kButtonDisabled) fCancel->SetState(kButtonUp);
1646  if (fApply->GetState()==kButtonDisabled) fApply->SetState(kButtonUp);
1647  Update();
1648  delete [] divx;
1649  delete [] divy;
1650  }
1651 // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0);
1652  // fModel = fHist;
1653  Refresh(fHist);
1654 }
1655 
1656 ////////////////////////////////////////////////////////////////////////////////
1657 /// Slot connected to the rebin slider in case of no ntuple histogram.
1658 
1659 void TH2Editor::DoBinPressed()
1660 {
1661  if (fAvoidSignal) return;
1662  Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins());
1663  Int_t* divy = Dividers(fHist->GetYaxis()->GetNbins());
1664  if (divx[0]==2 && divy[0]==2 && !fBinHist)
1665  new TGMsgBox(fClient->GetDefaultRoot(), this->GetMainFrame(),
1666  "TH2Editor", "It is not possible to rebin the histogram",
1667  kMBIconExclamation, kMBOk, 0, kVerticalFrame);
1668  // calling the MessageBox again does NOT work!*/
1669  delete [] divx;
1670  delete [] divy;
1671 }
1672 
1673 ////////////////////////////////////////////////////////////////////////////////
1674 /// Slot connected to the rebin sliders in case of no ntuple histogram
1675 /// does the rebinning of the selected histogram.
1676 
1677 void TH2Editor::DoBinMoved()
1678 {
1679  // create a clone in the background, when the slider is moved for 1st time
1680  if (fAvoidSignal) return;
1681  if (!fBinHist /*&& fDelaydraw->GetState()!=kButtonDown*/) {
1682  Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins());
1683  Int_t* divy = Dividers(fHist->GetYaxis()->GetNbins());
1684  // if there is nothing to rebin:
1685  if (divx[0]==2 && divy[0]==2) {
1686  delete [] divx;
1687  delete [] divy;
1688  return;
1689  }
1690  fBinHist = (TH2*)fHist->Clone("BinHist");
1691  fBinHist->SetDirectory(0); // TH2Editor manages this histogram
1692  delete [] divx;
1693  delete [] divy;
1694  }
1695  // if the slider already has been moved and the clone is saved
1696  Int_t nx = fBinHist->GetXaxis()->GetNbins();
1697  Int_t ny = fBinHist->GetYaxis()->GetNbins();
1698  Int_t numx = fBinXSlider->GetPosition();
1699  Int_t numy = fBinYSlider->GetPosition();
1700  if (nx < 1 || ny < 1) return;
1701  Int_t* divx = Dividers(nx);
1702  Int_t* divy = Dividers(ny);
1703  if (divx[0]==2) {
1704  fBinXSlider->SetPosition(2);
1705  numx=1;
1706  }
1707  if (divy[0]==2) {
1708  fBinYSlider->SetPosition(2);
1709  numy=1;
1710  }
1711  Int_t maxx = (Int_t)nx/divx[numx];
1712  Int_t maxy = (Int_t)ny/divy[numy];
1713  if (maxx==1) maxx=2;
1714  if (maxy==1) maxy=2;
1715  if (fDelaydraw->GetState()==kButtonUp){
1716  // delete the histogram which is on the screen
1717  fGedEditor->GetPad()->cd();
1718  fHist->Reset();
1719  fHist->SetBins(nx,fBinHist->GetXaxis()->GetXmin(),
1720  fBinHist->GetXaxis()->GetXmax(),
1721  ny,fBinHist->GetYaxis()->GetXmin(),
1722  fBinHist->GetYaxis()->GetXmax());
1723  fHist->Add(fBinHist);
1724  fHist->SetCanExtend(TH1::kNoAxis);
1725  fHist->Rebin2D(divx[numx], divy[numy]);
1726  //fModel=fHist;
1727  if (divx[0]!=2) {
1728  TAxis* xaxis = fHist->GetXaxis();
1729  Double_t xBinWidth = xaxis->GetBinWidth(1);
1730  // if the user has zoomed into a special area the range will be reset:
1731  xaxis->SetRangeUser(fSldXMin->GetNumber()+xBinWidth/2,
1732  fSldXMax->GetNumber()-xBinWidth/2);
1733  fSliderX->SetRange(1,maxx);
1734  fSliderX->SetPosition(xaxis->FindBin(fSldXMin->GetNumber()+xBinWidth/2),
1735  xaxis->FindBin(fSldXMax->GetNumber()-xBinWidth/2));
1736  // the axis range could be changed a little bit by the Rebin algorithm
1737  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
1738  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
1739  fClient->NeedRedraw(fBinXSlider,kTRUE);
1740  }
1741  if (divy[0]!=2) {
1742  TAxis* yaxis = fHist->GetYaxis();
1743  Double_t yBinWidth = yaxis->GetBinWidth(1);
1744  yaxis->SetRangeUser(fSldYMin->GetNumber()+yBinWidth/2,
1745  fSldYMax->GetNumber()-yBinWidth/2);
1746  fSliderY->SetRange(1,maxy);
1747  fSliderY->SetPosition(yaxis->FindBin(fSldYMin->GetNumber()+yBinWidth/2),
1748  yaxis->FindBin(fSldYMax->GetNumber()-yBinWidth/2));
1749  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
1750  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
1751  fClient->NeedRedraw(fBinYSlider,kTRUE);
1752  }
1753  Update();
1754  }
1755  // set the according NumberEntries
1756  if (fCancel->GetState()==kButtonDisabled)
1757  fCancel->SetState(kButtonUp);
1758  if (fApply->GetState()==kButtonDisabled)
1759  fApply->SetState(kButtonUp);
1760  fBinXNumberEntry->SetNumber(maxx);
1761  fBinYNumberEntry->SetNumber(maxy);
1762  delete [] divx;
1763  delete [] divy;
1764 }
1765 
1766 ////////////////////////////////////////////////////////////////////////////////
1767 /// Slot connected to the Bin Number Entry for the Rebin.
1768 
1769 void TH2Editor::DoBinLabel()
1770 {
1771  if (fAvoidSignal) return;
1772  Int_t i;
1773  Int_t numx = (Int_t)(fBinXNumberEntry->GetNumber());
1774  Int_t numy = (Int_t)(fBinYNumberEntry->GetNumber());
1775  Int_t nx = 0;
1776  if (fBinHist) nx = fBinHist->GetXaxis()->GetNbins();
1777  else nx = fHist->GetXaxis()->GetNbins();
1778  Int_t ny = 0;
1779  if (fBinHist) ny = fBinHist->GetYaxis()->GetNbins();
1780  else ny = fHist->GetYaxis()->GetNbins();
1781  if (nx < 2 || ny < 2) return;
1782  // Get the divider of nx/ny which is closest to numx/numy
1783  Int_t *divx = Dividers(nx);
1784  Int_t *divy = Dividers(ny);
1785  Int_t diff = TMath::Abs(numx - divx[1]);
1786  Int_t c = 1; Int_t d = 1;
1787  for (i = 2; i <= divx[0]; i++) {
1788  if ((TMath::Abs(numx - divx[i])) < diff) {
1789  c = i;
1790  diff = TMath::Abs(numx - divx[i]);
1791  }
1792  }
1793  diff = TMath::Abs(numy - divy[1]);
1794  for (i = 2; i <= divy[0]; i++) {
1795  if ((TMath::Abs(numy - divy[i])) < diff) {
1796  d = i;
1797  diff = TMath::Abs(numy - divy[i]);
1798  }
1799  }
1800  if (divx[c]!= fHist->GetXaxis()->GetNbins() ||
1801  divy[d]!= fHist->GetYaxis()->GetNbins()) {
1802  fBinXNumberEntry->SetNumber(divx[c]);
1803  fBinXSlider->SetPosition(divx[0] - c +1);
1804  fBinYNumberEntry->SetNumber(divy[d]);
1805  fBinYSlider->SetPosition(divy[0] - d +1);
1806  if (fDelaydraw->GetState()==kButtonUp) DoBinMoved();
1807  else DoBinReleased();
1808  }
1809 // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0);
1810 // fModel = fHist;
1811  Refresh(fHist);
1812  delete [] divx;
1813  delete [] divy;
1814 }
1815 
1816 ////////////////////////////////////////////////////////////////////////////////
1817 /// Slot connected to the Apply Button in the Rebinned histogram Window.
1818 
1819 void TH2Editor::DoApply()
1820 {
1821  Int_t ret = 0;
1822  new TGMsgBox(fClient->GetDefaultRoot(), this->GetMainFrame(),
1823  "TH2 Editor", "Replace origin histogram with rebinned one?",
1824  kMBIconQuestion, kMBYes | kMBNo, &ret, kVerticalFrame);
1825  if (ret==1) {
1826  if (fBinHist) {
1827  delete fBinHist;
1828  fBinHist = 0;
1829  }
1830  Int_t nx = fHist->GetXaxis()->GetNbins();
1831  Int_t ny = fHist->GetYaxis()->GetNbins();
1832  Int_t *divx = Dividers(nx);
1833  Int_t *divy = Dividers(ny);
1834  Int_t upx = 0, upy = 0;
1835  if (divx[0]-1 <= 1) upx = 2;
1836  else upx = divx[0]-1;
1837  if (divy[0]-1 <= 1) upy = 2;
1838  else upy = divy[0]-1;
1839  fBinXSlider->SetRange(1,upx);
1840  fBinYSlider->SetRange(1,upy);
1841  if (fBinXSlider->GetMaxPosition()==2 && divx[0]==2 )
1842  fBinXSlider->SetPosition(2);
1843  else fBinXSlider->SetPosition(1);
1844  if (fBinYSlider->GetMaxPosition()==2 && divy[0]==2 )
1845  fBinYSlider->SetPosition(2);
1846  else fBinYSlider->SetPosition(1);
1847  fCancel->SetState(kButtonDisabled);
1848  fApply->SetState(kButtonDisabled);
1849  Update();
1850  delete [] divx;
1851  delete [] divy;
1852  } else if (ret==2) DoCancel();
1853 }
1854 
1855 ////////////////////////////////////////////////////////////////////////////////
1856 /// Slot connected to the Cancel Button in the Rebinned histogram Window.
1857 
1858 void TH2Editor::DoCancel()
1859 {
1860  if (fBinHist) {
1861  fGedEditor->GetPad()->cd();
1862  fHist->Reset();
1863  fHist->SetBins(fBinHist->GetXaxis()->GetNbins(),
1864  fBinHist->GetXaxis()->GetXmin(),
1865  fBinHist->GetXaxis()->GetXmax(),
1866  fBinHist->GetYaxis()->GetNbins(),
1867  fBinHist->GetYaxis()->GetXmin(),
1868  fBinHist->GetYaxis()->GetXmax());
1869  fHist->Add(fBinHist);
1870  fHist->GetXaxis()->SetRange(fBinHist->GetXaxis()->GetFirst(),
1871  fBinHist->GetXaxis()->GetLast());
1872  fHist->GetYaxis()->SetRange(fBinHist->GetYaxis()->GetFirst(),
1873  fBinHist->GetYaxis()->GetLast());
1874 
1875  delete fBinHist;
1876  fBinHist = 0;
1877 
1878  fCancel->SetState(kButtonDisabled);
1879  fApply->SetState(kButtonDisabled);
1880  Int_t* divx = Dividers(fHist->GetXaxis()->GetNbins());
1881  Int_t* divy = Dividers(fHist->GetYaxis()->GetNbins());
1882  if (divx[0]!=2) fBinXSlider->SetPosition(1);
1883  if (divy[0]!=2) fBinYSlider->SetPosition(1);
1884  // Consigning the new Histogram to all other Editors
1885 // fGedEditor->GetPad()->GetCanvas()->Selected(fGedEditor->GetPad(), fHist, 0);
1886  Update();
1887  // fModel = fHist;
1888  Refresh(fHist);
1889  delete [] divx;
1890  delete [] divy;
1891  }
1892 }
1893 
1894 
1895 ////////////////////////////////////////////////////////////////////////////////
1896 /// Slot connected to the BinNumber Slider in case of a 'ntuple histogram'.
1897 /// It does the rebin.
1898 
1899 void TH2Editor::DoBinReleased1()
1900 {
1901  if (fAvoidSignal) return;
1902  Double_t oldXOffset = fXOffsetNumberEntry->GetNumber();
1903  Int_t xnumber = fBinXSlider1->GetPosition();
1904  Double_t oldYOffset = fYOffsetNumberEntry->GetNumber();
1905  Int_t ynumber = fBinYSlider1->GetPosition();
1906  if (xnumber==5 && ynumber==5) return;
1907  Int_t xfact = 0;
1908  Int_t yfact = 0;
1909  Int_t xBinNumber = 0;
1910  Int_t yBinNumber = 0;
1911  TAxis* xaxis = fHist->GetXaxis();
1912  TAxis* yaxis = fHist->GetYaxis();
1913  //"compute" the scaling factor:
1914  if (xnumber >= 5) xfact = xnumber - 4;
1915  else xfact = xnumber - 6;
1916  if (ynumber >= 5) yfact = ynumber - 4;
1917  else yfact = ynumber - 6;
1918  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
1919  if (!player) return;
1920  Int_t nx = xaxis->GetNbins();
1921  Int_t ny = yaxis->GetNbins();
1922  Int_t firstx = xaxis->GetFirst();
1923  Int_t lastx = xaxis->GetLast();
1924  Int_t firsty = yaxis->GetFirst();
1925  Int_t lasty = yaxis->GetLast();
1926  Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords
1927  Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords
1928  Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords
1929  Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords
1930  Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords
1931  Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords
1932  Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords
1933  Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords
1934 
1935  ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis);
1936  ((TH2*)player->GetHistogram())->Reset();
1937 
1938  // Get new Number of bins
1939  if (xfact > 0) xBinNumber = xfact*nx;
1940  if (xfact < 0) xBinNumber = (Int_t) ((-1)*nx/xfact+0.5);
1941  if (xBinNumber < 1) xBinNumber = 1;
1942  if (xBinNumber > 1000) xBinNumber= 1000;
1943  if (yfact > 0) yBinNumber = yfact*ny;
1944  if (yfact < 0) yBinNumber = (Int_t) ((-1)*ny/yfact+0.5);
1945  if (yBinNumber < 1) yBinNumber = 1;
1946  if (yBinNumber > 1000) yBinNumber= 1000;
1947  Double_t xOffset = 1.*fXBinOffsetSld->GetPosition()/100*((maxx-minx)/xBinNumber);
1948  Double_t yOffset = 1.*fYBinOffsetSld->GetPosition()/100*((maxy-miny)/yBinNumber);
1949  // create new histogram - the main job is done by sel->TakeAction()
1950 
1951  ((TH2*)player->GetHistogram())->SetBins(xBinNumber, minx-oldXOffset+xOffset,
1952  maxx-oldXOffset+xOffset,
1953  yBinNumber, miny-oldYOffset+yOffset,
1954  maxy-oldYOffset+yOffset);
1955  TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector();
1956  if (!sel) return;
1957  sel->TakeAction();
1958 
1959  // Restore and set all the attributes which were changed by TakeAction()
1960  fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram();
1961  fSliderX->SetRange(1,xBinNumber);
1962  fSliderY->SetRange(1,yBinNumber);
1963  Double_t xBinWidth = xaxis->GetBinWidth(1);
1964  Double_t yBinWidth = yaxis->GetBinWidth(1);
1965  fSliderX->SetPosition(xaxis->FindBin(rminx+xBinWidth/2),
1966  xaxis->FindBin(rmaxx-xBinWidth/2));
1967  fSliderY->SetPosition(yaxis->FindBin(rminy+yBinWidth/2),
1968  yaxis->FindBin(rmaxy-yBinWidth/2));
1969  xOffset = 1.*fXBinOffsetSld->GetPosition()/100*xBinWidth; // nessesary ??
1970  yOffset = 1.*fYBinOffsetSld->GetPosition()/100*yBinWidth; // nessesary ??
1971 
1972  // SetRange in BinNumbers along x and y!
1973  xaxis->SetRange(xaxis->FindBin(rminx+xBinWidth/2),
1974  xaxis->FindBin(rmaxx-xBinWidth/2));
1975  yaxis->SetRange(yaxis->FindBin(rminy+yBinWidth/2),
1976  yaxis->FindBin(rmaxy-yBinWidth/2));
1977  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
1978  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
1979  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
1980  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
1981  fBinXNumberEntry1->SetNumber(xaxis->GetLast() - xaxis->GetFirst()+1);
1982  fBinYNumberEntry1->SetNumber(yaxis->GetLast() - yaxis->GetFirst()+1);
1983  fBinXSlider1->SetPosition(5);
1984  fBinYSlider1->SetPosition(5);
1985  fXOffsetNumberEntry->SetNumber(xOffset);
1986  fYOffsetNumberEntry->SetNumber(yOffset);
1987  fXOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0,
1988  xaxis->GetBinWidth(1));
1989  fYOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax, 0,
1990  yaxis->GetBinWidth(1));
1991  fClient->NeedRedraw(fBinXSlider1, kTRUE);
1992  // when you 2-clicks on a slider, sometimes it gets caught on wrong position! (2 or -2)
1993  fClient->NeedRedraw(fBinYSlider1, kTRUE);
1994  // when you 2-clicks on a slider, sometimes it gets caught on wrong position! (2 or -2)
1995  Update();
1996 }
1997 
1998 ////////////////////////////////////////////////////////////////////////////////
1999 /// Slot connected to the rebin slider in case of an ntuple histogram.
2000 /// Updates the BinNumberEntryField during the BinSlider movement.
2001 
2002 void TH2Editor::DoBinMoved1()
2003 {
2004  if (fAvoidSignal) return;
2005  TAxis* xaxis = fHist->GetXaxis();
2006  TAxis* yaxis = fHist->GetYaxis();
2007  Int_t firstx = xaxis->GetFirst();
2008  Int_t lastx = xaxis->GetLast();
2009  Int_t firsty = yaxis->GetFirst();
2010  Int_t lasty = yaxis->GetLast();
2011  Int_t xnumber = fBinXSlider1->GetPosition();
2012  Int_t ynumber = fBinYSlider1->GetPosition();
2013  Int_t numx = lastx-firstx+1;
2014  Int_t numy = lasty-firsty+1;
2015  Int_t xfact = 0;
2016  Int_t yfact = 0;
2017  Int_t xBinNumber = 0;
2018  Int_t yBinNumber = 0;
2019  if (xnumber >= 5) xfact = xnumber - 4;
2020  else xfact = xnumber - 6;
2021  if (xfact > 0) xBinNumber = xfact*numx;
2022  if (xfact < 0) xBinNumber = (Int_t) ((-1)*numx/xfact+0.5);
2023  if (xBinNumber < 1) xBinNumber = 1;
2024  if (xBinNumber > 1000) xBinNumber= 1000;
2025  if (fBinXNumberEntry1->GetNumber()!=xBinNumber)
2026  fBinXNumberEntry1->SetIntNumber(xBinNumber);
2027 
2028  if (ynumber >= 5) yfact = ynumber - 4;
2029  else yfact = ynumber - 6;
2030  if (yfact > 0) yBinNumber = yfact*numy;
2031  if (yfact < 0) yBinNumber = (Int_t) ((-1)*numy/yfact+0.5);
2032  if (yBinNumber < 1) yBinNumber = 1;
2033  if (yBinNumber > 1000) yBinNumber= 1000;
2034  if (fBinYNumberEntry1->GetNumber()!=yBinNumber)
2035  fBinYNumberEntry1->SetIntNumber(yBinNumber);
2036 }
2037 
2038 ////////////////////////////////////////////////////////////////////////////////
2039 /// Slot connected to the Bin Number Entry for the Rebin.
2040 
2041 void TH2Editor::DoBinLabel1()
2042 {
2043  if (fAvoidSignal) return;
2044  Double_t oldXOffset = fXOffsetNumberEntry->GetNumber();
2045  Int_t numx = (Int_t)fBinXNumberEntry1->GetNumber();
2046  Double_t oldYOffset = fYOffsetNumberEntry->GetNumber();
2047  Int_t numy = (Int_t)fBinYNumberEntry1->GetNumber();
2048  TAxis* xaxis = fHist->GetXaxis();
2049  TAxis* yaxis = fHist->GetYaxis();
2050  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
2051  if (!player) return;
2052  Int_t firstx = xaxis->GetFirst();
2053  Int_t lastx = xaxis->GetLast();
2054  Int_t firsty = yaxis->GetFirst();
2055  Int_t lasty = yaxis->GetLast();
2056  Int_t nx = xaxis->GetNbins();
2057  Int_t ny = yaxis->GetNbins();
2058  Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords
2059  Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords
2060  Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords
2061  Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords
2062  Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords
2063  Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords
2064  Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords
2065  Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords
2066 
2067  ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis);
2068  ((TH2*)player->GetHistogram())->Reset();
2069 
2070  // Calculate the new number of bins in the complete range
2071  Int_t xBinNumber = (Int_t) ((maxx-minx)/(rmaxx - rminx)*numx + 0.5);
2072  if (xBinNumber < 1) xBinNumber = 1;
2073  if (xBinNumber > 1000) xBinNumber= 1000;
2074  Double_t xOffset = 1.*(fXBinOffsetSld->GetPosition())/100*(maxx-minx)/xBinNumber;
2075  Int_t yBinNumber = (Int_t) ((maxy-miny)/(rmaxy - rminy)*numy + 0.5);
2076  if (yBinNumber < 1) yBinNumber = 1;
2077  if (yBinNumber > 1000) yBinNumber= 1000;
2078  Double_t yOffset = 1.*(fYBinOffsetSld->GetPosition())/100*(maxy-miny)/yBinNumber;
2079  // create new histogram - the main job is done by sel->TakeAction()
2080  ((TH2*)player->GetHistogram())->SetBins(xBinNumber, minx-oldXOffset+xOffset,
2081  maxx-oldXOffset+xOffset,
2082  yBinNumber, miny-oldYOffset+yOffset,
2083  maxy-oldYOffset+yOffset);
2084  TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector();
2085  if (!sel) return;
2086  sel->TakeAction();
2087 
2088  // Restore and set all the attributes which were changed by TakeAction()
2089  fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram();
2090  fSliderX->SetRange(1,xBinNumber);
2091  fSliderY->SetRange(1,yBinNumber);
2092  Double_t xBinWidth = xaxis->GetBinWidth(1);
2093  Double_t yBinWidth = yaxis->GetBinWidth(1);
2094  fSliderX->SetPosition(xaxis->FindBin(rminx+xBinWidth/2),
2095  xaxis->FindBin(rmaxx-xBinWidth/2));
2096  fSliderY->SetPosition(yaxis->FindBin(rminy+yBinWidth/2),
2097  yaxis->FindBin(rmaxy-yBinWidth/2));
2098  xOffset = 1.*fXBinOffsetSld->GetPosition()/100*xBinWidth; //nesessary ??
2099  yOffset = 1.*fYBinOffsetSld->GetPosition()/100*yBinWidth; //nesessary ??
2100 
2101  // SetRange in BinNumbers along x and y!
2102  xaxis->SetRange(xaxis->FindBin(rminx+xBinWidth/2),
2103  xaxis->FindBin(rmaxx-xBinWidth/2));
2104  yaxis->SetRange(yaxis->FindBin(rminy+yBinWidth/2),
2105  yaxis->FindBin(rmaxy-yBinWidth/2));
2106  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
2107  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
2108  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
2109  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
2110  fXOffsetNumberEntry->SetNumber(xOffset);
2111  fXOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax,0,xBinWidth);
2112  fYOffsetNumberEntry->SetNumber(yOffset);
2113  fYOffsetNumberEntry->SetLimits(TGNumberFormat::kNELLimitMinMax,0,yBinWidth);
2114  Update();
2115 }
2116 
2117 ////////////////////////////////////////////////////////////////////////////////
2118 /// Slot connected to the OffSetSlider. It saves the OldBinOffset
2119 /// (nessesary for delay draw mode).
2120 
2121 void TH2Editor::DoOffsetPressed()
2122 {
2123  if (fAvoidSignal) return;
2124  fOldXOffset = fXOffsetNumberEntry->GetNumber();
2125  fOldYOffset = fYOffsetNumberEntry->GetNumber();
2126 }
2127 
2128 ////////////////////////////////////////////////////////////////////////////////
2129 /// Slot connected to the OffSetSlider that
2130 /// changes the origin of the histogram inbetween a binwidth;
2131 /// rebin the histogram with the new Offset given by the slider.
2132 /// problem: histogram with variable binwidth??
2133 
2134 void TH2Editor::DoOffsetReleased()
2135 {
2136  if (fAvoidSignal) return;
2137  if (fDelaydraw->GetState()==kButtonDown){
2138  Int_t numx = (Int_t)fXBinOffsetSld->GetPosition();
2139  Int_t numy = (Int_t)fYBinOffsetSld->GetPosition();
2140  TAxis* xaxis = fHist->GetXaxis();
2141  TAxis* yaxis = fHist->GetYaxis();
2142  Double_t xBinWidth = xaxis->GetBinWidth(1);
2143  Double_t yBinWidth = yaxis->GetBinWidth(1);
2144  Double_t xOffset = 1.*numx/100*xBinWidth;
2145  Double_t yOffset = 1.*numy/100*yBinWidth;
2146  Double_t oldXOffset = fOldXOffset;
2147  Double_t oldYOffset = fOldYOffset;
2148  Int_t nx = xaxis->GetNbins();
2149  Int_t ny = yaxis->GetNbins();
2150 
2151  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
2152  if (!player) return;
2153 
2154  Int_t firstx = xaxis->GetFirst();
2155  Int_t lastx = xaxis->GetLast();
2156  Int_t firsty = yaxis->GetFirst();
2157  Int_t lasty = yaxis->GetLast();
2158  Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords
2159  Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords
2160  Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords
2161  Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords
2162  Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords
2163  Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords
2164  Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords
2165  Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords
2166 
2167  ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis);
2168  ((TH2*)player->GetHistogram())->Reset();
2169 
2170  ((TH2*)player->GetHistogram())->SetBins(nx, minx-oldXOffset+xOffset,
2171  maxx-oldXOffset+xOffset,
2172  ny, miny-oldYOffset+yOffset,
2173  maxy-oldYOffset+yOffset);
2174  TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector();
2175  if (!sel) return;
2176  sel->TakeAction();
2177 
2178  // Restore all the attributes which were changed by TakeAction()
2179  fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram();
2180 
2181  // SetRange in BinNumbers along x and y!
2182  xaxis->SetRange(xaxis->FindBin(rminx+xOffset-oldXOffset+xBinWidth/2),
2183  xaxis->FindBin(rmaxx+xOffset-oldXOffset-xBinWidth/2));
2184  yaxis->SetRange(yaxis->FindBin(rminy+yOffset-oldYOffset+yBinWidth/2),
2185  yaxis->FindBin(rmaxy+yOffset-oldYOffset-yBinWidth/2));
2186  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
2187  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
2188  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
2189  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
2190  fXOffsetNumberEntry->SetNumber(xOffset);
2191  fYOffsetNumberEntry->SetNumber(yOffset);
2192  Update();
2193  }
2194 }
2195 
2196 ////////////////////////////////////////////////////////////////////////////////
2197 /// Slot connected to the OffSetSlider.
2198 /// It changes the origin of the histogram inbetween a binwidth;
2199 /// rebin the histogram with the new offset given by the slider.
2200 /// problem: histogram with variable binwidth??
2201 
2202 void TH2Editor::DoOffsetMoved()
2203 {
2204  if (fAvoidSignal) return;
2205  Int_t numx = (Int_t)fXBinOffsetSld->GetPosition();
2206  Int_t numy = (Int_t)fYBinOffsetSld->GetPosition();
2207  TAxis* xaxis = fHist->GetXaxis();
2208  TAxis* yaxis = fHist->GetYaxis();
2209  Double_t xBinWidth = xaxis->GetBinWidth(1);
2210  Double_t yBinWidth = yaxis->GetBinWidth(1);
2211  Double_t xOffset = 1.*numx/100*xBinWidth;
2212  Double_t yOffset = 1.*numy/100*yBinWidth;
2213  if (fDelaydraw->GetState()==kButtonUp){
2214  Double_t oldXOffset = fXOffsetNumberEntry->GetNumber();
2215  Double_t oldYOffset = fYOffsetNumberEntry->GetNumber();
2216  Int_t nx = xaxis->GetNbins();
2217  Int_t ny = yaxis->GetNbins();
2218 
2219  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
2220  if (!player) return;
2221 
2222  Int_t firstx = xaxis->GetFirst();
2223  Int_t lastx = xaxis->GetLast();
2224  Int_t firsty = yaxis->GetFirst();
2225  Int_t lasty = yaxis->GetLast();
2226  Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords
2227  Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords
2228  Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords
2229  Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords
2230  Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords
2231  Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords
2232  Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords
2233  Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords
2234 
2235  ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis);
2236  ((TH2*)player->GetHistogram())->Reset();
2237 
2238  ((TH2*)player->GetHistogram())->SetBins(nx,minx-oldXOffset+xOffset,
2239  maxx-oldXOffset+xOffset,
2240  ny, miny-oldYOffset+yOffset,
2241  maxy-oldYOffset+yOffset);
2242  TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector();
2243  if (!sel) return;
2244  sel->TakeAction();
2245 
2246  // Restore all the attributes which were changed by TakeAction()
2247  fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram();
2248 
2249  // SetRange in BinNumbers along x and y!
2250  xaxis->SetRange(xaxis->FindBin(rminx+xOffset-oldXOffset+xBinWidth/2),
2251  xaxis->FindBin(rmaxx+xOffset-oldXOffset-xBinWidth/2));
2252  yaxis->SetRange(yaxis->FindBin(rminy+yOffset-oldYOffset+yBinWidth/2),
2253  yaxis->FindBin(rmaxy+yOffset-oldYOffset-yBinWidth/2));
2254  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
2255  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
2256  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
2257  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
2258  fClient->NeedRedraw(fXBinOffsetSld, kTRUE);
2259  fClient->NeedRedraw(fYBinOffsetSld, kTRUE);
2260  Update();
2261  }
2262  fXOffsetNumberEntry->SetNumber(xOffset);
2263  fYOffsetNumberEntry->SetNumber(yOffset);
2264  fClient->NeedRedraw(fXOffsetNumberEntry, kTRUE);
2265  fClient->NeedRedraw(fYOffsetNumberEntry, kTRUE);
2266 }
2267 
2268 ////////////////////////////////////////////////////////////////////////////////
2269 /// Slot connected to the OffSetNumberEntry, related to the OffSetSlider
2270 /// changes the origin of the histogram inbetween a binwidth.
2271 
2272 void TH2Editor::DoBinOffset()
2273 {
2274  if (fAvoidSignal) return;
2275  TAxis* xaxis = fHist->GetXaxis();
2276  TAxis* yaxis = fHist->GetYaxis();
2277  Double_t xBinWidth = xaxis->GetBinWidth(1);
2278  Double_t yBinWidth = yaxis->GetBinWidth(1);
2279  Double_t xOffset = fXOffsetNumberEntry->GetNumber();
2280  Double_t oldXOffset = 1.*fXBinOffsetSld->GetPosition()/100*xBinWidth;
2281  Double_t yOffset = fYOffsetNumberEntry->GetNumber();
2282  Double_t oldYOffset = 1.*fYBinOffsetSld->GetPosition()/100*yBinWidth;
2283  Int_t nx = xaxis->GetNbins();
2284  Int_t ny = yaxis->GetNbins();
2285  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
2286  if (!player) return;
2287  Int_t firstx = xaxis->GetFirst();
2288  Int_t lastx = xaxis->GetLast();
2289  Int_t firsty = yaxis->GetFirst();
2290  Int_t lasty = yaxis->GetLast();
2291  Double_t minx = xaxis->GetBinLowEdge(1); // overall min in user coords
2292  Double_t maxx = xaxis->GetBinUpEdge(nx); // overall max in user coords
2293  Double_t miny = yaxis->GetBinLowEdge(1); // overall min in user coords
2294  Double_t maxy = yaxis->GetBinUpEdge(ny); // overall max in user coords
2295  Double_t rminx = xaxis->GetBinLowEdge(firstx); // recent min in user coords
2296  Double_t rmaxx = xaxis->GetBinUpEdge(lastx); // recent max in user coords
2297  Double_t rminy = yaxis->GetBinLowEdge(firsty); // recent min in user coords
2298  Double_t rmaxy = yaxis->GetBinUpEdge(lasty); // recent max in user coords
2299 
2300  ((TH2*)player->GetHistogram())->SetCanExtend(TH1::kNoAxis);
2301  ((TH2*)player->GetHistogram())->Reset();
2302 
2303  ((TH2*)player->GetHistogram())->SetBins(nx,minx+xOffset-oldXOffset,
2304  maxx+xOffset-oldXOffset,
2305  ny,miny+yOffset-oldYOffset,
2306  maxy+yOffset-oldYOffset);
2307  TSelectorDraw *sel = (TSelectorDraw*)player->GetSelector();
2308  if (!sel) return;
2309  sel->TakeAction();
2310 
2311  // Restore all the attributes which were changed by TakeAction()
2312  fHist = (TH2*)((TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer())->GetHistogram();
2313 
2314  // SetRange in BinNumbers along x and y!
2315  xaxis->SetRange(xaxis->FindBin(rminx+xOffset-oldXOffset+xBinWidth/2),
2316  xaxis->FindBin(rmaxx+xOffset-oldXOffset-xBinWidth/2));
2317  yaxis->SetRange(yaxis->FindBin(rminy+yOffset-oldYOffset+yBinWidth/2),
2318  yaxis->FindBin(rmaxy+yOffset-oldYOffset-yBinWidth/2));
2319  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
2320  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
2321  fXBinOffsetSld->SetPosition((Int_t)(xOffset/xBinWidth*100));
2322  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
2323  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
2324  fYBinOffsetSld->SetPosition((Int_t)(yOffset/yBinWidth*100));
2325  Update();
2326 }
2327 
2328 ////////////////////////////////////////////////////////////////////////////////
2329 /// Slot connected to the x-Slider that redraws the histogram
2330 /// with the new slider range.
2331 
2332 void TH2Editor::DoSliderXMoved()
2333 {
2334  if (fAvoidSignal) return;
2335  TAxis* xaxis = fHist->GetXaxis();
2336  if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) {
2337  // 2D plot
2338  Int_t px1,py1,px2,py2;
2339  Float_t ymin,ymax,xleft,xright;
2340  xleft = xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5));
2341  xright = xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5));
2342  ymin = fGedEditor->GetPad()->GetUymin();
2343  ymax = fGedEditor->GetPad()->GetUymax();
2344  px1 = fGedEditor->GetPad()->XtoAbsPixel(xleft);
2345  py1 = fGedEditor->GetPad()->YtoAbsPixel(ymin);
2346  px2 = fGedEditor->GetPad()->XtoAbsPixel(xright);
2347  py2 = fGedEditor->GetPad()->YtoAbsPixel(ymax);
2348  if (fGedEditor->GetPad()->GetCanvas())
2349  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE);
2350  fGedEditor->GetPad()->cd();
2351  fGedEditor->GetPad()->SetLineWidth(1);
2352  fGedEditor->GetPad()->SetLineColor(2);
2353  gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow);
2354  gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2355  fPx1old = px1;
2356  fPy1old = py1;
2357  fPx2old = px2 ;
2358  fPy2old = py2;
2359  gVirtualX->Update(0);
2360  fSldXMin->SetNumber(xleft);
2361  fSldXMax->SetNumber(xright);
2362  } else if (fDelaydraw->GetState()==kButtonDown &&
2363  fDim0->GetState()==kButtonDown &&
2364  fCoordsCombo->GetSelected()==kCOORDS_CAR) {
2365  // 3D plot
2366  Float_t p1[3], p2[3], p3[3], p4[3], p5[3], p6[3], p7[3], p8[3];
2367  if (fGedEditor->GetPad()->GetCanvas())
2368  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE);
2369  fGedEditor->GetPad()->cd();
2370  TView *fView = fGedEditor->GetPad()->GetView();
2371  if (!fView) return;
2372  Double_t *rmin = fView->GetRmin();
2373  if (!rmin) return;
2374  Double_t *rmax = fView->GetRmax();
2375  if (!rmax) return;
2376  p1[0] = p4[0] = p5[0] = p8[0] =
2377  xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5));
2378  p2[0] = p3[0] = p6[0] = p7[0] =
2379  xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5));
2380  p1[1] = p2[1] = p3[1] = p4[1] = rmin[1];
2381  p5[1] = p6[1] = p7[1] = p8[1] = rmax[1];
2382  p1[2] = p2[2] = p5[2] = p6[2] = rmin[2];
2383  p3[2] = p4[2] = p7[2] = p8[2] = rmax[2];
2384  fGedEditor->GetPad()->SetLineWidth(1);
2385  fGedEditor->GetPad()->SetLineColor(2);
2386  PaintBox3D(fP2oldx, fP3oldx, fP7oldx, fP6oldx);
2387  PaintBox3D(fP1oldx, fP4oldx, fP8oldx, fP5oldx);
2388  PaintBox3D(p2, p3, p7, p6);
2389  PaintBox3D(p1, p4, p8, p5);
2390  for (Int_t i = 0; i<3; i++){
2391  fP1oldx[i] = p1[i];
2392  fP2oldx[i] = p2[i];
2393  fP3oldx[i] = p3[i];
2394  fP4oldx[i] = p4[i];
2395  fP5oldx[i] = p5[i];
2396  fP6oldx[i] = p6[i];
2397  fP7oldx[i] = p7[i];
2398  fP8oldx[i] = p8[i];
2399  }
2400  fSldXMin->SetNumber(p1[0]);
2401  fSldXMax->SetNumber(p2[0]);
2402  } else if (fDelaydraw->GetState()==kButtonDown &&
2403  fDim0->GetState()==kButtonDown) {
2404  fSldXMin->SetNumber(xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5)));
2405  fSldXMax->SetNumber(xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5)));
2406  } else {
2407  fHist->GetXaxis()->SetRange((Int_t)((fSliderX->GetMinPosition())+0.5),
2408  (Int_t)((fSliderX->GetMaxPosition())+0.5));
2409  fSldXMin->SetNumber(xaxis->GetBinLowEdge(xaxis->GetFirst()));
2410  fSldXMax->SetNumber(xaxis->GetBinUpEdge(xaxis->GetLast()));
2411  fClient->NeedRedraw(fSliderX,kTRUE);
2412  Update();
2413  }
2414  fClient->NeedRedraw(fSldXMin,kTRUE);
2415  fClient->NeedRedraw(fSldXMax,kTRUE);
2416 }
2417 
2418 ////////////////////////////////////////////////////////////////////////////////
2419 /// Slot connected to the x axis range slider that initialises
2420 /// the "virtual" box which is drawn in delay draw mode.
2421 
2422 void TH2Editor::DoSliderXPressed()
2423 {
2424  if (fAvoidSignal) return;
2425  TAxis* xaxis = fHist->GetXaxis();
2426  Float_t ymin,ymax,xleft,xright;
2427  if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) {
2428  // 2D Plot
2429  if (!fGedEditor->GetPad()) return;
2430  fGedEditor->GetPad()->cd();
2431  if (fGedEditor->GetPad()->GetCanvas())
2432  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kFALSE);
2433  fGedEditor->GetPad()->SetLineWidth(1);
2434  fGedEditor->GetPad()->SetLineColor(2);
2435  xleft = xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5));
2436  xright = xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5));
2437  ymin = fGedEditor->GetPad()->GetUymin();
2438  ymax = fGedEditor->GetPad()->GetUymax();
2439  fPx1old = fGedEditor->GetPad()->XtoAbsPixel(xleft);
2440  fPy1old = fGedEditor->GetPad()->YtoAbsPixel(ymin);
2441  fPx2old = fGedEditor->GetPad()->XtoAbsPixel(xright);
2442  fPy2old = fGedEditor->GetPad()->YtoAbsPixel(ymax);
2443  gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow);
2444  } else if (fDelaydraw->GetState()==kButtonDown &&
2445  fDim0->GetState()==kButtonDown &&
2446  fCoordsCombo->GetSelected()==kCOORDS_CAR) {
2447  // 3D plot
2448  if (!fGedEditor->GetPad()) return;
2449  fGedEditor->GetPad()->cd();
2450  TView *fView = fGedEditor->GetPad()->GetView();
2451  if (!fView) return;
2452  Double_t *rmin = fView->GetRmin();
2453  if (!rmin) return;
2454  Double_t *rmax = fView->GetRmax();
2455  if (!rmax) return;
2456  fP1oldx[0] = fP4oldx[0] = fP5oldx[0] = fP8oldx[0] =
2457  xaxis->GetBinLowEdge((Int_t)((fSliderX->GetMinPosition())+0.5));
2458  fP2oldx[0] = fP3oldx[0] = fP6oldx[0] = fP7oldx[0] =
2459  xaxis->GetBinUpEdge((Int_t)((fSliderX->GetMaxPosition())+0.5));
2460  fP1oldx[1] = fP2oldx[1] = fP3oldx[1] = fP4oldx[1] = rmin[1];
2461  fP5oldx[1] = fP6oldx[1] = fP7oldx[1] = fP8oldx[1] = rmax[1];
2462  fP1oldx[2] = fP2oldx[2] = fP5oldx[2] = fP6oldx[2] = rmin[2];
2463  fP3oldx[2] = fP4oldx[2] = fP7oldx[2] = fP8oldx[2] = rmax[2];
2464  if (fGedEditor->GetPad()->GetCanvas())
2465  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE);
2466  fGedEditor->GetPad()->SetLineWidth(1);
2467  fGedEditor->GetPad()->SetLineColor(2);
2468  PaintBox3D(fP2oldx, fP3oldx, fP7oldx, fP6oldx);
2469  PaintBox3D(fP1oldx, fP4oldx, fP8oldx, fP5oldx);
2470  }
2471 }
2472 
2473 ////////////////////////////////////////////////////////////////////////////////
2474 /// Slot connected to the x-axis slider finalizing values after
2475 /// the slider movement.
2476 
2477 void TH2Editor::DoSliderXReleased()
2478 {
2479  if (fAvoidSignal) return;
2480  if (fDelaydraw->GetState()==kButtonDown) {
2481  fHist->GetXaxis()->SetRange((Int_t)((fSliderX->GetMinPosition())+0.5),
2482  (Int_t)((fSliderX->GetMaxPosition())+0.5));
2483  fSldXMin->SetNumber(fHist->GetXaxis()->GetBinLowEdge(fHist->GetXaxis()->GetFirst()));
2484  fSldXMax->SetNumber(fHist->GetXaxis()->GetBinUpEdge(fHist->GetXaxis()->GetLast()));
2485  Update();
2486  }
2487  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
2488  if (player) if (player->GetHistogram() == fHist) {
2489  Int_t last = fHist->GetXaxis()->GetLast();
2490  Int_t first = fHist->GetXaxis()->GetFirst();
2491  fBinXNumberEntry1->SetIntNumber(last-first+1);
2492  Update();
2493  }
2494 }
2495 
2496 ////////////////////////////////////////////////////////////////////////////////
2497 /// Slot connected to the Max/Min number entry fields showing x-axis range.
2498 
2499 void TH2Editor::DoXAxisRange()
2500 {
2501  TAxis* xaxis = fHist->GetXaxis();
2502  Int_t nx = xaxis->GetNbins();
2503  Double_t width = xaxis->GetBinWidth(1);
2504  if ((fSldXMin->GetNumber()+width/2) < (xaxis->GetBinLowEdge(1)))
2505  fSldXMin->SetNumber(xaxis->GetBinLowEdge(1));
2506  if ((fSldXMax->GetNumber()-width/2) > (xaxis->GetBinUpEdge(nx)))
2507  fSldXMax->SetNumber(xaxis->GetBinUpEdge(nx));
2508  xaxis->SetRangeUser(fSldXMin->GetNumber()+width/2,
2509  fSldXMax->GetNumber()-width/2);
2510  Int_t nxbinmin = xaxis->GetFirst();
2511  Int_t nxbinmax = xaxis->GetLast();
2512  fSliderX->SetPosition((Double_t)(nxbinmin),(Double_t)(nxbinmax));
2513  Update();
2514 }
2515 
2516 ////////////////////////////////////////////////////////////////////////////////
2517 /// Slot connected to the x-slider for redrawing the
2518 /// histogram with the new slider Range (immediately).
2519 
2520 void TH2Editor::DoSliderYMoved()
2521 {
2522  if (fAvoidSignal) return;
2523  TAxis* yaxis = fHist->GetYaxis();
2524  if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) {
2525  Int_t px1,py1,px2,py2;
2526  Float_t xmin,xmax,ybottom,ytop;
2527  ybottom = yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));
2528  ytop = yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));
2529  xmin = fGedEditor->GetPad()->GetUxmin();
2530  xmax = fGedEditor->GetPad()->GetUxmax();
2531  px1 = fGedEditor->GetPad()->XtoAbsPixel(xmin);
2532  py1 = fGedEditor->GetPad()->YtoAbsPixel(ybottom);
2533  px2 = fGedEditor->GetPad()->XtoAbsPixel(xmax);
2534  py2 = fGedEditor->GetPad()->YtoAbsPixel(ytop);
2535  if (fGedEditor->GetPad()->GetCanvas())
2536  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE);
2537  fGedEditor->GetPad()->cd();
2538  fGedEditor->GetPad()->SetLineWidth(1);
2539  fGedEditor->GetPad()->SetLineColor(2);
2540  gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow);
2541  gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
2542  fPx1old = px1;
2543  fPy1old = py1;
2544  fPx2old = px2 ;
2545  fPy2old = py2;
2546  gVirtualX->Update(0);
2547  fSldYMin->SetNumber(ybottom);
2548  fSldYMax->SetNumber(ytop);
2549  } else if (fDelaydraw->GetState()==kButtonDown &&
2550  fDim0->GetState()==kButtonDown &&
2551  fCoordsCombo->GetSelected()==kCOORDS_CAR) {
2552  // 3D plot
2553  Float_t p1[3], p2[3], p3[3], p4[3], p5[3], p6[3], p7[3], p8[3];
2554  if (fGedEditor->GetPad()->GetCanvas())
2555  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE);
2556  fGedEditor->GetPad()->cd();
2557  TView *fView = fGedEditor->GetPad()->GetView();
2558  if (!fView) return;
2559  Double_t *rmin = fView->GetRmin();
2560  if (!rmin) return;
2561  Double_t *rmax = fView->GetRmax();
2562  if (!rmax) return;
2563  p1[0] = p2[0] = p3[0] = p4[0] = rmin[0];
2564  p5[0] = p6[0] = p7[0] = p8[0] = rmax[0];
2565  p1[1] = p4[1] = p5[1] = p8[1] =
2566  yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));
2567  p2[1] = p3[1] = p6[1] = p7[1] =
2568  yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));
2569  p1[2] = p2[2] = p5[2] = p6[2] = rmin[2];
2570  p3[2] = p4[2] = p7[2] = p8[2] = rmax[2];
2571  fGedEditor->GetPad()->SetLineWidth(1);
2572  fGedEditor->GetPad()->SetLineColor(2);
2573  PaintBox3D(fP2oldy, fP3oldy, fP7oldy, fP6oldy);
2574  PaintBox3D(fP1oldy, fP4oldy, fP8oldy, fP5oldy);
2575  PaintBox3D(p2, p3, p7, p6);
2576  PaintBox3D(p1, p4, p8, p5);
2577  for (Int_t i = 0; i<3; i++) {
2578  fP1oldy[i] = p1[i];
2579  fP2oldy[i] = p2[i];
2580  fP3oldy[i] = p3[i];
2581  fP4oldy[i] = p4[i];
2582  fP5oldy[i] = p5[i];
2583  fP6oldy[i] = p6[i];
2584  fP7oldy[i] = p7[i];
2585  fP8oldy[i] = p8[i];
2586  }
2587  fSldYMin->SetNumber(p1[1]);
2588  fSldYMax->SetNumber(p2[1]);
2589  } else if (fDelaydraw->GetState()==kButtonDown &&
2590  fDim0->GetState()==kButtonDown) {
2591  fSldYMin->SetNumber(yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5)));
2592  fSldYMax->SetNumber(yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5)));
2593  } else {
2594  yaxis->SetRange((Int_t)((fSliderY->GetMinPosition())+0.5),
2595  (Int_t)((fSliderY->GetMaxPosition())+0.5));
2596  fSldYMin->SetNumber(yaxis->GetBinLowEdge(yaxis->GetFirst()));
2597  fSldYMax->SetNumber(yaxis->GetBinUpEdge(yaxis->GetLast()));
2598  fClient->NeedRedraw(fSliderY,kTRUE);
2599  Update();
2600  }
2601  fClient->NeedRedraw(fSldYMin,kTRUE);
2602  fClient->NeedRedraw(fSldYMax,kTRUE);
2603 }
2604 
2605 ////////////////////////////////////////////////////////////////////////////////
2606 /// Slot connected to y-axis slider which initialises
2607 /// the "virtual" box which is drawn in delay draw mode.
2608 
2609 void TH2Editor::DoSliderYPressed()
2610 {
2611  if (fAvoidSignal) return;
2612  TAxis* yaxis = fHist->GetYaxis();
2613  Float_t xmin,xmax,ytop,ybottom;
2614  if (fDelaydraw->GetState()==kButtonDown && fDim->GetState()==kButtonDown) {
2615  // 2D plot:
2616  if (!fGedEditor->GetPad()) return;
2617  fGedEditor->GetPad()->cd();
2618  if (fGedEditor->GetPad()->GetCanvas())
2619  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kFALSE);
2620  fGedEditor->GetPad()->SetLineWidth(1);
2621  fGedEditor->GetPad()->SetLineColor(2);
2622  ybottom = yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));
2623  ytop = yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));
2624  xmin = fGedEditor->GetPad()->GetUxmin();
2625  xmax = fGedEditor->GetPad()->GetUxmax();
2626  fPx1old = fGedEditor->GetPad()->XtoAbsPixel(xmin);
2627  fPy1old = fGedEditor->GetPad()->YtoAbsPixel(ybottom);
2628  fPx2old = fGedEditor->GetPad()->XtoAbsPixel(xmax);
2629  fPy2old = fGedEditor->GetPad()->YtoAbsPixel(ytop);
2630  gVirtualX->DrawBox(fPx1old, fPy1old, fPx2old, fPy2old, TVirtualX::kHollow);
2631  } else if (fDelaydraw->GetState()==kButtonDown &&
2632  fDim0->GetState()==kButtonDown &&
2633  fCoordsCombo->GetSelected()==kCOORDS_CAR) {
2634  // 3D plot
2635  if (!fGedEditor->GetPad()) return;
2636  fGedEditor->GetPad()->cd();
2637  TView *fView = fGedEditor->GetPad()->GetView();
2638  if (!fView) return;
2639  Double_t *rmin = fView->GetRmin();
2640  if (!rmin) return;
2641  Double_t *rmax = fView->GetRmax();
2642  if (!rmax) return;
2643  fP1oldy[0] = fP2oldy[0] = fP3oldy[0] = fP4oldy[0] = rmin[0];
2644  fP5oldy[0] = fP6oldy[0] = fP7oldy[0] = fP8oldy[0] = rmax[0];
2645  fP1oldy[1] = fP4oldy[1] = fP5oldy[1] = fP8oldy[1] =
2646  yaxis->GetBinLowEdge((Int_t)((fSliderY->GetMinPosition())+0.5));
2647  fP2oldy[1] = fP3oldy[1] = fP6oldy[1] = fP7oldy[1] =
2648  yaxis->GetBinUpEdge((Int_t)((fSliderY->GetMaxPosition())+0.5));
2649  fP1oldy[2] = fP2oldy[2] = fP5oldy[2] = fP6oldy[2] = rmin[2];
2650  fP3oldy[2] = fP4oldy[2] = fP7oldy[2] = fP8oldy[2] = rmax[2];
2651  if (fGedEditor->GetPad()->GetCanvas())
2652  fGedEditor->GetPad()->GetCanvas()->FeedbackMode(kTRUE);
2653  fGedEditor->GetPad()->SetLineWidth(1);
2654  fGedEditor->GetPad()->SetLineColor(2);
2655  PaintBox3D(fP2oldy, fP3oldy, fP7oldy, fP6oldy);
2656  PaintBox3D(fP1oldy, fP4oldy, fP8oldy, fP5oldy);
2657  }
2658 }
2659 
2660 ////////////////////////////////////////////////////////////////////////////////
2661 /// Slot connected to the y-axis slider finalizing values after
2662 /// the slider movement.
2663 
2664 void TH2Editor::DoSliderYReleased()
2665 {
2666  if (fAvoidSignal) return;
2667  if (fDelaydraw->GetState()==kButtonDown) {
2668  fHist->GetYaxis()->SetRange((Int_t)((fSliderY->GetMinPosition())+0.5),
2669  (Int_t)((fSliderY->GetMaxPosition())+0.5));
2670  fSldYMin->SetNumber(fHist->GetYaxis()->GetBinLowEdge(fHist->GetYaxis()->GetFirst()));
2671  fSldYMax->SetNumber(fHist->GetYaxis()->GetBinUpEdge(fHist->GetYaxis()->GetLast()));
2672  Update();
2673  }
2674 
2675  TTreePlayer *player = (TTreePlayer*)TVirtualTreePlayer::GetCurrentPlayer();
2676  if (player) if (player->GetHistogram() == fHist) {
2677  Int_t last = fHist->GetYaxis()->GetLast();
2678  Int_t first = fHist->GetYaxis()->GetFirst();
2679  fBinYNumberEntry1->SetIntNumber(last-first+1);
2680  Update();
2681  }
2682 }
2683 
2684 ////////////////////////////////////////////////////////////////////////////////
2685 /// Slot connected to the Max/Min number entry fields showing y-axis range.
2686 
2687 void TH2Editor::DoYAxisRange()
2688 {
2689  if (fAvoidSignal) return;
2690  TAxis* yaxis = fHist->GetYaxis();
2691  Int_t ny = yaxis->GetNbins();
2692  Double_t width = yaxis->GetBinWidth(1);
2693 
2694  if ((fSldYMin->GetNumber()+width/2) < (yaxis->GetBinLowEdge(1)))
2695  fSldYMin->SetNumber(yaxis->GetBinLowEdge(1));
2696  if ((fSldYMax->GetNumber()-width/2) > (yaxis->GetBinUpEdge(ny)))
2697  fSldYMax->SetNumber(yaxis->GetBinUpEdge(ny));
2698 
2699  yaxis->SetRangeUser(fSldYMin->GetNumber()+width/2,
2700  fSldYMax->GetNumber()-width/2);
2701  Int_t nybinmin = yaxis -> GetFirst();
2702  Int_t nybinmax = yaxis -> GetLast();
2703  fSliderY->SetPosition((Double_t)(nybinmin),(Double_t)(nybinmax));
2704  Update();
2705 }
2706 
2707 ////////////////////////////////////////////////////////////////////////////////
2708 /// Slot connected to the fill area color.
2709 
2710 void TH2Editor::DoFillColor(Pixel_t color)
2711 {
2712  if (fAvoidSignal || !fGedEditor->GetPad()) return;
2713  fGedEditor->GetPad()->cd();
2714  fGedEditor->GetPad()->SetFrameFillColor(TColor::GetColor(color));
2715  Update();
2716 }
2717 
2718 ////////////////////////////////////////////////////////////////////////////////
2719 /// Slot connected to the fill area pattern.
2720 
2721 void TH2Editor::DoFillPattern(Style_t pattern)
2722 {
2723  if (fAvoidSignal || !fGedEditor->GetPad()) return;
2724  fGedEditor->GetPad()->cd();
2725  fGedEditor->GetPad()->SetFrameFillStyle(pattern);
2726  Update();
2727 }
2728 
2729 ////////////////////////////////////////////////////////////////////////////////
2730 /// Return the immediate histogram type (HIST, LEGO1-4, SURF1-5).
2731 
2732 TString TH2Editor::GetHistTypeLabel()
2733 {
2734  TString s="";
2735  switch (fTypeCombo->GetSelected()){
2736  case (-1) : {s = ""; break;}
2737  case (kTYPE_LEGO ): {s = "LEGO"; break;}
2738  case (kTYPE_LEGO1): {s = "LEGO1"; break;}
2739  case (kTYPE_LEGO2): {s = "LEGO2"; break;}
2740  case (kTYPE_LEGO3): {s = "LEGO3"; break;}
2741  case (kTYPE_LEGO4): {s = "LEGO4"; break;}
2742  case (kTYPE_SURF ): {s = "SURF"; break;}
2743  case (kTYPE_SURF1): {s = "SURF1"; break;}
2744  case (kTYPE_SURF2): {s = "SURF2"; break;}
2745  case (kTYPE_SURF3): {s = "SURF3"; break;}
2746  case (kTYPE_SURF4): {s = "SURF4"; break;}
2747  case (kTYPE_SURF5): {s = "SURF5"; break;}
2748  default: break;
2749  }
2750  return s;
2751 }
2752 
2753 ////////////////////////////////////////////////////////////////////////////////
2754 /// Return the immediate coordinate system of the histogram.
2755 /// (POL, CYL, SPH,PSR)
2756 
2757 TString TH2Editor::GetHistCoordsLabel()
2758 {
2759  TString s="";
2760  switch (fCoordsCombo->GetSelected()){
2761  case (-1) : {s = ""; break;}
2762  case (kCOORDS_CAR): {s = ""; break;}
2763  case (kCOORDS_POL): {s = "POL"; break;}
2764  case (kCOORDS_CYL): {s = "CYL"; break;}
2765  case (kCOORDS_SPH): {s = "SPH"; break;}
2766  case (kCOORDS_PSR): {s = "PSR"; break;}
2767  default: break;
2768  }
2769  return s;
2770 }
2771 
2772 ////////////////////////////////////////////////////////////////////////////////
2773 /// Returns histogram contour option (None,Cont0..5).
2774 
2775 TString TH2Editor::GetHistContLabel()
2776 {
2777  TString s="";
2778  switch (fContCombo->GetSelected()){
2779  case (-1) : {s = ""; break;}
2780  case (kCONT_NONE) : {s = ""; break;}
2781  case (kCONT_0) : {s = "CONT0"; break;}
2782  case (kCONT_1) : {s = "CONT1"; break;}
2783  case (kCONT_2) : {s = "CONT2"; break;}
2784  case (kCONT_3) : {s = "CONT3"; break;}
2785  case (kCONT_4) : {s = "CONT4"; break;}
2786  default: break;
2787  }
2788  return s;
2789 }
2790 
2791 ////////////////////////////////////////////////////////////////////////////////
2792 /// Return histogram additive options (Arr,Box,Col,Scat,Col,Text,E,Z,FB,BB).
2793 
2794 TString TH2Editor::GetHistAdditiveLabel()
2795 {
2796  TString s="";
2797  if (fDim->GetState()==kButtonDown) {
2798  if (fAddArr->GetState()==kButtonDown) s+="ARR";
2799  if (fAddBox->GetState()==kButtonDown) s+="BOX";
2800  if (fAddCol->GetState()==kButtonDown) s+="COL";
2801  if (fAddScat->GetState()==kButtonDown) s+="SCAT";
2802  if (fAddText->GetState()==kButtonDown) s+="TEXT";
2803  if (fAddPalette->GetState()==kButtonDown) s+="Z";
2804  } else if (fDim0->GetState()==kButtonDown){
2805  if (fAddPalette1->GetState()==kButtonDown) s+="Z";
2806  if (fAddError->GetState()==kButtonDown) s+="E";
2807  if (fAddFB->GetState()==kButtonUp) s+="FB";
2808  if (fAddBB->GetState()==kButtonUp) s+="BB";
2809  }
2810  return s;
2811 }
2812 
2813 ////////////////////////////////////////////////////////////////////////////////
2814 /// Return draw option string related to graphical cut in use.
2815 
2816 TString TH2Editor::GetCutOptionString()
2817 {
2818  TString cutopt = " ";
2819  TString opt = GetDrawOption();
2820  Int_t scut = opt.First('[');
2821  if (scut != -1) {
2822  Int_t ecut = opt.First(']');
2823  cutopt += opt(scut,ecut);
2824  }
2825  return cutopt;
2826 }
2827 
2828 ////////////////////////////////////////////////////////////////////////////////
2829 /// Create histogram type combo box.
2830 
2831 TGComboBox* TH2Editor::BuildHistTypeComboBox(TGFrame* parent, Int_t id)
2832 {
2833  TGComboBox *c = new TGComboBox(parent, id);
2834 
2835  c->AddEntry("Lego" , kTYPE_LEGO);
2836  c->AddEntry("Lego1", kTYPE_LEGO1);
2837  c->AddEntry("Lego2", kTYPE_LEGO2);
2838  c->AddEntry("Lego3", kTYPE_LEGO3);
2839  c->AddEntry("Lego4", kTYPE_LEGO4);
2840  c->AddEntry("Surf" , kTYPE_SURF);
2841  c->AddEntry("Surf1", kTYPE_SURF1);
2842  c->AddEntry("Surf2", kTYPE_SURF2);
2843  c->AddEntry("Surf3", kTYPE_SURF3);
2844  c->AddEntry("Surf4", kTYPE_SURF4);
2845  c->AddEntry("Surf5", kTYPE_SURF5);
2846 
2847  return c;
2848 }
2849 
2850 ////////////////////////////////////////////////////////////////////////////////
2851 /// Create coordinate system combo box.
2852 
2853 TGComboBox* TH2Editor::BuildHistCoordsComboBox(TGFrame* parent, Int_t id)
2854 {
2855  TGComboBox *c = new TGComboBox(parent, id);
2856 
2857  c->AddEntry("Cartesian", kCOORDS_CAR);
2858  c->AddEntry("Cylindric", kCOORDS_CYL);
2859  c->AddEntry("Polar", kCOORDS_POL);
2860  c->AddEntry("Rapidity", kCOORDS_PSR);
2861  c->AddEntry("Spheric", kCOORDS_SPH);
2862  TGListBox* lb = c->GetListBox();
2863  lb->Resize(lb->GetWidth(), 83);
2864 
2865  return c;
2866 }
2867 
2868 ////////////////////////////////////////////////////////////////////////////////
2869 /// Create contour combo box.
2870 
2871 TGComboBox* TH2Editor::BuildHistContComboBox(TGFrame* parent, Int_t id)
2872 {
2873  TGComboBox *c = new TGComboBox(parent, id);
2874 
2875  c->AddEntry("None" , kCONT_NONE);
2876  c->AddEntry("Cont0", kCONT_0);
2877  c->AddEntry("Cont1", kCONT_1);
2878  c->AddEntry("Cont2", kCONT_2);
2879  c->AddEntry("Cont3", kCONT_3);
2880  c->AddEntry("Cont4", kCONT_4);
2881 
2882  return c;
2883 }
2884 
2885 ////////////////////////////////////////////////////////////////////////////////
2886 /// Paint a square in 3D.
2887 
2888 void TH2Editor::PaintBox3D(Float_t *p1, Float_t *p2,Float_t *p3, Float_t *p4)
2889 {
2890  fGedEditor->GetPad()->PaintLine3D(p1, p2);
2891  fGedEditor->GetPad()->PaintLine3D(p2, p3);
2892  fGedEditor->GetPad()->PaintLine3D(p3, p4);
2893  fGedEditor->GetPad()->PaintLine3D(p4, p1);
2894 }
2895 ////////////////////////////////////////////////////////////////////////////////
2896 /// Give an array of dividers of n (without the trivial divider n))
2897 /// in the first entry the number of dividers is saved.
2898 
2899 Int_t* TH2Editor::Dividers(Int_t n)
2900 {
2901  Int_t* div;
2902  if (n <= 0) {
2903  div = new Int_t[1];
2904  div[0]=0;
2905  } else if (n == 1) {
2906  div = new Int_t[2];
2907  div[0]=div[1]=1;
2908  } else {
2909  div = new Int_t[(Int_t) n/2+2];
2910  div[0]=0;
2911  div[1]=1;
2912 
2913  Int_t num = 1;
2914  for (Int_t i=2; i <= n/2; i++) {
2915  if (n % i == 0) {
2916  num++;
2917  div[num] = i;
2918  }
2919  }
2920  num++;
2921  div[num]=n;
2922  div[0] = num;
2923  }
2924  return div;
2925 }
2926 
2927 ////////////////////////////////////////////////////////////////////////////////
2928 /// Skip TH1Editor in building list of editors.
2929 
2930 void TH2Editor::ActivateBaseClassEditors(TClass* /*cl*/)
2931 {
2932  fGedEditor->ActivateEditors(TH1::Class()->GetListOfBases(), kTRUE);
2933 }
2934 
2935 ////////////////////////////////////////////////////////////////////////////////
2936 /// If the contained histogram obj is deleted we must set its pointer to zero
2937 
2938 void TH2Editor::RecursiveRemove(TObject* obj)
2939 {
2940  if (obj == fHist) {
2941  fHist = 0;
2942  }
2943 }
2944