Logo ROOT   6.12/07
Reference Guide
TDiamond.cxx
Go to the documentation of this file.
1 // @(#)root/graf:$Id$
2 // Author: Rene Brun 22/06/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 <stdlib.h>
13 
14 #include "Riostream.h"
15 #include "TBufferFile.h"
16 #include "TROOT.h"
17 #include "TDiamond.h"
18 #include "TVirtualPad.h"
19 #include "TVirtualX.h"
20 #include "TMath.h"
21 
23 
24 /** \class TDiamond
25 \ingroup BasicGraphics
26 
27 Draw a Diamond.
28 
29 A diamond is defined by:
30 
31 - Its central left coordinates x1,y1
32 - Its top central coordinates x2,y2
33 
34 A diamond has line attributes (see TAttLine) and fill area attributes (see TAttFill).
35 
36 Like for the class TPaveText, a TDiamond may have one or more line(s) of text inside.
37 
38 Begin_Macro(source)
39 ../../../tutorials/graphics/diamond.C
40 End_Macro
41 */
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Diamond default constructor.
45 
47 {
48 }
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 /// Diamond standard constructor.
52 
54  :TPaveText(x1,y1,x2,y2)
55 {
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////////
59 /// Diamond destructor.
60 
62 {
63 }
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /// Copy constructor.
67 
68 TDiamond::TDiamond(const TDiamond &diamond) : TPaveText()
69 {
71  TDiamond *p = (TDiamond*)(&diamond);
72  p->Streamer(b);
73  b.SetReadMode();
74  b.SetBufferOffset(0);
75  Streamer(b);
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Compute distance from point px,py to a diamond.
80 ///
81 /// Compute the closest distance of approach from point px,py to the
82 /// edges of this diamond.
83 /// The distance is computed in pixels units.
84 
86 {
87  return TPaveText::DistancetoPrimitive(px,py);
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Draw this diamond with its current attributes.
92 
93 void TDiamond::Draw(Option_t *option)
94 {
95  AppendPad(option);
96 
97 }
98 
99 ////////////////////////////////////////////////////////////////////////////////
100 /// Execute action corresponding to one event.
101 ///
102 /// This member function is called when a Diamond object is clicked.
103 ///
104 /// If the mouse is clicked inside the diamond, the diamond is moved.
105 ///
106 /// If the mouse is clicked on the 4 tops (pL,pR,pTop,pBot), the diamond is
107 /// rescaled.
108 
109 void TDiamond::ExecuteEvent(Int_t event, Int_t px, Int_t py)
110 {
111  if (!gPad) return;
112 
113  const Int_t kMaxDiff = 5;
114  const Int_t kMinSize = 20;
115 
116  static Int_t px1, px2, py1, py2, pxl, pyl, pxt, pyt, pxold, pyold;
117  static Int_t px1p, px2p, py1p, py2p;
118  static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
119  static Double_t x1c,x2c,x3c,x4c;
120  static Bool_t pTop, pL, pR, pBot, pINSIDE;
121  static Int_t i,x[5], y[5];
122  Int_t wx, wy;
123  TVirtualPad *parent;
124  Bool_t opaque = gPad->OpaqueMoving();
125  Bool_t ropaque = gPad->OpaqueResizing();
126 
127  if (!gPad->IsEditable()) return;
128 
129  parent = gPad;
130 
131  switch (event) {
132 
133  case kArrowKeyPress:
134  case kButton1Down:
135 
136  gVirtualX->SetLineColor(-1);
137  TAttLine::Modify(); //Change line attributes only if necessary
138  if (GetFillColor())
139  gVirtualX->SetLineColor(GetFillColor());
140  else
141  gVirtualX->SetLineColor(1);
142  gVirtualX->SetLineWidth(2);
143 
144  // No break !!!
145 
146  case kMouseMotion:
147 
148  px1 = gPad->XtoAbsPixel(GetX1());
149  py1 = gPad->YtoAbsPixel(GetY1());
150  px2 = gPad->XtoAbsPixel(GetX2());
151  py2 = gPad->YtoAbsPixel(GetY2());
152 
153  if (px1 < px2) {
154  pxl = px1;
155  pxt = px2;
156  } else {
157  pxl = px2;
158  pxt = px1;
159  }
160  if (py1 < py2) {
161  pyl = py1;
162  pyt = py2;
163  } else {
164  pyl = py2;
165  pyt = py1;
166  }
167 
168  px1p = parent->XtoAbsPixel(parent->GetX1()) + parent->GetBorderSize();
169  py1p = parent->YtoAbsPixel(parent->GetY1()) - parent->GetBorderSize();
170  px2p = parent->XtoAbsPixel(parent->GetX2()) - parent->GetBorderSize();
171  py2p = parent->YtoAbsPixel(parent->GetY2()) + parent->GetBorderSize();
172 
173  pTx = pBx = (pxl+pxt)/2;
174  pLy = pRy = (pyl+pyt)/2;
175  pTy = pyl;
176  pBy = pyt;
177  pLx = pxl;
178  pRx = pxt;
179 
180  pTop = pL = pR = pBot = pINSIDE = kFALSE;
181 
182  if ((TMath::Abs(px-(pxl+pxt)/2) < kMaxDiff) &&
183  (TMath::Abs(py - pyl) < kMaxDiff)) { // top edge
184  pxold = pxl; pyold = pyl; pTop = kTRUE;
185  gPad->SetCursor(kTopSide);
186  }
187 
188  if ((TMath::Abs(px-(pxl+pxt)/2) < kMaxDiff) &&
189  (TMath::Abs(py - pyt) < kMaxDiff)) { // bottom edge
190  pxold = pxt; pyold = pyt; pBot = kTRUE;
191  gPad->SetCursor(kBottomSide);
192  }
193 
194  if ((TMath::Abs(py-(pyl+pyt)/2) < kMaxDiff) &&
195  (TMath::Abs(px - pxl) < kMaxDiff)) { // left edge
196  pxold = pxl; pyold = pyl; pL = kTRUE;
197  gPad->SetCursor(kLeftSide);
198  }
199 
200  if ((TMath::Abs(py-(pyl+pyt)/2) < kMaxDiff) &&
201  (TMath::Abs(px - pxt) < kMaxDiff)) { // right edge
202  pxold = pxt; pyold = pyt; pR = kTRUE;
203  gPad->SetCursor(kRightSide);
204  }
205 
206  x1c = (py-pTy)*(pTx-pLx)/(pTy-pLy)+pTx;
207  x2c = (py-pTy)*(pRx-pTx)/(pRy-pTy)+pTx;
208  x3c = (py-pRy)*(pRx-pBx)/(pRy-pBy)+pRx;
209  x4c = (py-pBy)*(pBx-pLx)/(pBy-pLy)+pBx;
210 
211  if (px > x1c+kMaxDiff && px < x2c-kMaxDiff &&
212  px > x4c+kMaxDiff && px < x3c-kMaxDiff) { // inside box
213  pxold = px; pyold = py; pINSIDE = kTRUE;
214  if (event == kButton1Down)
215  gPad->SetCursor(kMove);
216  else
217  gPad->SetCursor(kCross);
218  }
219 
220  fResizing = kFALSE;
221  if (pTop || pL || pR || pBot)
222  fResizing = kTRUE;
223 
224  if (!pTop && !pL && !pR && !pBot && !pINSIDE)
225  gPad->SetCursor(kCross);
226 
227  break;
228 
229  case kArrowKeyRelease:
230  case kButton1Motion:
231 
232  wx = wy = 0;
233  x[0] = x[2] = x[4] = (px1+px2)/2;
234  x[1] = px2;
235  x[3] = px1;
236  y[0] = y[4] = py1;
237  y[2] = py2;
238  y[1] = y[3] = (py1+py2)/2;
239  if (pTop) {
240  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
241  py2 += py - pyold;
242  if (py2 > py1-kMinSize) { py2 = py1-kMinSize; wy = py2; }
243  if (py2 < py2p) { py2 = py2p; wy = py2; }
244  y[2] = py2;
245  y[1] = y[3] = (py1+py2)/2;
246  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
247  }
248  if (pBot) {
249  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
250  py1 += py - pyold;
251  if (py1 < py2+kMinSize) { py1 = py2+kMinSize; wy = py1; }
252  if (py1 > py1p) { py1 = py1p; wy = py1; }
253  y[0] = y[4] = py1;
254  y[1] = y[3] = (py1+py2)/2;
255  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
256  }
257  if (pL) {
258  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
259  px1 += px - pxold;
260  if (px1 > px2-kMinSize) { px1 = px2-kMinSize; wx = px1; }
261  if (px1 < px1p) { px1 = px1p; wx = px1; }
262  x[3] = px1;
263  x[0] = x[2] = x[4] = (px1+px2)/2;
264  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
265  }
266  if (pR) {
267  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
268  px2 += px - pxold;
269  if (px2 < px1+kMinSize) { px2 = px1+kMinSize; wx = px2; }
270  if (px2 > px2p) { px2 = px2p; wx = px2; }
271  x[1] = px2;
272  x[0] = x[2] = x[4] = (px1+px2)/2;
273  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
274  }
275  if (pINSIDE) {
276  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
277  Int_t dx = px - pxold;
278  Int_t dy = py - pyold;
279  px1 += dx; py1 += dy; px2 += dx; py2 += dy;
280  if (px1 < px1p) { dx = px1p - px1; px1 += dx; px2 += dx; wx = px+dx; }
281  if (px2 > px2p) { dx = px2 - px2p; px1 -= dx; px2 -= dx; wx = px-dx; }
282  if (py1 > py1p) { dy = py1 - py1p; py1 -= dy; py2 -= dy; wy = py-dy; }
283  if (py2 < py2p) { dy = py2p - py2; py1 += dy; py2 += dy; wy = py+dy; }
284  x[0] = x[2] = x[4] = (px1+px2)/2;
285  x[1] = px2;
286  x[3] = px1;
287  y[0] = y[4] = py1;
288  y[2] = py2;
289  y[1] = y[3] = (py1+py2)/2;
290  for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
291  }
292 
293  if (wx || wy) {
294  if (wx) px = wx;
295  if (wy) py = wy;
296  gVirtualX->Warp(px, py);
297  }
298 
299  pxold = px;
300  pyold = py;
301 
302  if ((pINSIDE && opaque) || (fResizing && ropaque)) {
303  if (pTop || pBot || pL || pR) {
304  fX1 = gPad->AbsPixeltoX(px1);
305  fY1 = gPad->AbsPixeltoY(py1);
306  fX2 = gPad->AbsPixeltoX(px2);
307  fY2 = gPad->AbsPixeltoY(py2);
308  }
309  if (pINSIDE) {
310  fX1 = gPad->AbsPixeltoX(px1);
311  fY1 = gPad->AbsPixeltoY(py1);
312  fX2 = gPad->AbsPixeltoX(px2);
313  fY2 = gPad->AbsPixeltoY(py2);
314  // if it was not a pad that was moved then it must have been
315  // a box or something like that so we have to redraw the pad
316  if (parent == gPad) gPad->Modified(kTRUE);
317  }
318 
319  if (pINSIDE) gPad->ShowGuidelines(this, event, 'i', true);
320  if (pTop) gPad->ShowGuidelines(this, event, 't', true);
321  if (pBot) gPad->ShowGuidelines(this, event, 'b', true);
322  if (pL) gPad->ShowGuidelines(this, event, 'l', true);
323  if (pR) gPad->ShowGuidelines(this, event, 'r', true);
324 
325  if (pTop || pL || pR || pBot)
326  gPad->Modified(kTRUE);
327  }
328 
329  break;
330 
331  case kButton1Up:
332 
333  if (opaque) {
334  gPad->ShowGuidelines(this, event);
335  } else {
336  if (pTop || pBot || pL || pR || pINSIDE) {
337  fX1 = gPad->AbsPixeltoX(px1);
338  fY1 = gPad->AbsPixeltoY(py1);
339  fX2 = gPad->AbsPixeltoX(px2);
340  fY2 = gPad->AbsPixeltoY(py2);
341  }
342 
343  if (pINSIDE) {
344  // if it was not a pad that was moved then it must have been
345  // a box or something like that so we have to redraw the pad
346  if (parent == gPad) gPad->Modified(kTRUE);
347  }
348  }
349 
350  if (pTop || pL || pR || pBot) gPad->Modified(kTRUE);
351 
352  if (!opaque) {
353  gVirtualX->SetLineColor(-1);
354  gVirtualX->SetLineWidth(-1);
355  }
356 
357  break;
358 
359  case kButton1Locate:
360 
361  ExecuteEvent(kButton1Down, px, py);
362 
363  while (1) {
364  px = py = 0;
365  event = gVirtualX->RequestLocator(1, 1, px, py);
366 
367  ExecuteEvent(kButton1Motion, px, py);
368 
369  if (event != -1) { // button is released
370  ExecuteEvent(kButton1Up, px, py);
371  return;
372  }
373  }
374  }
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// Paint this diamond with its current attributes.
379 
381 {
382  Double_t x[7],y[7],depx,depy;
383  Double_t x1 = fX1;
384  Double_t y1 = fY1;
385  Double_t x2 = fX2;
386  Double_t y2 = fY2;
387  Int_t fillstyle = GetFillStyle();
388  Int_t fillcolor = GetFillColor();
389  Int_t linecolor = GetLineColor();
390  if (fBorderSize) {
391  Double_t wy = gPad->PixeltoY(0) - gPad->PixeltoY(fBorderSize);
392  Double_t wx = gPad->PixeltoX(fBorderSize) - gPad->PixeltoX(0);
393  // Draw the frame top right
394  if (y2-y1>x2-x1) {
395  depx = wx;
396  depy = 0;
397  }
398  else if (y2-y1<x2-x1) {
399  depx = 0;
400  depy = -wy;
401  }
402  else {
403  depx = wx;
404  depy = -wy;
405  }
406  x[0] = x[2] = (x1+x2)/2+depx;
407  x[1] = x2+depx;
408  x[3] = x1+depx;
409  y[0] = y2+depy;
410  y[2] = y1+depy;
411  y[1] = y[3] =(y1+y2)/2+depy;
412  x[4] = x[0]; y[4] = y[0];
413  SetFillStyle(fillstyle);
414  SetFillColor(linecolor);
415  TAttFill::Modify(); //Change fill area attributes only if necessary
416  gPad->PaintFillArea(4,x,y);
417  }
418  x[0] = x[2] = (x1+x2)/2;
419  x[1] = x2;
420  x[3] = x1;
421  y[0] = y2;
422  y[2] = y1;
423  y[1] = y[3] = (y1+y2)/2;
424  x[4] = x[0]; y[4] =y[0];
425  SetLineColor(linecolor);
426  SetFillColor(fillcolor);
427  TAttLine::Modify(); //Change line attributes only if necessary
428  TAttFill::Modify(); //Change fill area attributes only if necessary
429  gPad->PaintFillArea(4,x,y);
430  gPad->PaintPolyLine(5,x,y);
431 
432  // Paint list of primitives (test,etc)
434 }
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// Save primitive as a C++ statement(s) on output stream out.
438 
439 void TDiamond::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
440 {
441  Bool_t saved = gROOT->ClassSaved(TDiamond::Class());
442  if (saved) {
443  out<<" ";
444  } else {
445  out<<" TDiamond *";
446  }
447  out<<"diamond = new TDiamond("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2<<");"<<std::endl;
448 
449  SaveFillAttributes(out,"diamond",0,1001);
450  SaveLineAttributes(out,"diamond",1,1,1);
451  SaveTextAttributes(out,"diamond",11,0,1,62,0.05);
452 
453  SaveLines(out,"diamond",saved);
454  out<<" diamond->Draw();"<<std::endl;
455 }
virtual void Draw(Option_t *option="")
Draw this diamond with its current attributes.
Definition: TDiamond.cxx:94
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:90
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TDiamond.cxx:110
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket...
Definition: TBufferFile.h:47
Double_t GetX2() const
Definition: TBox.h:53
const char Option_t
Definition: RtypesCore.h:62
Double_t fY2
Y of 2nd point.
Definition: TBox.h:33
#define gROOT
Definition: TROOT.h:402
virtual ~TDiamond()
Diamond destructor.
Definition: TDiamond.cxx:62
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Double_t GetY2() const
Definition: TBox.h:55
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:232
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
virtual Double_t GetX1() const =0
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:105
Double_t fY1
Y of 1st point.
Definition: TBox.h:31
static const double x2[5]
Double_t x[n]
Definition: legend1.C:17
Bool_t fResizing
! True if box is being resized
Definition: TBox.h:34
void Class()
Definition: Class.C:29
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition: TAttLine.cxx:260
virtual void Modify()
Change current fill area attributes if necessary.
Definition: TAttFill.cxx:209
virtual void Paint(Option_t *option="")
Paint this diamond with its current attributes.
Definition: TDiamond.cxx:381
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:49
virtual Short_t GetBorderSize() const =0
TDiamond()
Diamond default constructor.
Definition: TDiamond.cxx:47
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual Double_t GetY2() const =0
virtual void SaveTextAttributes(std::ostream &out, const char *name, Int_t alidef=12, Float_t angdef=0, Int_t coldef=1, Int_t fondef=61, Float_t sizdef=1)
Save text attributes as C++ statement(s) on output stream out.
Definition: TAttText.cxx:347
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
Draw a Diamond.
Definition: TDiamond.h:21
virtual Int_t XtoAbsPixel(Double_t x) const =0
Double_t fX2
X of 2nd point.
Definition: TBox.h:32
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition: TAttFill.cxx:232
Double_t fX1
X of 1st point.
Definition: TBox.h:30
void SetReadMode()
Set buffer in read mode.
Definition: TBuffer.cxx:281
Int_t fBorderSize
window box bordersize in pixels
Definition: TPave.h:26
#define gVirtualX
Definition: TVirtualX.h:350
virtual Double_t GetY1() const =0
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual Int_t YtoAbsPixel(Double_t y) const =0
static const double x1[5]
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
#define ClassImp(name)
Definition: Rtypes.h:359
Double_t GetX1() const
Definition: TBox.h:52
double Double_t
Definition: RtypesCore.h:55
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a pave.
Definition: TPave.cxx:196
Double_t y[n]
Definition: legend1.C:17
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a diamond.
Definition: TDiamond.cxx:86
virtual void SaveLines(std::ostream &out, const char *name, Bool_t saved)
Save lines of this pavetext as C++ statements on output stream out.
Definition: TPaveText.cxx:677
virtual Double_t GetX2() const =0
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
virtual void PaintPrimitives(Int_t mode)
Paint list of primitives in this pavetext.
Definition: TPaveText.cxx:422
#define gPad
Definition: TVirtualPad.h:285
Double_t GetY1() const
Definition: TBox.h:54
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
const Bool_t kTRUE
Definition: RtypesCore.h:87
TPaveText()
pavetext default constructor.
Definition: TPaveText.cxx:73
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TDiamond.cxx:440