Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TBox.cxx
Go to the documentation of this file.
1// @(#)root/graf:$Id$
2// Author: Rene Brun 12/12/94
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 "TROOT.h"
16#include "TBuffer.h"
17#include "TBox.h"
18#include "TVirtualPad.h"
19#include "TVirtualPadPainter.h"
20#include "TCanvasImp.h"
21#include "TClass.h"
22#include "TMath.h"
23#include "TPoint.h"
24
25
26/** \class TBox
27\ingroup BasicGraphics
28
29Create a Box.
30
31A box is defined by :
32
33- Its bottom left coordinates x1,y1
34- Its top right coordinates x2,y2
35
36A box has line attributes (see TAttLine) and fill area attributes (see TAttFill).
37*/
38
39////////////////////////////////////////////////////////////////////////////////
40/// Box default constructor.
41
43{
44 fTip = nullptr;
45 fX1 = 0.;
46 fY1 = 0.;
47 fX2 = 0.;
48 fY2 = 0.;
50}
51
52////////////////////////////////////////////////////////////////////////////////
53/// Box standard constructor.
54
56 : TObject(), TAttLine(), TAttFill()
57{
58 if (x2 >= x1) {fX1 =x1; fX2 = x2;}
59 else {fX1 = x2; fX2 = x1;}
60 if (y2 >= y1) {fY1 =y1; fY2 = y2;}
61 else {fY1 = y2; fY2 = y1;}
63 fTip = nullptr;
64}
65
66////////////////////////////////////////////////////////////////////////////////
67/// Box destructor.
68
70{
71 if (fTip && gPad) {
72 gPad->CloseToolTip(fTip);
73 gPad->DeleteToolTip(fTip);
74 }
75}
76
77////////////////////////////////////////////////////////////////////////////////
78/// Box copy constructor.
79
81{
82 fX1 = 0.;
83 fY1 = 0.;
84 fX2 = 0.;
85 fY2 = 0.;
87 ((TBox&)box).TBox::Copy(*this);
88}
89
90////////////////////////////////////////////////////////////////////////////////
91/// Assignment operator.
92
94{
95 if(this!=&b) {
97 TAttLine::operator=(b);
98 TAttFill::operator=(b);
99 fTip=b.fTip;
100 fX1=b.fX1;
101 fY1=b.fY1;
102 fX2=b.fX2;
103 fY2=b.fY2;
104 fResizing=b.fResizing;
105 }
106 return *this;
107}
108
109////////////////////////////////////////////////////////////////////////////////
110/// Copy a Box.
111
112void TBox::Copy(TObject &obj) const
113{
114 TObject::Copy(obj);
115 TAttLine::Copy(((TBox&)obj));
116 TAttFill::Copy(((TBox&)obj));
117 ((TBox&)obj).fX1 = fX1;
118 ((TBox&)obj).fY1 = fY1;
119 ((TBox&)obj).fX2 = fX2;
120 ((TBox&)obj).fY2 = fY2;
121 ((TBox&)obj).fResizing = fResizing;
122 ((TBox&)obj).fTip = nullptr; //FIXME
123}
124
125////////////////////////////////////////////////////////////////////////////////
126/// Compute distance from point px,py to a box.
127///
128/// Compute the closest distance of approach from point px,py to the
129/// edges of this box.
130/// The distance is computed in pixels units.
131///
132/// In case of a filled box the distance returned is 0 if the point
133/// (px,py) is inside the box, and is huge if the point is outside.
134
136{
137 if (!gPad) return 9999;
138 Int_t pxl, pyl, pxt, pyt;
139 Int_t px1 = gPad->XtoAbsPixel(fX1);
140 Int_t py1 = gPad->YtoAbsPixel(fY1);
141 Int_t px2 = gPad->XtoAbsPixel(fX2);
142 Int_t py2 = gPad->YtoAbsPixel(fY2);
143
144 Bool_t isBox = !(InheritsFrom("TPave") || InheritsFrom("TWbox"));
145
146 if (isBox) {
147 if (gPad->GetLogx()) {
148 if (fX1>0) px1 = gPad->XtoAbsPixel(TMath::Log10(fX1));
149 if (fX2>0) px2 = gPad->XtoAbsPixel(TMath::Log10(fX2));
150 }
151 if (gPad->GetLogy()) {
152 if (fY1>0) py1 = gPad->YtoAbsPixel(TMath::Log10(fY1));
153 if (fY2>0) py2 = gPad->YtoAbsPixel(TMath::Log10(fY2));
154 }
155 }
156
157 if (px1 < px2) {pxl = px1; pxt = px2;}
158 else {pxl = px2; pxt = px1;}
159 if (py1 < py2) {pyl = py1; pyt = py2;}
160 else {pyl = py2; pyt = py1;}
161
162 // Are we inside the box?
163 if (GetFillStyle()) {
164 if ( (px >= pxl && px <= pxt) && (py >= pyl && py <= pyt) ) return 0;
165 else return 9999;
166 }
167
168 // Are we on the edges?
169 Int_t dxl = TMath::Abs(px - pxl);
170 if (py < pyl) dxl += pyl - py;
171 if (py > pyt) dxl += py - pyt;
172 Int_t dxt = TMath::Abs(px - pxt);
173 if (py < pyl) dxt += pyl - py;
174 if (py > pyt) dxt += py - pyt;
175 Int_t dyl = TMath::Abs(py - pyl);
176 if (px < pxl) dyl += pxl - px;
177 if (px > pxt) dyl += px - pxt;
178 Int_t dyt = TMath::Abs(py - pyt);
179 if (px < pxl) dyt += pxl - px;
180 if (px > pxt) dyt += px - pxt;
181
183 if (dxt < distance) distance = dxt;
184 if (dyl < distance) distance = dyl;
185 if (dyt < distance) distance = dyt;
186
187 return distance - Int_t(0.5*fLineWidth);
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Draw this box with its current attributes.
192/// if the box has no fill style (ie fill style=0), the box contour is drawn
193/// if the box has a fill style, the box contour is not drawn by default.
194/// to force the contour to be drawn, specify option "l"
195
197{
199
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Draw this box with new coordinates.
204
206{
207 TBox *newbox = new TBox(x1,y1,x2,y2);
210 newbox->SetBit(kCanDelete);
211 newbox->AppendPad();
212 return newbox;
213}
214
215////////////////////////////////////////////////////////////////////////////////
216/// Execute action corresponding to one event.
217///
218/// This member function is called when a BOX/WBOX/PAD object is clicked.
219///
220/// If the mouse is clicked in one of the 4 corners of the box (pA,pB,pC,pD)
221/// the box is resized with the rubber rectangle.
222///
223/// If the mouse is clicked inside the box, the box is moved.
224///
225/// If the mouse is clicked on the 4 edges (pL,pR,pTop,pBot), the box is
226/// rescaled parallel to this edge (same as Motif window manager).
227///
228/// Note that this function is duplicated on purpose by TPad::ExecuteEvent.
229/// If somebody modifies this function, may be similar changes should also
230/// be applied to TPad::ExecuteEvent.
231
233{
234 if (!gPad) return;
235 if (!gPad->IsEditable() && event != kMouseEnter) return;
236
237 if (TestBit(kCannotMove)) return;
238
239 Bool_t isBox = !(InheritsFrom("TPave") || InheritsFrom("TWbox"));
240
241 const Int_t kMaxDiff = 7;
242 const Int_t kMinSize = 20;
243
244 static Int_t px1, px2, py1, py2, pxl, pyl, pxt, pyt, pxold, pyold;
245 static Int_t px1p, px2p, py1p, py2p, pxlp, pylp, pxtp, pytp;
246 static Double_t oldX1, oldY1, oldX2, oldY2;
247 static Bool_t pA, pB, pC, pD, pTop, pL, pR, pBot, pINSIDE;
248 Int_t wx, wy;
249 auto parent = gPad;
250 auto pp = parent->GetPainter();
251 Bool_t opaque = gPad->OpaqueMoving();
252 Bool_t ropaque = gPad->OpaqueResizing();
253
254 // convert to user coordinates and either paint ot set back
255 auto action = [parent,pp,isBox,this](Bool_t paint, Int_t _x1, Int_t _y1, Int_t _x2, Int_t _y2) {
256 auto x1 = parent->AbsPixeltoX(_x1);
257 auto y1 = parent->AbsPixeltoY(_y1);
258 auto x2 = parent->AbsPixeltoX(_x2);
259 auto y2 = parent->AbsPixeltoY(_y2);
260 if (isBox) {
261 if (parent->GetLogx()) {
262 x1 = TMath::Power(10, x1);
263 x2 = TMath::Power(10, x2);
264 }
265 if (parent->GetLogy()) {
266 y1 = TMath::Power(10, y1);
267 y2 = TMath::Power(10, y2);
268 }
269 }
270 if (paint) {
271 pp->DrawBox(x1, y1, x2, y2, TVirtualPadPainter::kHollow);
272 } else {
273 SetX1(x1);
274 SetY1(y1);
275 SetX2(x2);
276 SetY2(y2);
277 }
278 };
279
280 HideToolTip(event);
281
282 switch (event) {
283
284 case kMouseEnter:
285 if (fTip) parent->ResetToolTip(fTip);
286 break;
287
288 case kButton1Double:
289 px1 = -1; //used by kButton1Up
290 break;
291
292 case kArrowKeyPress:
293 case kButton1Down:
294
295 oldX1 = fX1;
296 oldY1 = fY1;
297 oldX2 = fX2;
298 oldY2 = fY2;
299 pp->SetAttLine({GetFillColor() > 0 ? GetFillColor() : (Color_t) 1, GetLineStyle(), 2});
300
301 // No break !!!
302
303 case kMouseMotion:
304
305 px1 = gPad->XtoAbsPixel(GetX1());
306 py1 = gPad->YtoAbsPixel(GetY1());
307 px2 = gPad->XtoAbsPixel(GetX2());
308 py2 = gPad->YtoAbsPixel(GetY2());
309
310 if (isBox) {
311 if (gPad->GetLogx()) {
312 if (GetX1() > 0) px1 = gPad->XtoAbsPixel(TMath::Log10(GetX1()));
313 if (GetX2() > 0) px2 = gPad->XtoAbsPixel(TMath::Log10(GetX2()));
314 }
315 if (gPad->GetLogy()) {
316 if (GetY1() > 0) py1 = gPad->YtoAbsPixel(TMath::Log10(GetY1()));
317 if (GetY2() > 0) py2 = gPad->YtoAbsPixel(TMath::Log10(GetY2()));
318 }
319 }
320
321 if (px1 < px2) {
322 pxl = px1;
323 pxt = px2;
324 } else {
325 pxl = px2;
326 pxt = px1;
327 }
328 if (py1 < py2) {
329 pyl = py1;
330 pyt = py2;
331 } else {
332 pyl = py2;
333 pyt = py1;
334 }
335
336 px1p = parent->XtoAbsPixel(parent->GetX1()) + parent->GetBorderSize();
337 py1p = parent->YtoAbsPixel(parent->GetY1()) - parent->GetBorderSize();
338 px2p = parent->XtoAbsPixel(parent->GetX2()) - parent->GetBorderSize();
339 py2p = parent->YtoAbsPixel(parent->GetY2()) + parent->GetBorderSize();
340
341 if (px1p < px2p) {
342 pxlp = px1p;
343 pxtp = px2p;
344 } else {
345 pxlp = px2p;
346 pxtp = px1p;
347 }
348 if (py1p < py2p) {
349 pylp = py1p;
350 pytp = py2p;
351 } else {
352 pylp = py2p;
353 pytp = py1p;
354 }
355
356 pA = pB = pC = pD = pTop = pL = pR = pBot = pINSIDE = kFALSE;
357
358 // case pA
359 if (TMath::Abs(px - pxl) <= kMaxDiff && TMath::Abs(py - pyl) <= kMaxDiff) {
360 pxold = pxl; pyold = pyl; pA = kTRUE;
361 gPad->SetCursor(kTopLeft);
362 }
363 // case pB
364 if (TMath::Abs(px - pxt) <= kMaxDiff && TMath::Abs(py - pyl) <= kMaxDiff) {
365 pxold = pxt; pyold = pyl; pB = kTRUE;
366 gPad->SetCursor(kTopRight);
367 }
368 // case pC
369 if (TMath::Abs(px - pxt) <= kMaxDiff && TMath::Abs(py - pyt) <= kMaxDiff) {
370 pxold = pxt; pyold = pyt; pC = kTRUE;
371 gPad->SetCursor(kBottomRight);
372 }
373 // case pD
374 if (TMath::Abs(px - pxl) <= kMaxDiff && TMath::Abs(py - pyt) <= kMaxDiff) {
375 pxold = pxl; pyold = pyt; pD = kTRUE;
376 gPad->SetCursor(kBottomLeft);
377 }
378
379 if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
380 TMath::Abs(py - pyl) < kMaxDiff) { // top edge
381 pxold = pxl; pyold = pyl; pTop = kTRUE;
382 gPad->SetCursor(kTopSide);
383 }
384
385 if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
386 TMath::Abs(py - pyt) < kMaxDiff) { // bottom edge
387 pxold = pxt; pyold = pyt; pBot = kTRUE;
388 gPad->SetCursor(kBottomSide);
389 }
390
391 if ((py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
392 TMath::Abs(px - pxl) < kMaxDiff) { // left edge
393 pxold = pxl; pyold = pyl; pL = kTRUE;
394 gPad->SetCursor(kLeftSide);
395 }
396
397 if ((py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
398 TMath::Abs(px - pxt) < kMaxDiff) { // right edge
399 pxold = pxt; pyold = pyt; pR = kTRUE;
400 gPad->SetCursor(kRightSide);
401 }
402
403 if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
404 (py > pyl+kMaxDiff && py < pyt-kMaxDiff)) { // inside box
405 pxold = px; pyold = py; pINSIDE = kTRUE;
406 if (event == kButton1Down)
407 gPad->SetCursor(kMove);
408 else
409 gPad->SetCursor(kCross);
410 }
411
412 fResizing = pA || pB || pC || pD || pTop || pL || pR || pBot;
413
414 if (!fResizing && !pINSIDE)
415 gPad->SetCursor(kCross);
416
417 break;
418
419 case kArrowKeyRelease:
420 case kButton1Motion:
421
422 wx = wy = 0;
423
424 if (pA) {
425 if (!ropaque) action(kTRUE, pxold, pyt, pxt, pyold); // draw the old box
426 if (px > pxt-kMinSize) { px = pxt-kMinSize; wx = px; }
427 if (py > pyt-kMinSize) { py = pyt-kMinSize; wy = py; }
428 if (px < pxlp) { px = pxlp; wx = px; }
429 if (py < pylp) { py = pylp; wy = py; }
430 if (!ropaque) action(kTRUE, px, pyt, pxt, py); // draw the new box
431 }
432 if (pB) {
433 if (!ropaque) action(kTRUE, pxl, pyt, pxold, pyold);
434 if (px < pxl+kMinSize) { px = pxl+kMinSize; wx = px; }
435 if (py > pyt-kMinSize) { py = pyt-kMinSize; wy = py; }
436 if (px > pxtp) { px = pxtp; wx = px; }
437 if (py < pylp) { py = pylp; wy = py; }
438 if (!ropaque) action(kTRUE, pxl, pyt, px, py);
439 }
440 if (pC) {
441 if (!ropaque) action(kTRUE, pxl, pyl, pxold, pyold);
442 if (px < pxl+kMinSize) { px = pxl+kMinSize; wx = px; }
443 if (py < pyl+kMinSize) { py = pyl+kMinSize; wy = py; }
444 if (px > pxtp) { px = pxtp; wx = px; }
445 if (py > pytp) { py = pytp; wy = py; }
446 if (!ropaque) action(kTRUE, pxl, pyl, px, py);
447 }
448 if (pD) {
449 if (!ropaque) action(kTRUE, pxold, pyold, pxt, pyl);
450 if (px > pxt-kMinSize) { px = pxt-kMinSize; wx = px; }
451 if (py < pyl+kMinSize) { py = pyl+kMinSize; wy = py; }
452 if (px < pxlp) { px = pxlp; wx = px; }
453 if (py > pytp) { py = pytp; wy = py; }
454 if (!ropaque) action(kTRUE, px, py, pxt, pyl);
455 }
456 if (pTop) {
457 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
458 py2 += py - pyold;
459 if (py2 > py1-kMinSize) { py2 = py1-kMinSize; wy = py2; }
460 if (py2 < py2p) { py2 = py2p; wy = py2; }
461 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
462 }
463 if (pBot) {
464 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
465 py1 += py - pyold;
466 if (py1 < py2+kMinSize) { py1 = py2+kMinSize; wy = py1; }
467 if (py1 > py1p) { py1 = py1p; wy = py1; }
468 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
469 }
470 if (pL) {
471 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
472 px1 += px - pxold;
473 if (px1 > px2-kMinSize) { px1 = px2-kMinSize; wx = px1; }
474 if (px1 < px1p) { px1 = px1p; wx = px1; }
475 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
476 }
477 if (pR) {
478 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
479 px2 += px - pxold;
480 if (px2 < px1+kMinSize) { px2 = px1+kMinSize; wx = px2; }
481 if (px2 > px2p) { px2 = px2p; wx = px2; }
482 if (!ropaque) action(kTRUE, px1, py1, px2, py2);
483 }
484 if (pINSIDE) {
485 if (!opaque) action(kTRUE, px1, py1, px2, py2); // draw the old box
486 Int_t dx = px - pxold;
487 Int_t dy = py - pyold;
488 px1 += dx; py1 += dy; px2 += dx; py2 += dy;
489 if (px1 < px1p) { dx = px1p - px1; px1 += dx; px2 += dx; wx = px+dx; }
490 if (px2 > px2p) { dx = px2 - px2p; px1 -= dx; px2 -= dx; wx = px-dx; }
491 if (py1 > py1p) { dy = py1 - py1p; py1 -= dy; py2 -= dy; wy = py-dy; }
492 if (py2 < py2p) { dy = py2p - py2; py1 += dy; py2 += dy; wy = py+dy; }
493 if (!opaque) action(kTRUE, px1, py1, px2, py2); // draw the new box
494 }
495
496 if (wx || wy) {
497 if (wx) px = wx;
498 if (wy) py = wy;
499 parent->GetCanvasImp()->Warp(px, py);
500 }
501
502 pxold = px;
503 pyold = py;
504
505 if ((pINSIDE && opaque) || (fResizing && ropaque)) {
506 if (pA)
508 if (pB)
510 if (pC)
512 if (pD)
514 if (pTop || pBot || pL || pR || pINSIDE)
515 action(kFALSE, px1, py1, px2, py2);
516
517 if (pINSIDE) parent->ShowGuidelines(this, event, 'i', true);
518 if (pTop) parent->ShowGuidelines(this, event, 't', true);
519 if (pBot) parent->ShowGuidelines(this, event, 'b', true);
520 if (pL) parent->ShowGuidelines(this, event, 'l', true);
521 if (pR) parent->ShowGuidelines(this, event, 'r', true);
522 if (pA) parent->ShowGuidelines(this, event, '1', true);
523 if (pB) parent->ShowGuidelines(this, event, '2', true);
524 if (pC) parent->ShowGuidelines(this, event, '3', true);
525 if (pD) parent->ShowGuidelines(this, event, '4', true);
526 parent->Modified(kTRUE);
527 }
528
529 break;
530
531 case kButton1Up:
532 if (gROOT->IsEscaped()) {
533 gROOT->SetEscape(kFALSE);
534 if (opaque) {
535 SetX1(oldX1);
536 SetY1(oldY1);
537 SetX2(oldX2);
538 SetY2(oldY2);
539 parent->Modified(kTRUE);
540 parent->Update();
541 }
542 break;
543 }
544
545 if (opaque || ropaque) {
546 parent->ShowGuidelines(this, event);
547 } else {
548 if (px1 < 0)
549 break;
550 if (pA)
552 if (pB)
554 if (pC)
556 if (pD)
558 if (pTop || pBot || pL || pR || pINSIDE)
559 action(kFALSE, px1, py1, px2, py2);
560 if (pINSIDE) {
561 // if it was not a pad that was moved then it must have been
562 // a box or something like that so we have to redraw the pad
563 if (parent == gPad) parent->Modified(kTRUE);
564 }
565 }
566
567 if (pA || pB || pC || pD || pTop || pL || pR || pBot)
568 parent->Modified(kTRUE);
569
570 if (!opaque)
571 pp->SetAttLine({-1, 1, -1});
572
573 break;
574
575 case kButton1Locate:
576 // Sergey: code is never used, has to be removed in ROOT7
577
578 ExecuteEvent(kButton1Down, px, py);
579
580 while (true) {
581 px = py = 0;
582 event = parent->GetCanvasImp()->RequestLocator(px, py);
583
585
586 if (event != -1) { // button is released
587 ExecuteEvent(kButton1Up, px, py);
588 return;
589 }
590 }
591 }
592}
593
594////////////////////////////////////////////////////////////////////////////////
595/// Hide tool tip depending on the event type. Typically tool tips
596/// are hidden when event is not a kMouseEnter and not a kMouseMotion
597/// event.
598
600{
601 if (event != kMouseEnter && event != kMouseMotion && fTip && gPad)
602 gPad->CloseToolTip(fTip);
603}
604
605////////////////////////////////////////////////////////////////////////////////
606/// Function which returns 1 if point x,y lies inside the box, 0 otherwise.
607
609{
610 if (x < fX1 || x > fX2) return 0;
611 if (y < fY1 || y > fY2) return 0;
612 return 1;
613}
614
615////////////////////////////////////////////////////////////////////////////////
616/// List this box with its attributes.
617
618void TBox::ls(Option_t *) const
619{
621 printf("%s X1= %f Y1=%f X2=%f Y2=%f\n",IsA()->GetName(),fX1,fY1,fX2,fY2);
622}
623
624////////////////////////////////////////////////////////////////////////////////
625/// Paint this box with its current attributes.
626
628{
629 if(gPad) PaintBox(gPad->XtoPad(fX1),gPad->YtoPad(fY1),gPad->XtoPad(fX2),gPad->YtoPad(fY2),option);
630}
631
632////////////////////////////////////////////////////////////////////////////////
633/// Draw this box with new coordinates.
634
636{
637 if (!gPad) return;
638
639 TAttLine::Modify(); //Change line attributes only if necessary
640 TAttFill::Modify(); //Change fill area attributes only if necessary
641
642 if (option) {
643 TString opt = option;
644 opt.ToLower();
645 if (opt.Contains("l")) gPad->PaintBox(x1,y1,x2,y2,"l");
646 else gPad->PaintBox(x1,y1,x2,y2);
647 } else {
648 gPad->PaintBox(x1,y1,x2,y2);
649 }
650}
651
652////////////////////////////////////////////////////////////////////////////////
653/// Dump this box with its attributes.
654
656{
657 printf("%s X1=%f Y1=%f X2=%f Y2=%f",IsA()->GetName(),fX1,fY1,fX2,fY2);
658 if (GetLineColor() != 1) printf(" Color=%d",GetLineColor());
659 if (GetLineStyle() != 1) printf(" Style=%d",GetLineStyle());
660 if (GetLineWidth() != 1) printf(" Width=%d",GetLineWidth());
661 if (GetFillColor() != 0) printf(" FillColor=%d",GetFillColor());
662 if (GetFillStyle() != 0) printf(" FillStyle=%d",GetFillStyle());
663 printf("\n");
664}
665
666////////////////////////////////////////////////////////////////////////////////
667/// Save primitive as a C++ statement(s) on output stream out
668
669void TBox::SavePrimitive(std::ostream &out, Option_t *option)
670{
671 SavePrimitiveConstructor(out, Class(), "box", TString::Format("%g, %g, %g, %g", fX1, fY1, fX2, fY2));
672
673 SaveFillAttributes(out, "box", -1, -1);
674 SaveLineAttributes(out, "box", 1, 1, 1);
675
676 SavePrimitiveDraw(out, "box", option);
677}
678
679////////////////////////////////////////////////////////////////////////////////
680/// Set tool tip text associated with this box. The delay is in
681/// milliseconds (minimum 250). To remove tool tip call method with
682/// text = 0.
683
685{
686 if (!gPad) {
687 Warning("SetToolTipText", "a canvas must exist before setting the tool tip text");
688 return;
689 }
690
691 if (fTip) {
692 gPad->DeleteToolTip(fTip);
693 fTip = nullptr;
694 }
695
696 if (text && strlen(text))
697 fTip = gPad->CreateToolTip(this, text, delayms);
698}
699
700////////////////////////////////////////////////////////////////////////////////
701/// Stream an object of class TBox.
702
704{
705 if (R__b.IsReading()) {
707 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
708 if (R__v > 1) {
709 R__b.ReadClassBuffer(TBox::Class(), this, R__v, R__s, R__c);
710 return;
711 }
712 //====process old versions before automatic schema evolution
716 Float_t x1,y1,x2,y2;
717 R__b >> x1; fX1 = x1;
718 R__b >> y1; fY1 = y1;
719 R__b >> x2; fX2 = x2;
720 R__b >> y2; fY2 = y2;
721 R__b.CheckByteCount(R__s, R__c, TBox::IsA());
722 //====end of old versions
723
724 } else {
725 R__b.WriteClassBuffer(TBox::Class(),this);
726 }
727}
728
729////////////////////////////////////////////////////////////////////////////////
730/// Return the "bounding Box" of the Box
731
733{
734 Rectangle_t BBox{0,0,0,0};
735 if (gPad) {
736 Int_t px1 = gPad->XtoPixel(fX1);
737 Int_t px2 = gPad->XtoPixel(fX2);
738 Int_t py1 = gPad->YtoPixel(fY1);
739 Int_t py2 = gPad->YtoPixel(fY2);
740
741 if (px1 > px2) {
742 Int_t tmp = px1;
743 px1 = px2;
744 px2 = tmp;
745 }
746 if (py1 > py2) {
747 Int_t tmp = py1;
748 py1 = py2;
749 py2 = tmp;
750 }
751
752 BBox.fX = px1;
753 BBox.fY = py1;
754 BBox.fWidth = px2 - px1;
755 BBox.fHeight = py2 - py1;
756 }
757
758 return BBox;
759}
760
761////////////////////////////////////////////////////////////////////////////////
762/// Return the center of the Box as TPoint in pixels
763
765{
766 TPoint p(0, 0);
767 if (gPad) {
768 p.SetX(gPad->XtoPixel(TMath::Min(fX1, fX2) + 0.5 * (TMath::Max(fX1, fX2) - TMath::Min(fX1, fX2))));
769 p.SetY(gPad->YtoPixel(TMath::Min(fY1, fY2) + 0.5 * (TMath::Max(fY1, fY2) - TMath::Min(fY1, fY2))));
770 }
771 return p;
772}
773
774////////////////////////////////////////////////////////////////////////////////
775/// Set center of the Box
776
778{
779 if (!gPad) return;
782 if (fX2>fX1) {
783 this->SetX1(gPad->PixeltoX(p.GetX())-0.5*w);
784 this->SetX2(gPad->PixeltoX(p.GetX())+0.5*w);
785 }
786 else {
787 this->SetX2(gPad->PixeltoX(p.GetX())-0.5*w);
788 this->SetX1(gPad->PixeltoX(p.GetX())+0.5*w);
789 }
790 if (fY2>fY1) {
791 this->SetY1(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))-0.5*h);
792 this->SetY2(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))+0.5*h);
793 }
794 else {
795 this->SetY2(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))-0.5*h);
796 this->SetY1(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))+0.5*h);
797 }
798}
799
800////////////////////////////////////////////////////////////////////////////////
801/// Set X coordinate of the center of the Box
802
804{
805 if (!gPad) return;
806 if (x<0) return;
808 if (fX2>fX1) {
809 this->SetX1(gPad->PixeltoX(x)-0.5*w);
810 this->SetX2(gPad->PixeltoX(x)+0.5*w);
811 }
812 else {
813 this->SetX2(gPad->PixeltoX(x)-0.5*w);
814 this->SetX1(gPad->PixeltoX(x)+0.5*w);
815 }
816}
817
818////////////////////////////////////////////////////////////////////////////////
819/// Set Y coordinate of the center of the Box
820
822{
823 if (!gPad) return;
824 if (y<0) return;
826 if (fY2>fY1) {
827 this->SetY1(gPad->PixeltoY(y-gPad->VtoPixel(0))-0.5*h);
828 this->SetY2(gPad->PixeltoY(y-gPad->VtoPixel(0))+0.5*h);
829 }
830 else {
831 this->SetY2(gPad->PixeltoY(y-gPad->VtoPixel(0))-0.5*h);
832 this->SetY1(gPad->PixeltoY(y-gPad->VtoPixel(0))+0.5*h);
833 }
834}
835
836////////////////////////////////////////////////////////////////////////////////
837/// Set left hand side of BoundingBox to a value
838/// (resize in x direction on left)
839
841{
842 if (x<0) return;
843 if (!gPad) return;
844 fX1 = gPad->PixeltoX(x);
845}
846
847////////////////////////////////////////////////////////////////////////////////
848/// Set right hand side of BoundingBox to a value
849/// (resize in x direction on right)
850
852{
853 if (x<0) return;
854 if (!gPad) return;
855 fX2 = gPad->PixeltoX(x);
856}
857
858////////////////////////////////////////////////////////////////////////////////
859/// Set top of BoundingBox to a value (resize in y direction on top)
860
862{
863 if (y<0) return;
864 if (!gPad) return;
865 fY2 = gPad->PixeltoY(y - gPad->VtoPixel(0));
866}
867
868////////////////////////////////////////////////////////////////////////////////
869/// Set bottom of BoundingBox to a value
870/// (resize in y direction on bottom)
871
873{
874 if (y<0) return;
875 if (!gPad) return;
876 fY1 = gPad->PixeltoY(y - gPad->VtoPixel(0));
877}
@ kMouseMotion
Definition Buttons.h:23
@ kArrowKeyRelease
Definition Buttons.h:21
@ kButton1Double
Definition Buttons.h:24
@ 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
@ kMouseEnter
Definition Buttons.h:23
@ kRightSide
Definition GuiTypes.h:374
@ kBottomSide
Definition GuiTypes.h:374
@ kTopLeft
Definition GuiTypes.h:373
@ kBottomRight
Definition GuiTypes.h:373
@ kTopSide
Definition GuiTypes.h:374
@ kLeftSide
Definition GuiTypes.h:374
@ kMove
Definition GuiTypes.h:375
@ kTopRight
Definition GuiTypes.h:373
@ kBottomLeft
Definition GuiTypes.h:373
@ kCross
Definition GuiTypes.h:375
#define b(i)
Definition RSha256.hxx:100
#define h(i)
Definition RSha256.hxx:106
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
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 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 TPoint TPoint const char text
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:414
#define gPad
Abstract base class for elements drawn in the editor.
Definition TAttBBox2D.h:19
Fill Area Attributes class.
Definition TAttFill.h:21
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:206
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: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:243
Line Attributes class.
Definition TAttLine.h:21
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
Width_t fLineWidth
Line width.
Definition TAttLine.h:26
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:37
virtual void Modify()
Change current line attributes if necessary.
Definition TAttLine.cxx:246
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:176
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
Create a Box.
Definition TBox.h:22
void Draw(Option_t *option="") override
Draw this box with its current attributes.
Definition TBox.cxx:196
Double_t GetX1() const
Definition TBox.h:51
virtual void SetToolTipText(const char *text, Long_t delayms=1000)
Set tool tip text associated with this box.
Definition TBox.cxx:684
virtual void SetY2(Double_t y2)
Definition TBox.h:65
virtual void PaintBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Option_t *option="")
Draw this box with new coordinates.
Definition TBox.cxx:635
static TClass * Class()
void Streamer(TBuffer &) override
Stream an object of class TBox.
Definition TBox.cxx:703
void SetBBoxX1(const Int_t x) override
Set left hand side of BoundingBox to a value (resize in x direction on left)
Definition TBox.cxx:840
~TBox() override
Box destructor.
Definition TBox.cxx:69
TBox & operator=(const TBox &)
Assignment operator.
Definition TBox.cxx:93
void SetBBoxY2(const Int_t y) override
Set bottom of BoundingBox to a value (resize in y direction on bottom)
Definition TBox.cxx:872
void SetBBoxY1(const Int_t y) override
Set top of BoundingBox to a value (resize in y direction on top)
Definition TBox.cxx:861
Double_t fX1
X of 1st point.
Definition TBox.h:28
TClass * IsA() const override
Definition TBox.h:77
virtual void HideToolTip(Int_t event)
Hide tool tip depending on the event type.
Definition TBox.cxx:599
void SetBBoxCenterY(const Int_t y) override
Set Y coordinate of the center of the Box.
Definition TBox.cxx:821
Double_t GetX2() const
Definition TBox.h:52
void ls(Option_t *option="") const override
List this box with its attributes.
Definition TBox.cxx:618
Double_t GetY1() const
Definition TBox.h:53
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TBox.cxx:232
virtual void SetX1(Double_t x1)
Definition TBox.h:62
void Paint(Option_t *option="") override
Paint this box with its current attributes.
Definition TBox.cxx:627
Double_t GetY2() const
Definition TBox.h:54
virtual Int_t IsInside(Double_t x, Double_t y) const
Function which returns 1 if point x,y lies inside the box, 0 otherwise.
Definition TBox.cxx:608
TPoint GetBBoxCenter() override
Return the center of the Box as TPoint in pixels.
Definition TBox.cxx:764
virtual void SetX2(Double_t x2)
Definition TBox.h:63
TBox()
Box default constructor.
Definition TBox.cxx:42
virtual TBox * DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this box with new coordinates.
Definition TBox.cxx:205
Rectangle_t GetBBox() override
Return the "bounding Box" of the Box.
Definition TBox.cxx:732
void Print(Option_t *option="") const override
Dump this box with its attributes.
Definition TBox.cxx:655
TObject * fTip
! tool tip associated with box
Definition TBox.h:25
void SetBBoxCenter(const TPoint &p) override
Set center of the Box.
Definition TBox.cxx:777
@ kCannotMove
Definition TBox.h:37
Double_t fY2
Y of 2nd point.
Definition TBox.h:31
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TBox.cxx:669
Double_t fX2
X of 2nd point.
Definition TBox.h:30
Double_t fY1
Y of 1st point.
Definition TBox.h:29
void Copy(TObject &box) const override
Copy a Box.
Definition TBox.cxx:112
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a box.
Definition TBox.cxx:135
Bool_t fResizing
! True if box is being resized
Definition TBox.h:32
void SetBBoxX2(const Int_t x) override
Set right hand side of BoundingBox to a value (resize in x direction on right)
Definition TBox.cxx:851
virtual void SetY1(Double_t y1)
Definition TBox.h:64
void SetBBoxCenterX(const Int_t x) override
Set X coordinate of the center of the Box.
Definition TBox.cxx:803
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Mother of all ROOT objects.
Definition TObject.h:42
TObject & operator=(const TObject &rhs) noexcept
TObject assignment operator.
Definition TObject.h:305
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:459
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:994
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1081
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:201
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:546
virtual void Copy(TObject &object) const
Copy this to obj.
Definition TObject.cxx:156
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:842
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:774
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:71
SCoord_t GetY() const
Definition TPoint.h:47
SCoord_t GetX() const
Definition TPoint.h:46
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:2905
Basic string class.
Definition TString.h:138
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
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
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
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
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:732
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:773
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
Rectangle structure (maps to the X11 XRectangle structure)
Definition GuiTypes.h:362