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 "TVirtualX.h"
20#include "TClass.h"
21#include "TMath.h"
22#include "TPoint.h"
23
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
182 Int_t distance = dxl;
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);
208 TAttLine::Copy(*newbox);
209 TAttFill::Copy(*newbox);
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 TVirtualPad *parent = gPad;
250 Bool_t opaque = gPad->OpaqueMoving();
251 Bool_t ropaque = gPad->OpaqueResizing();
252
253 HideToolTip(event);
254
255 switch (event) {
256
257 case kMouseEnter:
258 if (fTip) gPad->ResetToolTip(fTip);
259 break;
260
261 case kButton1Double:
262 px1 = -1; //used by kButton1Up
263 break;
264
265 case kArrowKeyPress:
266 case kButton1Down:
267
268 oldX1 = fX1;
269 oldY1 = fY1;
270 oldX2 = fX2;
271 oldY2 = fY2;
272 gVirtualX->SetLineColor(-1);
273 TAttLine::Modify(); //Change line attributes only if necessary
274 if (GetFillColor())
275 gVirtualX->SetLineColor(GetFillColor());
276 else
277 gVirtualX->SetLineColor(1);
278 gVirtualX->SetLineWidth(2);
279
280 // No break !!!
281
282 case kMouseMotion:
283
284 px1 = gPad->XtoAbsPixel(GetX1());
285 py1 = gPad->YtoAbsPixel(GetY1());
286 px2 = gPad->XtoAbsPixel(GetX2());
287 py2 = gPad->YtoAbsPixel(GetY2());
288
289 if (isBox) {
290 if (gPad->GetLogx()) {
291 if (fX1>0) px1 = gPad->XtoAbsPixel(TMath::Log10(fX1));
292 if (fX2>0) px2 = gPad->XtoAbsPixel(TMath::Log10(fX2));
293 }
294 if (gPad->GetLogy()) {
295 if (fY1>0) py1 = gPad->YtoAbsPixel(TMath::Log10(fY1));
296 if (fY2>0) py2 = gPad->YtoAbsPixel(TMath::Log10(fY2));
297 }
298 }
299
300 if (px1 < px2) {
301 pxl = px1;
302 pxt = px2;
303 } else {
304 pxl = px2;
305 pxt = px1;
306 }
307 if (py1 < py2) {
308 pyl = py1;
309 pyt = py2;
310 } else {
311 pyl = py2;
312 pyt = py1;
313 }
314
315 px1p = parent->XtoAbsPixel(parent->GetX1()) + parent->GetBorderSize();
316 py1p = parent->YtoAbsPixel(parent->GetY1()) - parent->GetBorderSize();
317 px2p = parent->XtoAbsPixel(parent->GetX2()) - parent->GetBorderSize();
318 py2p = parent->YtoAbsPixel(parent->GetY2()) + parent->GetBorderSize();
319
320 if (px1p < px2p) {
321 pxlp = px1p;
322 pxtp = px2p;
323 } else {
324 pxlp = px2p;
325 pxtp = px1p;
326 }
327 if (py1p < py2p) {
328 pylp = py1p;
329 pytp = py2p;
330 } else {
331 pylp = py2p;
332 pytp = py1p;
333 }
334
335 pA = pB = pC = pD = pTop = pL = pR = pBot = pINSIDE = kFALSE;
336
337 // case pA
338 if (TMath::Abs(px - pxl) <= kMaxDiff && TMath::Abs(py - pyl) <= kMaxDiff) {
339 pxold = pxl; pyold = pyl; pA = kTRUE;
340 gPad->SetCursor(kTopLeft);
341 }
342 // case pB
343 if (TMath::Abs(px - pxt) <= kMaxDiff && TMath::Abs(py - pyl) <= kMaxDiff) {
344 pxold = pxt; pyold = pyl; pB = kTRUE;
345 gPad->SetCursor(kTopRight);
346 }
347 // case pC
348 if (TMath::Abs(px - pxt) <= kMaxDiff && TMath::Abs(py - pyt) <= kMaxDiff) {
349 pxold = pxt; pyold = pyt; pC = kTRUE;
350 gPad->SetCursor(kBottomRight);
351 }
352 // case pD
353 if (TMath::Abs(px - pxl) <= kMaxDiff && TMath::Abs(py - pyt) <= kMaxDiff) {
354 pxold = pxl; pyold = pyt; pD = kTRUE;
355 gPad->SetCursor(kBottomLeft);
356 }
357
358 if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
359 TMath::Abs(py - pyl) < kMaxDiff) { // top edge
360 pxold = pxl; pyold = pyl; pTop = kTRUE;
361 gPad->SetCursor(kTopSide);
362 }
363
364 if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
365 TMath::Abs(py - pyt) < kMaxDiff) { // bottom edge
366 pxold = pxt; pyold = pyt; pBot = kTRUE;
367 gPad->SetCursor(kBottomSide);
368 }
369
370 if ((py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
371 TMath::Abs(px - pxl) < kMaxDiff) { // left edge
372 pxold = pxl; pyold = pyl; pL = kTRUE;
373 gPad->SetCursor(kLeftSide);
374 }
375
376 if ((py > pyl+kMaxDiff && py < pyt-kMaxDiff) &&
377 TMath::Abs(px - pxt) < kMaxDiff) { // right edge
378 pxold = pxt; pyold = pyt; pR = kTRUE;
379 gPad->SetCursor(kRightSide);
380 }
381
382 if ((px > pxl+kMaxDiff && px < pxt-kMaxDiff) &&
383 (py > pyl+kMaxDiff && py < pyt-kMaxDiff)) { // inside box
384 pxold = px; pyold = py; pINSIDE = kTRUE;
385 if (event == kButton1Down)
386 gPad->SetCursor(kMove);
387 else
388 gPad->SetCursor(kCross);
389 }
390
392 if (pA || pB || pC || pD || pTop || pL || pR || pBot)
394
395 if (!pA && !pB && !pC && !pD && !pTop && !pL && !pR && !pBot && !pINSIDE)
396 gPad->SetCursor(kCross);
397
398 break;
399
400 case kArrowKeyRelease:
401 case kButton1Motion:
402
403 wx = wy = 0;
404
405 if (pA) {
406 if (!ropaque) gVirtualX->DrawBox(pxold, pyt, pxt, pyold, TVirtualX::kHollow); // draw the old box
407 if (px > pxt-kMinSize) { px = pxt-kMinSize; wx = px; }
408 if (py > pyt-kMinSize) { py = pyt-kMinSize; wy = py; }
409 if (px < pxlp) { px = pxlp; wx = px; }
410 if (py < pylp) { py = pylp; wy = py; }
411 if (!ropaque) gVirtualX->DrawBox(px , pyt, pxt, py, TVirtualX::kHollow); // draw the new box
412 }
413 if (pB) {
414 if (!ropaque) gVirtualX->DrawBox(pxl , pyt, pxold, pyold, TVirtualX::kHollow);
415 if (px < pxl+kMinSize) { px = pxl+kMinSize; wx = px; }
416 if (py > pyt-kMinSize) { py = pyt-kMinSize; wy = py; }
417 if (px > pxtp) { px = pxtp; wx = px; }
418 if (py < pylp) { py = pylp; wy = py; }
419 if (!ropaque) gVirtualX->DrawBox(pxl , pyt, px , py, TVirtualX::kHollow);
420 }
421 if (pC) {
422 if (!ropaque) gVirtualX->DrawBox(pxl , pyl, pxold, pyold, TVirtualX::kHollow);
423 if (px < pxl+kMinSize) { px = pxl+kMinSize; wx = px; }
424 if (py < pyl+kMinSize) { py = pyl+kMinSize; wy = py; }
425 if (px > pxtp) { px = pxtp; wx = px; }
426 if (py > pytp) { py = pytp; wy = py; }
427 if (!ropaque) gVirtualX->DrawBox(pxl , pyl, px , py, TVirtualX::kHollow);
428 }
429 if (pD) {
430 if (!ropaque) gVirtualX->DrawBox(pxold, pyold, pxt, pyl, TVirtualX::kHollow);
431 if (px > pxt-kMinSize) { px = pxt-kMinSize; wx = px; }
432 if (py < pyl+kMinSize) { py = pyl+kMinSize; wy = py; }
433 if (px < pxlp) { px = pxlp; wx = px; }
434 if (py > pytp) { py = pytp; wy = py; }
435 if (!ropaque) gVirtualX->DrawBox(px , py , pxt, pyl, TVirtualX::kHollow);
436 }
437 if (pTop) {
438 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
439 py2 += py - pyold;
440 if (py2 > py1-kMinSize) { py2 = py1-kMinSize; wy = py2; }
441 if (py2 < py2p) { py2 = py2p; wy = py2; }
442 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
443 }
444 if (pBot) {
445 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
446 py1 += py - pyold;
447 if (py1 < py2+kMinSize) { py1 = py2+kMinSize; wy = py1; }
448 if (py1 > py1p) { py1 = py1p; wy = py1; }
449 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
450 }
451 if (pL) {
452 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
453 px1 += px - pxold;
454 if (px1 > px2-kMinSize) { px1 = px2-kMinSize; wx = px1; }
455 if (px1 < px1p) { px1 = px1p; wx = px1; }
456 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
457 }
458 if (pR) {
459 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
460 px2 += px - pxold;
461 if (px2 < px1+kMinSize) { px2 = px1+kMinSize; wx = px2; }
462 if (px2 > px2p) { px2 = px2p; wx = px2; }
463 if (!ropaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow);
464 }
465 if (pINSIDE) {
466 if (!opaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); // draw the old box
467 Int_t dx = px - pxold;
468 Int_t dy = py - pyold;
469 px1 += dx; py1 += dy; px2 += dx; py2 += dy;
470 if (px1 < px1p) { dx = px1p - px1; px1 += dx; px2 += dx; wx = px+dx; }
471 if (px2 > px2p) { dx = px2 - px2p; px1 -= dx; px2 -= dx; wx = px-dx; }
472 if (py1 > py1p) { dy = py1 - py1p; py1 -= dy; py2 -= dy; wy = py-dy; }
473 if (py2 < py2p) { dy = py2p - py2; py1 += dy; py2 += dy; wy = py+dy; }
474 if (!opaque) gVirtualX->DrawBox(px1, py1, px2, py2, TVirtualX::kHollow); // draw the new box
475 }
476
477 if (wx || wy) {
478 if (wx) px = wx;
479 if (wy) py = wy;
480 gVirtualX->Warp(px, py);
481 }
482
483 pxold = px;
484 pyold = py;
485
486
487 if ((pINSIDE && opaque) || (fResizing && ropaque)) {
488 if (pA) {
489 fX1 = gPad->AbsPixeltoX(pxold);
490 fY1 = gPad->AbsPixeltoY(pyt);
491 fX2 = gPad->AbsPixeltoX(pxt);
492 fY2 = gPad->AbsPixeltoY(pyold);
493 }
494 if (pB) {
495 fX1 = gPad->AbsPixeltoX(pxl);
496 fY1 = gPad->AbsPixeltoY(pyt);
497 fX2 = gPad->AbsPixeltoX(pxold);
498 fY2 = gPad->AbsPixeltoY(pyold);
499 }
500 if (pC) {
501 fX1 = gPad->AbsPixeltoX(pxl);
502 fY1 = gPad->AbsPixeltoY(pyold);
503 fX2 = gPad->AbsPixeltoX(pxold);
504 fY2 = gPad->AbsPixeltoY(pyl);
505 }
506 if (pD) {
507 fX1 = gPad->AbsPixeltoX(pxold);
508 fY1 = gPad->AbsPixeltoY(pyold);
509 fX2 = gPad->AbsPixeltoX(pxt);
510 fY2 = gPad->AbsPixeltoY(pyl);
511 }
512 if (pTop || pBot || pL || pR || pINSIDE) {
513 fX1 = gPad->AbsPixeltoX(px1);
514 fY1 = gPad->AbsPixeltoY(py1);
515 fX2 = gPad->AbsPixeltoX(px2);
516 fY2 = gPad->AbsPixeltoY(py2);
517 }
518
519 if (isBox) {
520 if (gPad->GetLogx()) {
521 fX1 = TMath::Power(10,fX1);
522 fX2 = TMath::Power(10,fX2);
523 }
524 if (gPad->GetLogy()) {
525 fY1 = TMath::Power(10,fY1);
526 fY2 = TMath::Power(10,fY2);
527 }
528 }
529
530 if (pINSIDE) gPad->ShowGuidelines(this, event, 'i', true);
531 if (pTop) gPad->ShowGuidelines(this, event, 't', true);
532 if (pBot) gPad->ShowGuidelines(this, event, 'b', true);
533 if (pL) gPad->ShowGuidelines(this, event, 'l', true);
534 if (pR) gPad->ShowGuidelines(this, event, 'r', true);
535 if (pA) gPad->ShowGuidelines(this, event, '1', true);
536 if (pB) gPad->ShowGuidelines(this, event, '2', true);
537 if (pC) gPad->ShowGuidelines(this, event, '3', true);
538 if (pD) gPad->ShowGuidelines(this, event, '4', true);
539 gPad->Modified(kTRUE);
540 }
541
542 break;
543
544 case kButton1Up:
545 if (gROOT->IsEscaped()) {
546 gROOT->SetEscape(kFALSE);
547 if (opaque) {
548 this->SetX1(oldX1);
549 this->SetY1(oldY1);
550 this->SetX2(oldX2);
551 this->SetY2(oldY2);
552 gPad->Modified(kTRUE);
553 gPad->Update();
554 }
555 break;
556 }
557
558 if (opaque || ropaque) {
559 gPad->ShowGuidelines(this, event);
560 } else {
561 if (px1 < 0 ) break;
562 if (pA) {
563 fX1 = gPad->AbsPixeltoX(pxold);
564 fY1 = gPad->AbsPixeltoY(pyt);
565 fX2 = gPad->AbsPixeltoX(pxt);
566 fY2 = gPad->AbsPixeltoY(pyold);
567 }
568 if (pB) {
569 fX1 = gPad->AbsPixeltoX(pxl);
570 fY1 = gPad->AbsPixeltoY(pyt);
571 fX2 = gPad->AbsPixeltoX(pxold);
572 fY2 = gPad->AbsPixeltoY(pyold);
573 }
574 if (pC) {
575 fX1 = gPad->AbsPixeltoX(pxl);
576 fY1 = gPad->AbsPixeltoY(pyold);
577 fX2 = gPad->AbsPixeltoX(pxold);
578 fY2 = gPad->AbsPixeltoY(pyl);
579 }
580 if (pD) {
581 fX1 = gPad->AbsPixeltoX(pxold);
582 fY1 = gPad->AbsPixeltoY(pyold);
583 fX2 = gPad->AbsPixeltoX(pxt);
584 fY2 = gPad->AbsPixeltoY(pyl);
585 }
586 if (pTop || pBot || pL || pR || pINSIDE) {
587 fX1 = gPad->AbsPixeltoX(px1);
588 fY1 = gPad->AbsPixeltoY(py1);
589 fX2 = gPad->AbsPixeltoX(px2);
590 fY2 = gPad->AbsPixeltoY(py2);
591 }
592
593 if (isBox) {
594 if (gPad->GetLogx()) {
595 fX1 = TMath::Power(10,fX1);
596 fX2 = TMath::Power(10,fX2);
597 }
598 if (gPad->GetLogy()) {
599 fY1 = TMath::Power(10,fY1);
600 fY2 = TMath::Power(10,fY2);
601 }
602 }
603 if (pINSIDE) {
604 // if it was not a pad that was moved then it must have been
605 // a box or something like that so we have to redraw the pad
606 if (parent == gPad) gPad->Modified(kTRUE);
607 }
608 }
609
610 if (pA || pB || pC || pD || pTop || pL || pR || pBot) gPad->Modified(kTRUE);
611
612 if (!opaque) {
613 gVirtualX->SetLineColor(-1);
614 gVirtualX->SetLineWidth(-1);
615 }
616
617 break;
618
619 case kButton1Locate:
620
621 ExecuteEvent(kButton1Down, px, py);
622
623 while (true) {
624 px = py = 0;
625 event = gVirtualX->RequestLocator(1, 1, px, py);
626
628
629 if (event != -1) { // button is released
630 ExecuteEvent(kButton1Up, px, py);
631 return;
632 }
633 }
634 }
635}
636
637////////////////////////////////////////////////////////////////////////////////
638/// Hide tool tip depending on the event type. Typically tool tips
639/// are hidden when event is not a kMouseEnter and not a kMouseMotion
640/// event.
641
643{
644 if (event != kMouseEnter && event != kMouseMotion && fTip && gPad)
645 gPad->CloseToolTip(fTip);
646}
647
648////////////////////////////////////////////////////////////////////////////////
649/// Function which returns 1 if point x,y lies inside the box, 0 otherwise.
650
652{
653 if (x < fX1 || x > fX2) return 0;
654 if (y < fY1 || y > fY2) return 0;
655 return 1;
656}
657
658////////////////////////////////////////////////////////////////////////////////
659/// List this box with its attributes.
660
661void TBox::ls(Option_t *) const
662{
664 printf("%s X1= %f Y1=%f X2=%f Y2=%f\n",IsA()->GetName(),fX1,fY1,fX2,fY2);
665}
666
667////////////////////////////////////////////////////////////////////////////////
668/// Paint this box with its current attributes.
669
671{
672 if(gPad) PaintBox(gPad->XtoPad(fX1),gPad->YtoPad(fY1),gPad->XtoPad(fX2),gPad->YtoPad(fY2),option);
673}
674
675////////////////////////////////////////////////////////////////////////////////
676/// Draw this box with new coordinates.
677
679{
680 if (!gPad) return;
681
682 TAttLine::Modify(); //Change line attributes only if necessary
683 TAttFill::Modify(); //Change fill area attributes only if necessary
684
685 if (option) {
686 TString opt = option;
687 opt.ToLower();
688 if (opt.Contains("l")) gPad->PaintBox(x1,y1,x2,y2,"l");
689 else gPad->PaintBox(x1,y1,x2,y2);
690 } else {
691 gPad->PaintBox(x1,y1,x2,y2);
692 }
693}
694
695////////////////////////////////////////////////////////////////////////////////
696/// Dump this box with its attributes.
697
699{
700 printf("%s X1=%f Y1=%f X2=%f Y2=%f",IsA()->GetName(),fX1,fY1,fX2,fY2);
701 if (GetLineColor() != 1) printf(" Color=%d",GetLineColor());
702 if (GetLineStyle() != 1) printf(" Style=%d",GetLineStyle());
703 if (GetLineWidth() != 1) printf(" Width=%d",GetLineWidth());
704 if (GetFillColor() != 0) printf(" FillColor=%d",GetFillColor());
705 if (GetFillStyle() != 0) printf(" FillStyle=%d",GetFillStyle());
706 printf("\n");
707}
708
709////////////////////////////////////////////////////////////////////////////////
710/// Save primitive as a C++ statement(s) on output stream out
711
712void TBox::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
713{
714 if (gROOT->ClassSaved(TBox::Class())) {
715 out<<" ";
716 } else {
717 out<<" TBox *";
718 }
719 out<<"box = new TBox("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2<<");"<<std::endl;
720
721 SaveFillAttributes(out,"box",0,1001);
722 SaveLineAttributes(out,"box",1,1,1);
723
724 out<<" box->Draw();"<<std::endl;
725}
726
727////////////////////////////////////////////////////////////////////////////////
728/// Set tool tip text associated with this box. The delay is in
729/// milliseconds (minimum 250). To remove tool tip call method with
730/// text = 0.
731
732void TBox::SetToolTipText(const char *text, Long_t delayms)
733{
734 if (!gPad) {
735 Warning("SetToolTipText", "a canvas must exist before setting the tool tip text");
736 return;
737 }
738
739 if (fTip) {
740 gPad->DeleteToolTip(fTip);
741 fTip = nullptr;
742 }
743
744 if (text && strlen(text))
745 fTip = gPad->CreateToolTip(this, text, delayms);
746}
747
748////////////////////////////////////////////////////////////////////////////////
749/// Stream an object of class TBox.
750
752{
753 if (R__b.IsReading()) {
754 UInt_t R__s, R__c;
755 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
756 if (R__v > 1) {
757 R__b.ReadClassBuffer(TBox::Class(), this, R__v, R__s, R__c);
758 return;
759 }
760 //====process old versions before automatic schema evolution
761 TObject::Streamer(R__b);
762 TAttLine::Streamer(R__b);
763 TAttFill::Streamer(R__b);
764 Float_t x1,y1,x2,y2;
765 R__b >> x1; fX1 = x1;
766 R__b >> y1; fY1 = y1;
767 R__b >> x2; fX2 = x2;
768 R__b >> y2; fY2 = y2;
769 R__b.CheckByteCount(R__s, R__c, TBox::IsA());
770 //====end of old versions
771
772 } else {
773 R__b.WriteClassBuffer(TBox::Class(),this);
774 }
775}
776
777////////////////////////////////////////////////////////////////////////////////
778/// Return the "bounding Box" of the Box
779
781{
782 Rectangle_t BBox{0,0,0,0};
783 if (gPad) {
784 Int_t px1 = gPad->XtoPixel(fX1);
785 Int_t px2 = gPad->XtoPixel(fX2);
786 Int_t py1 = gPad->YtoPixel(fY1);
787 Int_t py2 = gPad->YtoPixel(fY2);
788
789 if (px1 > px2) {
790 Int_t tmp = px1;
791 px1 = px2;
792 px2 = tmp;
793 }
794 if (py1 > py2) {
795 Int_t tmp = py1;
796 py1 = py2;
797 py2 = tmp;
798 }
799
800 BBox.fX = px1;
801 BBox.fY = py1;
802 BBox.fWidth = px2 - px1;
803 BBox.fHeight = py2 - py1;
804 }
805
806 return BBox;
807}
808
809////////////////////////////////////////////////////////////////////////////////
810/// Return the center of the Box as TPoint in pixels
811
813{
814 TPoint p(0, 0);
815 if (gPad) {
816 p.SetX(gPad->XtoPixel(TMath::Min(fX1, fX2) + 0.5 * (TMath::Max(fX1, fX2) - TMath::Min(fX1, fX2))));
817 p.SetY(gPad->YtoPixel(TMath::Min(fY1, fY2) + 0.5 * (TMath::Max(fY1, fY2) - TMath::Min(fY1, fY2))));
818 }
819 return p;
820}
821
822////////////////////////////////////////////////////////////////////////////////
823/// Set center of the Box
824
826{
827 if (!gPad) return;
830 if (fX2>fX1) {
831 this->SetX1(gPad->PixeltoX(p.GetX())-0.5*w);
832 this->SetX2(gPad->PixeltoX(p.GetX())+0.5*w);
833 }
834 else {
835 this->SetX2(gPad->PixeltoX(p.GetX())-0.5*w);
836 this->SetX1(gPad->PixeltoX(p.GetX())+0.5*w);
837 }
838 if (fY2>fY1) {
839 this->SetY1(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))-0.5*h);
840 this->SetY2(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))+0.5*h);
841 }
842 else {
843 this->SetY2(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))-0.5*h);
844 this->SetY1(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))+0.5*h);
845 }
846}
847
848////////////////////////////////////////////////////////////////////////////////
849/// Set X coordinate of the center of the Box
850
852{
853 if (!gPad) return;
854 if (x<0) return;
856 if (fX2>fX1) {
857 this->SetX1(gPad->PixeltoX(x)-0.5*w);
858 this->SetX2(gPad->PixeltoX(x)+0.5*w);
859 }
860 else {
861 this->SetX2(gPad->PixeltoX(x)-0.5*w);
862 this->SetX1(gPad->PixeltoX(x)+0.5*w);
863 }
864}
865
866////////////////////////////////////////////////////////////////////////////////
867/// Set Y coordinate of the center of the Box
868
870{
871 if (!gPad) return;
872 if (y<0) return;
874 if (fY2>fY1) {
875 this->SetY1(gPad->PixeltoY(y-gPad->VtoPixel(0))-0.5*h);
876 this->SetY2(gPad->PixeltoY(y-gPad->VtoPixel(0))+0.5*h);
877 }
878 else {
879 this->SetY2(gPad->PixeltoY(y-gPad->VtoPixel(0))-0.5*h);
880 this->SetY1(gPad->PixeltoY(y-gPad->VtoPixel(0))+0.5*h);
881 }
882}
883
884////////////////////////////////////////////////////////////////////////////////
885/// Set left hand side of BoundingBox to a value
886/// (resize in x direction on left)
887
889{
890 if (x<0) return;
891 if (!gPad) return;
892 fX1 = gPad->PixeltoX(x);
893}
894
895////////////////////////////////////////////////////////////////////////////////
896/// Set right hand side of BoundingBox to a value
897/// (resize in x direction on right)
898
900{
901 if (x<0) return;
902 if (!gPad) return;
903 fX2 = gPad->PixeltoX(x);
904}
905
906////////////////////////////////////////////////////////////////////////////////
907/// Set top of BoundingBox to a value (resize in y direction on top)
908
910{
911 if (y<0) return;
912 if (!gPad) return;
913 fY2 = gPad->PixeltoY(y - gPad->VtoPixel(0));
914}
915
916////////////////////////////////////////////////////////////////////////////////
917/// Set bottom of BoundingBox to a value
918/// (resize in y direction on bottom)
919
921{
922 if (y<0) return;
923 if (!gPad) return;
924 fY1 = gPad->PixeltoY(y - gPad->VtoPixel(0));
925}
@ 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:373
@ kBottomSide
Definition GuiTypes.h:373
@ kTopLeft
Definition GuiTypes.h:372
@ kBottomRight
Definition GuiTypes.h:372
@ kTopSide
Definition GuiTypes.h:373
@ kLeftSide
Definition GuiTypes.h:373
@ kMove
Definition GuiTypes.h:374
@ kTopRight
Definition GuiTypes.h:372
@ kBottomLeft
Definition GuiTypes.h:372
@ kCross
Definition GuiTypes.h:374
#define b(i)
Definition RSha256.hxx:100
#define h(i)
Definition RSha256.hxx:106
int Int_t
Definition RtypesCore.h:45
short Version_t
Definition RtypesCore.h:65
long Long_t
Definition RtypesCore.h:54
float Float_t
Definition RtypesCore.h:57
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 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:406
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
Abstract base class for elements drawn in the editor.
Definition TAttBBox2D.h:19
Fill Area Attributes class.
Definition TAttFill.h:19
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:207
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
Line Attributes class.
Definition TAttLine.h:18
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:35
Width_t fLineWidth
Line width.
Definition TAttLine.h:23
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:34
virtual void Modify()
Change current line attributes if necessary.
Definition TAttLine.cxx:247
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:177
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
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:732
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:678
static TClass * Class()
void Streamer(TBuffer &) override
Stream an object of class TBox.
Definition TBox.cxx:751
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:888
~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:920
void SetBBoxY1(const Int_t y) override
Set top of BoundingBox to a value (resize in y direction on top)
Definition TBox.cxx:909
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:642
void SetBBoxCenterY(const Int_t y) override
Set Y coordinate of the center of the Box.
Definition TBox.cxx:869
Double_t GetX2() const
Definition TBox.h:52
void ls(Option_t *option="") const override
List this box with its attributes.
Definition TBox.cxx:661
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:670
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:651
TPoint GetBBoxCenter() override
Return the center of the Box as TPoint in pixels.
Definition TBox.cxx:812
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:780
void Print(Option_t *option="") const override
Dump this box with its attributes.
Definition TBox.cxx:698
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:825
@ 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:712
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:899
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:851
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
Definition TBuffer.h:86
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:456
TObject & operator=(const TObject &rhs)
TObject assignment operator.
Definition TObject.h:296
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:906
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:991
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:202
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:798
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:542
virtual void Copy(TObject &object) const
Copy this to obj.
Definition TObject.cxx:158
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
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:2895
Basic string class.
Definition TString.h:139
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
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 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:250
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:725
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:766
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Rectangle structure (maps to the X11 XRectangle structure)
Definition GuiTypes.h:361