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
22
23/** \class TDiamond
24\ingroup BasicGraphics
25
26Draw a Diamond.
27
28A diamond is defined by:
29
30- Its central left coordinates x1,y1
31- Its top central coordinates x2,y2
32
33A diamond has line attributes (see TAttLine) and fill area attributes (see TAttFill).
34
35Like for the class TPaveText, a TDiamond may have one or more line(s) of text inside.
36
37Begin_Macro(source)
38../../../tutorials/visualisation/graphics/diamond.C
39End_Macro
40*/
41
42////////////////////////////////////////////////////////////////////////////////
43/// Diamond default constructor.
44
48
49////////////////////////////////////////////////////////////////////////////////
50/// Diamond standard constructor.
51
56
57////////////////////////////////////////////////////////////////////////////////
58/// Diamond destructor.
59
63
64////////////////////////////////////////////////////////////////////////////////
65/// Copy constructor.
66
68{
70 TDiamond *p = (TDiamond*)(&diamond);
71 p->Streamer(b);
72 b.SetReadMode();
73 b.SetBufferOffset(0);
74 Streamer(b);
75}
76
77////////////////////////////////////////////////////////////////////////////////
78/// Compute distance from point px,py to a diamond.
79///
80/// Compute the closest distance of approach from point px,py to the
81/// edges of this diamond.
82/// The distance is computed in pixels units.
83
88
89////////////////////////////////////////////////////////////////////////////////
90/// Draw this diamond with its current attributes.
91
97
98////////////////////////////////////////////////////////////////////////////////
99/// Execute action corresponding to one event.
100///
101/// This member function is called when a Diamond object is clicked.
102///
103/// If the mouse is clicked inside the diamond, the diamond is moved.
104///
105/// If the mouse is clicked on the 4 tops (pL,pR,pTop,pBot), the diamond is
106/// rescaled.
107
109{
110 if (!gPad) return;
111
112 const Int_t kMaxDiff = 5;
113 const Int_t kMinSize = 20;
114
115 static Int_t px1, px2, py1, py2, pxl, pyl, pxt, pyt, pxold, pyold;
116 static Int_t px1p, px2p, py1p, py2p;
117 static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
118 static Double_t x1c,x2c,x3c,x4c;
119 static Bool_t pTop, pL, pR, pBot, pINSIDE;
120 static Int_t i,x[5], y[5];
121 Int_t wx, wy;
122 TVirtualPad *parent;
123 Bool_t opaque = gPad->OpaqueMoving();
124 Bool_t ropaque = gPad->OpaqueResizing();
125
126 if (!gPad->IsEditable()) return;
127
128 parent = gPad;
129
130 switch (event) {
131
132 case kArrowKeyPress:
133 case kButton1Down:
134
136 TAttLine::Modify(); //Change line attributes only if necessary
137 if (GetFillColor())
138 gVirtualX->SetLineColor(GetFillColor());
139 else
140 gVirtualX->SetLineColor(1);
141 gVirtualX->SetLineWidth(2);
142
143 // No break !!!
144
145 case kMouseMotion:
146
147 px1 = gPad->XtoAbsPixel(GetX1());
148 py1 = gPad->YtoAbsPixel(GetY1());
149 px2 = gPad->XtoAbsPixel(GetX2());
150 py2 = gPad->YtoAbsPixel(GetY2());
151
152 if (px1 < px2) {
153 pxl = px1;
154 pxt = px2;
155 } else {
156 pxl = px2;
157 pxt = px1;
158 }
159 if (py1 < py2) {
160 pyl = py1;
161 pyt = py2;
162 } else {
163 pyl = py2;
164 pyt = py1;
165 }
166
167 px1p = parent->XtoAbsPixel(parent->GetX1()) + parent->GetBorderSize();
168 py1p = parent->YtoAbsPixel(parent->GetY1()) - parent->GetBorderSize();
169 px2p = parent->XtoAbsPixel(parent->GetX2()) - parent->GetBorderSize();
170 py2p = parent->YtoAbsPixel(parent->GetY2()) + parent->GetBorderSize();
171
172 pTx = pBx = (pxl+pxt)/2;
173 pLy = pRy = (pyl+pyt)/2;
174 pTy = pyl;
175 pBy = pyt;
176 pLx = pxl;
177 pRx = pxt;
178
179 pTop = pL = pR = pBot = pINSIDE = kFALSE;
180
181 if ((TMath::Abs(px-(pxl+pxt)/2) < kMaxDiff) &&
182 (TMath::Abs(py - pyl) < kMaxDiff)) { // top edge
183 pxold = pxl; pyold = pyl; pTop = kTRUE;
184 gPad->SetCursor(kTopSide);
185 }
186
187 if ((TMath::Abs(px-(pxl+pxt)/2) < kMaxDiff) &&
188 (TMath::Abs(py - pyt) < kMaxDiff)) { // bottom edge
189 pxold = pxt; pyold = pyt; pBot = kTRUE;
190 gPad->SetCursor(kBottomSide);
191 }
192
193 if ((TMath::Abs(py-(pyl+pyt)/2) < kMaxDiff) &&
194 (TMath::Abs(px - pxl) < kMaxDiff)) { // left edge
195 pxold = pxl; pyold = pyl; pL = kTRUE;
196 gPad->SetCursor(kLeftSide);
197 }
198
199 if ((TMath::Abs(py-(pyl+pyt)/2) < kMaxDiff) &&
200 (TMath::Abs(px - pxt) < kMaxDiff)) { // right edge
201 pxold = pxt; pyold = pyt; pR = kTRUE;
202 gPad->SetCursor(kRightSide);
203 }
204
205 x1c = (py-pTy)*(pTx-pLx)/(pTy-pLy)+pTx;
206 x2c = (py-pTy)*(pRx-pTx)/(pRy-pTy)+pTx;
207 x3c = (py-pRy)*(pRx-pBx)/(pRy-pBy)+pRx;
208 x4c = (py-pBy)*(pBx-pLx)/(pBy-pLy)+pBx;
209
210 if (px > x1c+kMaxDiff && px < x2c-kMaxDiff &&
211 px > x4c+kMaxDiff && px < x3c-kMaxDiff) { // inside box
212 pxold = px; pyold = py; pINSIDE = kTRUE;
213 if (event == kButton1Down)
214 gPad->SetCursor(kMove);
215 else
216 gPad->SetCursor(kCross);
217 }
218
220 if (pTop || pL || pR || pBot)
222
223 if (!pTop && !pL && !pR && !pBot && !pINSIDE)
224 gPad->SetCursor(kCross);
225
226 break;
227
228 case kArrowKeyRelease:
229 case kButton1Motion:
230
231 wx = wy = 0;
232 x[0] = x[2] = x[4] = (px1+px2)/2;
233 x[1] = px2;
234 x[3] = px1;
235 y[0] = y[4] = py1;
236 y[2] = py2;
237 y[1] = y[3] = (py1+py2)/2;
238 if (pTop) {
239 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
240 py2 += py - pyold;
241 if (py2 > py1-kMinSize) { py2 = py1-kMinSize; wy = py2; }
242 if (py2 < py2p) { py2 = py2p; wy = py2; }
243 y[2] = py2;
244 y[1] = y[3] = (py1+py2)/2;
245 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
246 }
247 if (pBot) {
248 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
249 py1 += py - pyold;
250 if (py1 < py2+kMinSize) { py1 = py2+kMinSize; wy = py1; }
251 if (py1 > py1p) { py1 = py1p; wy = py1; }
252 y[0] = y[4] = py1;
253 y[1] = y[3] = (py1+py2)/2;
254 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
255 }
256 if (pL) {
257 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
258 px1 += px - pxold;
259 if (px1 > px2-kMinSize) { px1 = px2-kMinSize; wx = px1; }
260 if (px1 < px1p) { px1 = px1p; wx = px1; }
261 x[3] = px1;
262 x[0] = x[2] = x[4] = (px1+px2)/2;
263 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
264 }
265 if (pR) {
266 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
267 px2 += px - pxold;
268 if (px2 < px1+kMinSize) { px2 = px1+kMinSize; wx = px2; }
269 if (px2 > px2p) { px2 = px2p; wx = px2; }
270 x[1] = px2;
271 x[0] = x[2] = x[4] = (px1+px2)/2;
272 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
273 }
274 if (pINSIDE) {
275 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
276 Int_t dx = px - pxold;
277 Int_t dy = py - pyold;
278 px1 += dx; py1 += dy; px2 += dx; py2 += dy;
279 if (px1 < px1p) { dx = px1p - px1; px1 += dx; px2 += dx; wx = px+dx; }
280 if (px2 > px2p) { dx = px2 - px2p; px1 -= dx; px2 -= dx; wx = px-dx; }
281 if (py1 > py1p) { dy = py1 - py1p; py1 -= dy; py2 -= dy; wy = py-dy; }
282 if (py2 < py2p) { dy = py2p - py2; py1 += dy; py2 += dy; wy = py+dy; }
283 x[0] = x[2] = x[4] = (px1+px2)/2;
284 x[1] = px2;
285 x[3] = px1;
286 y[0] = y[4] = py1;
287 y[2] = py2;
288 y[1] = y[3] = (py1+py2)/2;
289 for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
290 }
291
292 if (wx || wy) {
293 if (wx) px = wx;
294 if (wy) py = wy;
295 gVirtualX->Warp(px, py);
296 }
297
298 pxold = px;
299 pyold = py;
300
301 if ((pINSIDE && opaque) || (fResizing && ropaque)) {
302 if (pTop || pBot || pL || pR) {
303 fX1 = gPad->AbsPixeltoX(px1);
304 fY1 = gPad->AbsPixeltoY(py1);
305 fX2 = gPad->AbsPixeltoX(px2);
306 fY2 = gPad->AbsPixeltoY(py2);
307 }
308 if (pINSIDE) {
309 fX1 = gPad->AbsPixeltoX(px1);
310 fY1 = gPad->AbsPixeltoY(py1);
311 fX2 = gPad->AbsPixeltoX(px2);
312 fY2 = gPad->AbsPixeltoY(py2);
313 // if it was not a pad that was moved then it must have been
314 // a box or something like that so we have to redraw the pad
315 if (parent == gPad) gPad->Modified(kTRUE);
316 }
317
318 if (pINSIDE) gPad->ShowGuidelines(this, event, 'i', true);
319 if (pTop) gPad->ShowGuidelines(this, event, 't', true);
320 if (pBot) gPad->ShowGuidelines(this, event, 'b', true);
321 if (pL) gPad->ShowGuidelines(this, event, 'l', true);
322 if (pR) gPad->ShowGuidelines(this, event, 'r', true);
323
324 if (pTop || pL || pR || pBot)
325 gPad->Modified(kTRUE);
326 }
327
328 break;
329
330 case kButton1Up:
331
332 if (opaque) {
333 gPad->ShowGuidelines(this, event);
334 } else {
335 if (pTop || pBot || pL || pR || pINSIDE) {
336 fX1 = gPad->AbsPixeltoX(px1);
337 fY1 = gPad->AbsPixeltoY(py1);
338 fX2 = gPad->AbsPixeltoX(px2);
339 fY2 = gPad->AbsPixeltoY(py2);
340 }
341
342 if (pINSIDE) {
343 // if it was not a pad that was moved then it must have been
344 // a box or something like that so we have to redraw the pad
345 if (parent == gPad) gPad->Modified(kTRUE);
346 }
347 }
348
349 if (pTop || pL || pR || pBot) gPad->Modified(kTRUE);
350
351 if (!opaque) {
352 gVirtualX->SetLineColor(-1);
353 gVirtualX->SetLineWidth(-1);
354 }
355
356 break;
357
358 case kButton1Locate:
359
360 ExecuteEvent(kButton1Down, px, py);
361
362 while (true) {
363 px = py = 0;
364 event = gVirtualX->RequestLocator(1, 1, px, py);
365
367
368 if (event != -1) { // button is released
369 ExecuteEvent(kButton1Up, px, py);
370 return;
371 }
372 }
373 }
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Return 1 if the point (x,y) is inside the polygon defined by
378/// the diamond 0 otherwise.
379
381{
382
383 Double_t xd[4], yd[4];
384
385 xd[0] = fX1;
386 yd[0] = (fY2 + fY1) / 2.;
387 xd[1] = (fX2 + fX1) / 2.;
388 yd[1] = fY1;
389 xd[2] = fX2;
390 yd[2] = yd[0];
391 xd[3] = xd[1];
392 yd[3] = fY2;
393
394 return (Int_t)TMath::IsInside(x, y, 4, xd, yd);
395}
396
397////////////////////////////////////////////////////////////////////////////////
398/// Paint this diamond with its current attributes.
399
401{
402 if (!gPad) return;
403 Double_t x[7],y[7],depx,depy;
404 Double_t x1 = fX1;
405 Double_t y1 = fY1;
406 Double_t x2 = fX2;
407 Double_t y2 = fY2;
411 if (fBorderSize) {
412 Double_t wy = gPad->PixeltoY(0) - gPad->PixeltoY(fBorderSize);
413 Double_t wx = gPad->PixeltoX(fBorderSize) - gPad->PixeltoX(0);
414 // Draw the frame top right
415 if (y2-y1>x2-x1) {
416 depx = wx;
417 depy = 0;
418 }
419 else if (y2-y1<x2-x1) {
420 depx = 0;
421 depy = -wy;
422 }
423 else {
424 depx = wx;
425 depy = -wy;
426 }
427 x[0] = x[2] = (x1+x2)/2+depx;
428 x[1] = x2+depx;
429 x[3] = x1+depx;
430 y[0] = y2+depy;
431 y[2] = y1+depy;
432 y[1] = y[3] =(y1+y2)/2+depy;
433 x[4] = x[0]; y[4] = y[0];
436 TAttFill::Modify(); //Change fill area attributes only if necessary
437 gPad->PaintFillArea(4,x,y);
438 }
439 x[0] = x[2] = (x1+x2)/2;
440 x[1] = x2;
441 x[3] = x1;
442 y[0] = y2;
443 y[2] = y1;
444 y[1] = y[3] = (y1+y2)/2;
445 x[4] = x[0]; y[4] =y[0];
448 TAttLine::Modify(); //Change line attributes only if necessary
449 TAttFill::Modify(); //Change fill area attributes only if necessary
450 gPad->PaintFillArea(4,x,y);
451 gPad->PaintPolyLine(5,x,y);
452
453 // Paint list of primitives (test,etc)
455}
456
457////////////////////////////////////////////////////////////////////////////////
458/// Save primitive as a C++ statement(s) on output stream out.
459
460void TDiamond::SavePrimitive(std::ostream &out, Option_t *option)
461{
462 SavePrimitiveConstructor(out, Class(), "diamond", TString::Format("%g, %g, %g, %g", fX1, fY1, fX2, fY2));
463
464 SaveFillAttributes(out, "diamond", 0, 1001);
465 SaveLineAttributes(out, "diamond", 1, 1, 1);
466 SaveTextAttributes(out, "diamond", 11, 0, 1, 62, 0.05);
467
468 SaveLines(out, "diamond", kTRUE);
469
470 SavePrimitiveDraw(out, "diamond", option);
471}
@ 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:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 gPad
#define gVirtualX
Definition TVirtualX.h:337
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:31
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:32
virtual void Modify()
Change current fill area attributes if necessary.
Definition TAttFill.cxx:215
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:238
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:35
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:42
virtual void Modify()
Change current line attributes if necessary.
Definition TAttLine.cxx:246
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:274
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:372
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:45
void Draw(Option_t *option="") override
Draw this diamond with its current attributes.
Definition TDiamond.cxx:92
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TDiamond.cxx:108
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TDiamond.cxx:460
void Paint(Option_t *option="") override
Paint this diamond with its current attributes.
Definition TDiamond.cxx:400
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:380
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a diamond.
Definition TDiamond.cxx:84
~TDiamond() override
Diamond destructor.
Definition TDiamond.cxx:60
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:284
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:822
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:771
A Pave (see TPave) with text, lines or/and boxes inside.
Definition TPaveText.h:21
virtual void SaveLines(std::ostream &out, const char *name, Bool_t)
Save lines of this pavetext as C++ statements on output stream out.
virtual void PaintPrimitives(Int_t mode)
Paint list of primitives in this pavetext.
Int_t fBorderSize
window box bordersize in pixels
Definition TPave.h:26
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
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
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:1320
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124