Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TButton.cxx
Go to the documentation of this file.
1 // @(#)root/gpad:$Id$
2 // Author: Rene Brun 01/07/96
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "Riostream.h"
13 #include "TROOT.h"
14 #include "TButton.h"
15 #include "TCanvas.h"
16 #include "TLatex.h"
17 
18 #include <string.h>
19 
20 ClassImp(TButton);
21 
22 
23 /** \class TButton
24 \ingroup gpad
25 
26 A TButton object is a user interface object.
27 
28 A TButton has a name and an associated action.
29 When the button is clicked with the left mouse button, the corresponding
30 action is executed.
31 
32 A TButton can be created by direct invocation of the constructors
33 or via the graphics editor.
34 
35 The action can be set via TButton::SetMethod.
36 The action can be any command. Examples of actions:
37  - "34+78" When the button is clicked, the result of addition is printed.
38  - ".x macro.C" . Clicking the button executes the macro macro.C
39 The action can be modified at any time via TButton::SetMethod.
40 
41 To modify the layout/size/contents of one or several buttons
42 in a canvas, you must set the canvas editable via TCanvas::SetEditable.
43 By default a TCanvas is editable.
44 By default a TDialogCanvas is not editable.
45 TButtons are in general placed in a TDialogCanvas.
46 
47 A TButton being a TPad, one can draw graphics primitives in it
48 when the TCanvas/TDialogCanvas is editable.
49 
50 Example of a macro creating a dialog canvas with buttons:
51 ~~~ {.cpp}
52 void but() {
53 // example of a dialog canvas with a few buttons
54 
55  TDialogCanvas *dialog = new TDialogCanvas("dialog","",200,300);
56 
57 // Create first button. Clicking on this button will execute 34+56
58  TButton *but1 = new TButton("button1","34+56",.05,.8,.45,.88);
59  but1->Draw();
60 
61 // Create second button. Clicking on this button will create a new canvas
62  TButton *but2 = new TButton("canvas","c2 = new TCanvas(\"c2\")",.55,.8,.95,.88);
63  but2->Draw();
64 
65 // Create third button. Clicking on this button will invoke the browser
66  but3 = new TButton("Browser","br = new TBrowser(\"br\")",0.25,0.54,0.75,0.64);
67  but3->SetFillColor(42);
68  but3->Draw();
69 
70 // Create last button with no name. Instead a graph is draw inside the button
71 // Clicking on this button will invoke the macro $ROOTSYS/tutorials/graphs/graph.C
72  button = new TButton("",".x tutorials/graphs/graph.C",0.15,0.15,0.85,0.38);
73  button->SetFillColor(42);
74  button->Draw();
75  button->SetEditable(kTRUE);
76  button->cd();
77 
78  Double_t x[8] = {0.08,0.21,0.34,0.48,0.61,0.7,0.81,0.92};
79  Double_t y[8] = {0.2,0.65,0.4,0.34,0.24,0.43,0.75,0.52};
80  TGraph *graph = new TGraph(8,x,y);
81  graph->SetMarkerColor(4);
82  graph->SetMarkerStyle(21);
83  graph->Draw("lp");
84 
85  dialog->cd();
86 }
87 ~~~
88 Executing the macro above produces the following dialog canvas:
89 
90 \image html gpad_dialogbuttons.png
91 */
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 /// Button default constructor.
95 
96 TButton::TButton(): TPad()
97 {
98  fFraming = 0;
99  fMethod = "";
100  fLogx = kFALSE;
101  fLogy = kFALSE;
102  SetEditable(kFALSE);
103  fFocused = 0;
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Button normal constructor.
108 ///
109 /// Note that the button coordinates x1,y1,x2,y2 are always in the range [0,1]
110 
111 TButton::TButton(const char *title, const char *method, Double_t x1, Double_t y1,Double_t x2, Double_t y2)
112  :TPad("button",title,x1,y1,x2,y2,18,2,1), TAttText(22,0,1,61,0.65)
113 {
114  fFraming=0;
115  SetBit(kCanDelete);
116  fModified = kTRUE;
117  fMethod = method;
118  if (strlen(title)) {
119  TLatex *text = new TLatex(0.5*(fX1+fX2),0.5*(fY1+fY2),title);
120  fPrimitives->Add(text);
121  }
122  fLogx = kFALSE;
123  fLogy = kFALSE;
124  SetEditable(kFALSE);
125  fFocused = 0;
126 }
127 
128 ////////////////////////////////////////////////////////////////////////////////
129 /// Button default destructor.
130 
131 TButton::~TButton()
132 {
133  if (fPrimitives) fPrimitives->Delete();
134 }
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 /// Draw this button with its current attributes.
138 
139 void TButton::Draw(Option_t *option)
140 {
141  if (fCanvas) AppendPad(option);
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 /// Execute action corresponding to one event.
146 ///
147 /// This member function is called when a Button object is clicked.
148 
149 void TButton::ExecuteEvent(Int_t event, Int_t px, Int_t py)
150 {
151  //check case where pressing a button deletes itself
152  if (!TestBit(kNotDeleted)) return;
153 
154  if (IsEditable()) {
155  TPad::ExecuteEvent(event,px,py);
156  return;
157  }
158 
159  TPad *cdpad = (TPad*)gROOT->GetSelectedPad();
160  HideToolTip(event);
161 
162  switch (event) {
163 
164  case kMouseEnter:
165  TPad::ExecuteEvent(event,px,py);
166  break;
167 
168  case kButton1Down:
169  SetBorderMode(-1);
170  fFocused=1;
171  Modified();
172  Update();
173  break;
174 
175  case kMouseMotion:
176 
177  break;
178 
179  case kButton1Motion:
180  if (px<XtoAbsPixel(1) && px>XtoAbsPixel(0) &&
181  py<YtoAbsPixel(0) && py>YtoAbsPixel(1)) {
182  if (!fFocused) {
183  SetBorderMode(-1);
184  fFocused=1;
185  Modified();
186  GetCanvas()->Modified();
187  Update();
188  }
189  } else if (fFocused) {
190  SetBorderMode(1);
191  fFocused=0;
192  Modified();
193  GetCanvas()->Modified();
194  Update();
195  }
196  break;
197 
198  case kButton1Up:
199  SetCursor(kWatch);
200  if (fFocused) {
201  if (cdpad) cdpad->cd();
202  gROOT->ProcessLine(GetMethod());
203  }
204  //check case where pressing a button deletes itself
205  if (!TestBit(kNotDeleted)) return;
206  SetBorderMode(1);
207  Modified();
208  Update();
209  SetCursor(kCross);
210  break;
211  }
212 }
213 
214 ////////////////////////////////////////////////////////////////////////////////
215 /// Paint this button with its current attributes.
216 
217 void TButton::Paint(Option_t *option)
218 {
219  if (!fCanvas) return;
220  if (!fPrimitives) fPrimitives = new TList();
221  TObject *obj = GetListOfPrimitives()->First();
222  if (obj && obj->InheritsFrom(TText::Class())) {
223  TLatex *text = (TLatex*)obj;
224  text->SetTitle(GetTitle());
225  text->SetTextSize(GetTextSize());
226  text->SetTextFont(GetTextFont());
227  text->SetTextAlign(GetTextAlign());
228  text->SetTextColor(GetTextColor());
229  text->SetTextAngle(GetTextAngle());
230  }
231  SetLogx(0);
232  SetLogy(0);
233  TPad::Paint(option); //only called for Postscript print
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// Paint is modified.
238 
239 void TButton::PaintModified()
240 {
241  if (!fCanvas) return;
242  if (!fPrimitives) fPrimitives = new TList();
243  TObject *obj = GetListOfPrimitives()->First();
244  if (obj && obj->InheritsFrom(TText::Class())) {
245  TLatex *text = (TLatex*)obj;
246  text->SetTitle(GetTitle());
247  text->SetTextSize(GetTextSize());
248  text->SetTextFont(GetTextFont());
249  text->SetTextAlign(GetTextAlign());
250  text->SetTextColor(GetTextColor());
251  text->SetTextAngle(GetTextAngle());
252  }
253  SetLogx(0);
254  SetLogy(0);
255  TPad::PaintModified();
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Set world coordinate system for the pad.
260 
261 void TButton::Range(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
262 {
263  TPad::Range(x1,y1,x2,y2);
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 /// Save primitive as a C++ statement(s) on output stream out
268 
269 void TButton::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
270 {
271  TPad *padsav = (TPad*)gPad;
272  char quote = '"';
273  if (gROOT->ClassSaved(TButton::Class())) {
274  out<<" ";
275  } else {
276  out<<" TButton *";
277  }
278  char *cm = (char*)GetMethod();
279  Int_t nch = strlen(cm);
280  char *cmethod = new char[nch+10];
281  Int_t i = 0;
282  while(*cm) {
283  if (*cm == '"') {
284  cmethod[i] = '\\';
285  i++;
286  }
287  cmethod[i] = *cm;
288  i++;
289  cm++;
290  }
291  cmethod[i] = 0;
292  out<<"button = new TButton("<<quote<<GetTitle()
293  <<quote<<","<<quote<<cmethod<<quote
294  <<","<<fXlowNDC
295  <<","<<fYlowNDC
296  <<","<<fXlowNDC+fWNDC
297  <<","<<fYlowNDC+fHNDC
298  <<");"<<std::endl;
299  delete [] cmethod;
300 
301  SaveFillAttributes(out,"button",0,1001);
302  SaveLineAttributes(out,"button",1,1,1);
303  SaveTextAttributes(out,"button",22,0,1,61,.65);
304 
305  if (GetBorderSize() != 2) {
306  out<<" button->SetBorderSize("<<GetBorderSize()<<");"<<std::endl;
307  }
308  if (GetBorderMode() != 1) {
309  out<<" button->SetBorderMode("<<GetBorderMode()<<");"<<std::endl;
310  }
311 
312  if (GetFraming()) out<<"button->SetFraming();"<<std::endl;
313  if (IsEditable()) out<<"button->SetEditable(kTRUE);"<<std::endl;
314 
315  out<<" button->Draw();"<<std::endl;
316 
317  TIter next(GetListOfPrimitives());
318  TObject *obj = next(); //do not save first primitive
319 
320  Int_t nprim = 0;
321  while ((obj = next())) {
322  if (!nprim) out<<" button->cd();"<<std::endl;
323  nprim++;
324  obj->SavePrimitive(out, (Option_t *)next.GetOption());
325  }
326 
327  if (nprim) out<<" "<<padsav->GetName()<<"->cd();"<<std::endl;
328  padsav->cd();
329 }
330 
331 ////////////////////////////////////////////////////////////////////////////////
332 /// if framing is set, button will be highlighted
333 
334 void TButton::SetFraming(Bool_t f)
335 {
336  fFraming=f;
337  if (f) SetBit(kFraming);
338  else ResetBit(kFraming);
339 }