Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 <cstdlib>
13
14#include <iostream>
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
27Draw a Diamond.
28
29A diamond is defined by:
30
31- Its central left coordinates x1,y1
32- Its top central coordinates x2,y2
33
34A diamond has line attributes (see TAttLine) and fill area attributes (see TAttFill).
35
36Like for the class TPaveText, a TDiamond may have one or more line(s) of text inside.
37
38Begin_Macro(source)
39../../../tutorials/graphics/diamond.C
40End_Macro
41*/
42
43////////////////////////////////////////////////////////////////////////////////
44/// Diamond default constructor.
45
47{
48}
49
50////////////////////////////////////////////////////////////////////////////////
51/// Diamond standard constructor.
52
55{
56}
57
58////////////////////////////////////////////////////////////////////////////////
59/// Diamond destructor.
60
62{
63}
64
65////////////////////////////////////////////////////////////////////////////////
66/// Copy constructor.
67
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{
88}
89
90////////////////////////////////////////////////////////////////////////////////
91/// Draw this diamond with its current attributes.
92
94{
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
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
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
221 if (pTop || pL || pR || pBot)
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 (true) {
364 px = py = 0;
365 event = gVirtualX->RequestLocator(1, 1, px, py);
366
368
369 if (event != -1) { // button is released
370 ExecuteEvent(kButton1Up, px, py);
371 return;
372 }
373 }
374 }
375}
376
377////////////////////////////////////////////////////////////////////////////////
378/// Return 1 if the point (x,y) is inside the polygon defined by
379/// the diamond 0 otherwise.
380
382{
383
384 Double_t xd[4], yd[4];
385
386 xd[0] = fX1;
387 yd[0] = (fY2 + fY1) / 2.;
388 xd[1] = (fX2 + fX1) / 2.;
389 yd[1] = fY1;
390 xd[2] = fX2;
391 yd[2] = yd[0];
392 xd[3] = xd[1];
393 yd[3] = fY2;
394
395 return (Int_t)TMath::IsInside(x, y, 4, xd, yd);
396}
397
398////////////////////////////////////////////////////////////////////////////////
399/// Paint this diamond with its current attributes.
400
402{
403 if (!gPad) return;
404 Double_t x[7],y[7],depx,depy;
405 Double_t x1 = fX1;
406 Double_t y1 = fY1;
407 Double_t x2 = fX2;
408 Double_t y2 = fY2;
409 Int_t fillstyle = GetFillStyle();
410 Int_t fillcolor = GetFillColor();
411 Int_t linecolor = GetLineColor();
412 if (fBorderSize) {
413 Double_t wy = gPad->PixeltoY(0) - gPad->PixeltoY(fBorderSize);
414 Double_t wx = gPad->PixeltoX(fBorderSize) - gPad->PixeltoX(0);
415 // Draw the frame top right
416 if (y2-y1>x2-x1) {
417 depx = wx;
418 depy = 0;
419 }
420 else if (y2-y1<x2-x1) {
421 depx = 0;
422 depy = -wy;
423 }
424 else {
425 depx = wx;
426 depy = -wy;
427 }
428 x[0] = x[2] = (x1+x2)/2+depx;
429 x[1] = x2+depx;
430 x[3] = x1+depx;
431 y[0] = y2+depy;
432 y[2] = y1+depy;
433 y[1] = y[3] =(y1+y2)/2+depy;
434 x[4] = x[0]; y[4] = y[0];
435 SetFillStyle(fillstyle);
436 SetFillColor(linecolor);
437 TAttFill::Modify(); //Change fill area attributes only if necessary
438 gPad->PaintFillArea(4,x,y);
439 }
440 x[0] = x[2] = (x1+x2)/2;
441 x[1] = x2;
442 x[3] = x1;
443 y[0] = y2;
444 y[2] = y1;
445 y[1] = y[3] = (y1+y2)/2;
446 x[4] = x[0]; y[4] =y[0];
447 SetLineColor(linecolor);
448 SetFillColor(fillcolor);
449 TAttLine::Modify(); //Change line attributes only if necessary
450 TAttFill::Modify(); //Change fill area attributes only if necessary
451 gPad->PaintFillArea(4,x,y);
452 gPad->PaintPolyLine(5,x,y);
453
454 // Paint list of primitives (test,etc)
456}
457
458////////////////////////////////////////////////////////////////////////////////
459/// Save primitive as a C++ statement(s) on output stream out.
460
461void TDiamond::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
462{
463 Bool_t saved = gROOT->ClassSaved(TDiamond::Class());
464 if (saved) {
465 out<<" ";
466 } else {
467 out<<" TDiamond *";
468 }
469 out<<"diamond = new TDiamond("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2<<");"<<std::endl;
470
471 SaveFillAttributes(out,"diamond",0,1001);
472 SaveLineAttributes(out,"diamond",1,1,1);
473 SaveTextAttributes(out,"diamond",11,0,1,62,0.05);
474
475 SaveLines(out,"diamond",saved);
476 out<<" diamond->Draw();"<<std::endl;
477}
@ kMouseMotion
Definition Buttons.h:23
@ kArrowKeyRelease
Definition Buttons.h:21
@ kButton1Motion
Definition Buttons.h:20
@ kButton1Up
Definition Buttons.h:19
@ kArrowKeyPress
Definition Buttons.h:21
@ kButton1Down
Definition Buttons.h:17
@ kButton1Locate
Definition Buttons.h:22
@ kDiamond
Definition Buttons.h:37
@ kRightSide
Definition GuiTypes.h:373
@ kBottomSide
Definition GuiTypes.h:373
@ kTopSide
Definition GuiTypes.h:373
@ kLeftSide
Definition GuiTypes.h:373
@ kMove
Definition GuiTypes.h:374
@ kCross
Definition GuiTypes.h:374
#define b(i)
Definition RSha256.hxx:100
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:382
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t SetFillStyle
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t SetFillColor
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:406
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
virtual void Modify()
Change current fill area attributes if necessary.
Definition TAttFill.cxx:216
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:239
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:40
virtual void Modify()
Change current line attributes if necessary.
Definition TAttLine.cxx:247
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:275
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:373
Double_t GetX1() const
Definition TBox.h:51
Double_t fX1
X of 1st point.
Definition TBox.h:28
Double_t GetX2() const
Definition TBox.h:52
Double_t GetY1() const
Definition TBox.h:53
Double_t GetY2() const
Definition TBox.h:54
Double_t fY2
Y of 2nd point.
Definition TBox.h:31
Double_t fX2
X of 2nd point.
Definition TBox.h:30
Double_t fY1
Y of 1st point.
Definition TBox.h:29
Bool_t fResizing
! True if box is being resized
Definition TBox.h:32
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Definition TBufferFile.h:47
@ kWrite
Definition TBuffer.h:73
Draw a Diamond.
Definition TDiamond.h:17
TDiamond()
Diamond default constructor.
Definition TDiamond.cxx:46
void Draw(Option_t *option="") override
Draw this diamond with its current attributes.
Definition TDiamond.cxx:93
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TDiamond.cxx:109
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TDiamond.cxx:461
void Paint(Option_t *option="") override
Paint this diamond with its current attributes.
Definition TDiamond.cxx:401
void Streamer(TBuffer &) override
Stream an object of class TBox.
Int_t IsInside(Double_t x, Double_t y) const override
Return 1 if the point (x,y) is inside the polygon defined by the diamond 0 otherwise.
Definition TDiamond.cxx:381
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a diamond.
Definition TDiamond.cxx:85
~TDiamond() override
Diamond destructor.
Definition TDiamond.cxx:61
static TClass * Class()
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Computes distance from point (px,py) to the object.
Definition TObject.cxx:283
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:202
A Pave (see TPave) with text, lines or/and boxes inside.
Definition TPaveText.h:21
virtual void PaintPrimitives(Int_t mode)
Paint list of primitives in this pavetext.
virtual void SaveLines(std::ostream &out, const char *name, Bool_t saved)
Save lines of this pavetext as C++ statements on output stream out.
Int_t fBorderSize
window box bordersize in pixels
Definition TPave.h:26
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual Int_t YtoAbsPixel(Double_t y) const =0
virtual Double_t GetX2() const =0
virtual Int_t XtoAbsPixel(Double_t x) const =0
virtual Double_t GetY1() const =0
virtual Double_t GetY2() const =0
virtual Short_t GetBorderSize() const =0
virtual Double_t GetX1() const =0
void Streamer(TBuffer &) override
Stream an object of class TObject.
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y)
Function which returns kTRUE if point xp,yp lies inside the polygon defined by the np points in array...
Definition TMath.h:1233
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123