GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4LabelPainter.cxx
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4LabelPainter.h"
15 
16 #include "TROOT.h"
17 #include "TVirtualPad.h"
18 
20  TNamed(),
21  fdX0(0),
22  fdY0(0),
23  fbIsLabStreamed(kTRUE)
24 {
26 }
27 
28 TGo4LabelPainter::TGo4LabelPainter(const char *name, const char *title) :
29  TNamed(name, title ? title : "Go4 LabelPainter"),
30  fdX0(0),
31  fdY0(0),
32  fbIsLabStreamed(kFALSE)
33 {
35 }
36 
38 {
39  SetBit(kMustCleanup);
40  fdWidth = 0.25;
41  fdHeight = 0.22;
42  SetCaption("Empty label");
43  SetTextAlign(12); // left and central aligned
44  //SetTextSize(0.03); // % of pad height
45  SetTextSize(0); // this will let root scale fontsize depending on label frame
46  SetTextFont(102); // proportional font for alignment of equations
47  SetTextColor(GetLineColor());
48 }
49 
51 {
52  if (fxLabel) {
53  delete fxLabel;
54  fxLabel = nullptr;
55  }
56 }
57 
58 void TGo4LabelPainter::PaintLabel(Option_t *opt)
59 {
60  if(!gPad) return;
61  Double_t xrange = (gPad->GetUxmax()-gPad->GetUxmin());
62  Double_t yrange = (gPad->GetUymax()-gPad->GetUymin());
63  if(!CheckLabel()) {
64  // label was deleted by us or by root:
65  if(fdX0 == 0)
66  fdX0 = xrange/2; // default: place at x center
67  if(fdY0 == 0)
68  fdY0 = yrange/2; // default: place at y center
69  // JAM: these initial coordinates can be problematic if assigned histogram is not yet drawn completely...
71  fxLabel->AppendPad(opt); // only append to pad if not already there
72  } else {
73  // label is existing:
74  if (!gPad->GetListOfPrimitives()->FindObject(fxLabel))
75  fxLabel->AppendPad(opt); // label was cleared from pad, we redraw it
76 
77  // JAM: catch here the case that label box was drawn with unsuited coordinates:
78  if(((fxLabel->GetX2()- fxLabel->GetX1())<0.05*xrange) || (fxLabel->GetY2()- fxLabel->GetY1())<0.05*yrange)
79  {
80  Double_t x0 = xrange/2;
81  Double_t y0 = yrange/2;
82  Double_t xmax = 0.;
83  Double_t ymax = 0.;
84  LabelCoords(x0,y0,xmax,ymax);
85  fxLabel->SetX1(x0);
86  fxLabel->SetX2(xmax);
87  fxLabel->SetY1(y0);
88  fxLabel->SetY2(ymax);
89  //printf("TGo4LabelPainter::PaintLabel corrected label coords to: (%f %f) (%f %f)",x0,y0,xmax,ymax);
90  }
91 
92  fxLabel->SetLineColor(GetLineColor());
93  fxLabel->Clear(); // remove old text lines
94  }
95  fxLabel->AddText(fxCaption.Data());
96  fxLabel->AddText(" "); // dummy for automatic position of next line
97  fxLabel->AddLine(0,0,0,0);
98 }
99 
101 {
102  gROOT->GetListOfCanvases()->RecursiveRemove(fxLabel);
103 
104  // we do not delete label, but restore graphics properties though invisible
105  TString option=opt;
106  if(option.Contains("reset")) {
107  // case of reset option: discard old label geometry if
108  if(CheckLabel()) {
109  delete fxLabel;
110  fxLabel = nullptr;
111  }
112  }
113 }
114 
116 {
117  if (fxLabel)
118  fxLabel->Paint(opt);
119 }
120 
122 {
123  if(fxLabel)
124  fxLabel->Pop();
125 }
126 
128 {
129  if(!gPad) return nullptr;
130  // buffer external variables, since LabelCoords will change them
131  Double_t x0 = x, y0 = y, xmax = 0, ymax = 0;
132  LabelCoords(x0,y0,xmax,ymax);
133  TGo4Label* label = new TGo4Label(x0,y0,xmax,ymax);
134  label->SetOwner(this);
135  TAttText::Copy(*label);
136  TAttLine::Copy(*label);
137  TAttFill::Copy(*label);
138  return label;
139 }
140 
142 {
143  if (fbIsLabStreamed && fxLabel) {
144  // case of label was streamed from file: not yet in cleanup list!
145  fxLabel->SetOwner(this);
146  fbIsLabStreamed = kFALSE;
147  return kTRUE;
148  }
149 
151  // our label was deleted by user mouse menu (or pad clear!)just before
152  TGo4Label::fxLastDeleted = nullptr;
153  fxLabel = nullptr; // reset reference, will re-create label on next paint
154  return kFALSE;
155  }
156 
157  return fxLabel != nullptr;
158 }
159 
160 void TGo4LabelPainter::LabelCoords(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
161 {
162  Double_t xpmin = gPad->GetUxmin();
163  Double_t xpmax = gPad->GetUxmax();
164  Double_t ypmin = gPad->GetUymin();
165  Double_t ypmax = gPad->GetUymax(); // this delivers pad coordinates
166  Double_t dx = (xpmax - xpmin);
167  Double_t dy = (ypmax - ypmin);
168  Double_t width = fdWidth * dx;
169  Double_t height = fdHeight * dy; // width is in pad coordinates
170  xmax = gPad->XtoPad(xmin) + width;
171  ymax = gPad->YtoPad(ymin) + height; // calculate label geometry in pad coordinates
172  xmax = gPad->PadtoX(xmax);
173  ymax = gPad->PadtoY(ymax); // back to axis coordinates for initial pavetext
174 }
175 
177 {
178  return fxLabel ? fxLabel->GetX1() : 0;
179 }
180 
182 {
183  return fxLabel ? fxLabel->GetY1() : 0;
184 }
185 
187 {
188  return fxLabel ? fxLabel->GetX2() : 0;
189 }
190 
192 {
193  return fxLabel ? fxLabel->GetY2() : 0;
194 }
195 
197 
198 const void *TGo4Label::fxLastDeleted = nullptr;
199 
200 
201 void TGo4Label::Paint(Option_t *opt)
202 {
203  if (!gPad)
204  return;
205 
206  if (fxOwner)
207  TPaveText::Paint(opt);
208 
209  // suppress painting of labels without owner. This case
210  // happens after insert canvas in go4 (separate cloning
211  // of lists of primitive members), thus leading to a
212  // second "ghost label" for markers and conditions
213 }
214 
216 void TGo4Label::ExecuteEvent(Int_t event, Int_t px, Int_t py)
217 {
218  if(!gPad) return;
219  TPaveText::ExecuteEvent(event,px,py);
220  if(event == kButton1Up) {
221  TGo4LabelPainter* painter = dynamic_cast<TGo4LabelPainter*>(fxOwner);
222  if(painter)
223  painter->DisplayToFront();
224  }
225 }
226 
228 
229 const void *TGo4LabelConnector::fxLastDeleted = nullptr;
230 
232 void TGo4LabelConnector::Paint(Option_t *opt)
233 {
234  if (!gPad)
235  return;
236  if (fxOwner)
237  TLine::Paint(opt);
238  // suppress painting of label connectors without owner. This case
239  // happens after insert canvas in go4 (separate cloning
240  // of lists of primitive members), thus leading to a
241  // second "ghost label connector" for markers
242 }
static const void * fxLastDeleted
virtual void UnPaintLabel(Option_t *opt="")
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
TGo4Label * CreateCurrentLabel(Double_t x, Double_t y)
void Paint(Option_t *opt="") override
virtual ~TGo4LabelPainter()
virtual void PaintLabel(Option_t *opt="")
static const void * fxLastDeleted
void SetCaption(const char *txt)
void LabelCoords(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
void Paint(Option_t *opt="") override
void SetOwner(TObject *ob)
virtual void DisplayToFront(Option_t *opt="")
virtual void RePaintLabel(Option_t *opt="")