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 "TVirtualPadPainter.h"
20#include "TCanvasImp.h"
21#include "TMath.h"
22
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/visualisation/graphics/diamond.C
40End_Macro
41*/
42
43////////////////////////////////////////////////////////////////////////////////
44/// Diamond default constructor.
45
49
50////////////////////////////////////////////////////////////////////////////////
51/// Diamond standard constructor.
52
57
58////////////////////////////////////////////////////////////////////////////////
59/// Diamond destructor.
60
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
89
90////////////////////////////////////////////////////////////////////////////////
91/// Draw this diamond with its current attributes.
92
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 || !gPad->IsEditable()) return;
112
113 auto &parent = *gPad;
114
115 const Int_t kMaxDiff = 5;
116 const Int_t kMinSize = 20;
117
118 static Int_t px1, px2, py1, py2, dpx1, dpy2;
119 static enum { pNone, pTop, pL, pR, pBot, pINSIDE } mode = pNone;
120 static bool firstPaint = kFALSE;
121 static Double_t oldX1, oldY1, oldX2, oldY2;
122 static Bool_t hasOld = kFALSE;
123 Bool_t opaque = parent.OpaqueMoving();
124 Bool_t ropaque = parent.OpaqueResizing();
125
126 auto paint_or_set = [&parent,this](Bool_t paint)
127 {
128 auto x1 = parent.AbsPixeltoX(px1);
129 auto y1 = parent.AbsPixeltoY(py1);
130 auto x2 = parent.AbsPixeltoX(px2);
131 auto y2 = parent.AbsPixeltoY(py2);
132 if (!paint) {
133 SetX1(parent.PadtoX(x1));
134 SetY1(parent.PadtoY(y1));
135 SetX2(parent.PadtoX(x2));
136 SetY2(parent.PadtoY(y2));
137 } else if (firstPaint) {
139 } else {
140 auto pp = parent.GetPainter();
141 Double_t arrx[5] = { x1, (x1+x2) / 2, x2, (x1+x2) / 2, x1 };
142 Double_t arry[5] = { (y1+y2)/2, y2, (y1+y2)/2, y1, (y1+y2)/2 };
143 pp->SetAttLine({GetFillColor() > 0 ? GetFillColor() : (Color_t) kBlack, 1, 2});
144 pp->DrawPolyLine(5, arrx, arry);
145 }
146 };
147
148 switch (event) {
149
150 case kArrowKeyPress:
151 case kButton1Down:
152
153 oldX1 = GetX1();
154 oldY1 = GetY1();
155 oldX2 = GetX2();
156 oldY2 = GetY2();
157 hasOld = kTRUE;
158
159 // No break !!!
160
161 case kMouseMotion:
162
163 px1 = parent.XtoAbsPixel(parent.XtoPad(GetX1()));
164 py1 = parent.YtoAbsPixel(parent.YtoPad(GetY1()));
165 px2 = parent.XtoAbsPixel(parent.XtoPad(GetX2()));
166 py2 = parent.YtoAbsPixel(parent.YtoPad(GetY2()));
167 if (px1 > px2)
168 std::swap(px1, px2);
169 if (py1 < py2)
170 std::swap(py1, py2);
171
172 if ((TMath::Abs(px-(px1+px2)/2) < kMaxDiff) && (TMath::Abs(py - py2) < kMaxDiff)) { // top edge
173 mode = pTop;
174 parent.SetCursor(kTopSide);
175 } else if ((TMath::Abs(px-(px1+px2)/2) < kMaxDiff) && (TMath::Abs(py - py1) < kMaxDiff)) { // bottom edge
176 mode = pBot;
177 parent.SetCursor(kBottomSide);
178 } else if ((TMath::Abs(py-(py1+py2)/2) < kMaxDiff) && (TMath::Abs(px - px1) < kMaxDiff)) { // left edge
179 mode = pL;
180 parent.SetCursor(kLeftSide);
181 } else if ((TMath::Abs(py-(py1+py2)/2) < kMaxDiff) && (TMath::Abs(px - px2) < kMaxDiff)) { // right edge
182 mode = pR;
183 parent.SetCursor(kRightSide);
184 } else if (IsInside(parent.PadtoX(parent.AbsPixeltoX(px)), parent.PadtoY(parent.AbsPixeltoY(py)))) {
185 mode = pINSIDE;
186 dpx1 = px - px1; // cursor position relative to top-left corner
187 dpy2 = py - py2;
188 parent.SetCursor(event == kButton1Down ? kMove : kCross);
189 } else {
190 mode = pNone;
191 parent.SetCursor(kCross);
192 }
193
194 fResizing = mode == pTop || mode == pL || mode == pR || mode == pBot;
196
197 break;
198
199 case kArrowKeyRelease:
200 case kButton1Motion: {
201 Int_t px1p = parent.XtoAbsPixel(parent.GetX1()) + parent.GetBorderSize();
202 Int_t py1p = parent.YtoAbsPixel(parent.GetY1()) - parent.GetBorderSize();
203 Int_t px2p = parent.XtoAbsPixel(parent.GetX2()) - parent.GetBorderSize();
204 Int_t py2p = parent.YtoAbsPixel(parent.GetY2()) + parent.GetBorderSize();
205 if (px1p > px2p)
206 std::swap(px1p, px2p);
207 if (py1p < py2p)
208 std::swap(py1p, py2p);
209
210 switch (mode) {
211 case pNone:
212 return;
213 case pTop:
215 py2 = TMath::Max(py2p, TMath::Min(py, py1 - kMinSize));
217 break;
218 case pBot:
220 py1 = TMath::Min(py1p, TMath::Max(py, py2 + kMinSize));
222 break;
223 case pL:
225 px1 = TMath::Max(px1p, TMath::Min(px, px2 - kMinSize));
227 break;
228 case pR:
230 px2 = TMath::Min(px2p, TMath::Max(px, px1 + kMinSize));
232 break;
233 case pINSIDE:
235 px2 += px - dpx1 - px1;
236 px1 = px - dpx1;
237 py1 += py - dpy2 - py2;
238 py2 = py - dpy2;
239 if (px1 < px1p) { px2 += px1p - px1; px1 = px1p; }
240 if (px2 > px2p) { px1 -= px2 - px2p; px2 = px2p; }
241 if (py1 > py1p) { py2 -= py1 - py1p; py1 = py1p; }
242 if (py2 < py2p) { py1 += py2p - py2; py2 = py2p; }
244 break;
245 }
246
247 if ((mode == pINSIDE && opaque) || (fResizing && ropaque)) {
248 switch(mode) {
249 case pINSIDE: parent.ShowGuidelines(this, event, 'i', true); break;
250 case pL: parent.ShowGuidelines(this, event, 'l', true); break;
251 case pR: parent.ShowGuidelines(this, event, 'r', true); break;
252 case pTop: parent.ShowGuidelines(this, event, 't', true); break;
253 case pBot: parent.ShowGuidelines(this, event, 'b', true); break;
254 default: break; // not involved
255 }
256 parent.Modified(kTRUE);
257 }
258
259 break;
260 }
261
262 case kButton1Up:
263
264 if (opaque || ropaque)
265 parent.ShowGuidelines(this, event);
266
267 if (gROOT->IsEscaped()) {
268 gROOT->SetEscape(kFALSE);
269 if (opaque && (mode != pNone)) {
270 if (hasOld) {
271 SetX1(oldX1);
272 SetY1(oldY1);
273 SetX2(oldX2);
274 SetY2(oldY2);
275 }
276 hasOld = kFALSE;
277 mode = pNone;
279 parent.ModifiedUpdate();
280 }
281 break;
282 }
283
284 if ((!opaque && mode == pINSIDE) || (!ropaque && fResizing))
286
287 if (mode != pNone)
288 parent.Modified(kTRUE);
289
290 mode = pNone;
292 hasOld = kFALSE;
293
294 break;
295
296 case kButton1Locate:
297 // Sergey: code is never used, has to be removed in ROOT7
298 ExecuteEvent(kButton1Down, px, py);
299
300 while (true) {
301 px = py = 0;
302 event = parent.GetCanvasImp()->RequestLocator(px, py);
303
305
306 if (event != -1) { // button is released
307 ExecuteEvent(kButton1Up, px, py);
308 return;
309 }
310 }
311 }
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// Return 1 if the point (x,y) is inside the polygon defined by
316/// the diamond 0 otherwise.
317
319{
320
321 Double_t xd[4], yd[4];
322
323 xd[0] = fX1;
324 yd[0] = (fY2 + fY1) / 2.;
325 xd[1] = (fX2 + fX1) / 2.;
326 yd[1] = fY1;
327 xd[2] = fX2;
328 yd[2] = yd[0];
329 xd[3] = xd[1];
330 yd[3] = fY2;
331
332 return (Int_t)TMath::IsInside(x, y, 4, xd, yd);
333}
334
335////////////////////////////////////////////////////////////////////////////////
336/// Paint this diamond with its current attributes.
337
339{
340 if (!gPad) return;
341 Double_t x[7],y[7],depx,depy;
342 Double_t x1 = fX1;
343 Double_t y1 = fY1;
344 Double_t x2 = fX2;
345 Double_t y2 = fY2;
349 if (fBorderSize) {
350 Double_t wy = gPad->PixeltoY(0) - gPad->PixeltoY(fBorderSize);
351 Double_t wx = gPad->PixeltoX(fBorderSize) - gPad->PixeltoX(0);
352 // Draw the frame top right
353 if (y2-y1>x2-x1) {
354 depx = wx;
355 depy = 0;
356 }
357 else if (y2-y1<x2-x1) {
358 depx = 0;
359 depy = -wy;
360 }
361 else {
362 depx = wx;
363 depy = -wy;
364 }
365 x[0] = x[2] = (x1+x2)/2+depx;
366 x[1] = x2+depx;
367 x[3] = x1+depx;
368 y[0] = y2+depy;
369 y[2] = y1+depy;
370 y[1] = y[3] =(y1+y2)/2+depy;
371 x[4] = x[0]; y[4] = y[0];
374 TAttFill::Modify(); //Change fill area attributes only if necessary
375 gPad->PaintFillArea(4,x,y);
376 }
377 x[0] = x[2] = (x1+x2)/2;
378 x[1] = x2;
379 x[3] = x1;
380 y[0] = y2;
381 y[2] = y1;
382 y[1] = y[3] = (y1+y2)/2;
383 x[4] = x[0]; y[4] =y[0];
386 TAttLine::Modify(); //Change line attributes only if necessary
387 TAttFill::Modify(); //Change fill area attributes only if necessary
388 gPad->PaintFillArea(4,x,y);
389 gPad->PaintPolyLine(5,x,y);
390
391 // Paint list of primitives (test,etc)
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Save primitive as a C++ statement(s) on output stream out.
397
398void TDiamond::SavePrimitive(std::ostream &out, Option_t *option)
399{
400 SavePrimitiveConstructor(out, Class(), "diamond", TString::Format("%g, %g, %g, %g", fX1, fY1, fX2, fY2));
401
402 SaveFillAttributes(out, "diamond", -1, -1);
403 SaveLineAttributes(out, "diamond", 1, 1, 1);
404 SaveTextAttributes(out, "diamond", 11, 0, 1, 62, 0.05);
405
406 SaveLines(out, "diamond", kTRUE);
407
408 SavePrimitiveDraw(out, "diamond", option);
409}
@ 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:374
@ kBottomSide
Definition GuiTypes.h:374
@ kTopSide
Definition GuiTypes.h:374
@ kLeftSide
Definition GuiTypes.h:374
@ kMove
Definition GuiTypes.h:375
@ kCross
Definition GuiTypes.h:375
#define b(i)
Definition RSha256.hxx:100
short Color_t
Color number (short)
Definition RtypesCore.h:100
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
@ kBlack
Definition Rtypes.h:66
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 mode
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:417
#define gPad
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:33
virtual void Modify()
Change current fill area attributes if necessary.
Definition TAttFill.cxx:212
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:240
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
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:289
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:399
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:398
void Paint(Option_t *option="") override
Paint this diamond with its current attributes.
Definition TDiamond.cxx:338
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:318
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: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:844
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:776
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.
void SetX2(Double_t x2) override
Set the X2 value.
Definition TPave.cxx:670
Int_t fBorderSize
window box bordersize in pixels
Definition TPave.h:26
void SetX1(Double_t x1) override
Set the X1 value.
Definition TPave.cxx:657
void SetY1(Double_t y1) override
Set the Y1 value.
Definition TPave.cxx:683
void SetY2(Double_t y2) override
Set the Y2 value.
Definition TPave.cxx:696
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:2459
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
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:1326
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122