Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TMarker.cxx
Go to the documentation of this file.
1 // @(#)root/graf:$Id$
2 // Author: Rene Brun 12/05/95
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 <stdlib.h>
13 
14 #include "Riostream.h"
15 #include "TROOT.h"
16 #include "TVirtualPad.h"
17 #include "TMarker.h"
18 #include "TVirtualX.h"
19 #include "TMath.h"
20 #include "TPoint.h"
21 #include "TText.h"
22 #include "TClass.h"
23 #include "TPoint.h"
24 
25 ClassImp(TMarker);
26 
27 
28 /** \class TMarker
29 \ingroup BasicGraphics
30 
31 Manages Markers. Marker attributes are managed by TAttMarker.
32 */
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 /// Marker default constructor.
36 
37 TMarker::TMarker(): TObject(), TAttMarker()
38 {
39  fX = 0;
40  fY = 0;
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Marker normal constructor.
45 
46 TMarker::TMarker(Double_t x, Double_t y, Int_t marker)
47  :TObject(), TAttMarker()
48 {
49  fX = x;
50  fY = y;
51  fMarkerStyle = marker;
52 }
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// Marker default destructor.
56 
57 TMarker::~TMarker()
58 {
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// Marker copy constructor.
63 
64 TMarker::TMarker(const TMarker &marker) : TObject(marker), TAttMarker(marker), TAttBBox2D(marker)
65 {
66  fX = 0;
67  fY = 0;
68  ((TMarker&)marker).Copy(*this);
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Copy this marker to marker.
73 
74 void TMarker::Copy(TObject &obj) const
75 {
76  TObject::Copy(obj);
77  TAttMarker::Copy(((TMarker&)obj));
78  ((TMarker&)obj).fX = fX;
79  ((TMarker&)obj).fY = fY;
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Display the table of markers with their numbers.
84 
85 void TMarker::DisplayMarkerTypes()
86 {
87  TMarker *marker = new TMarker();
88  marker->SetMarkerSize(3);
89  TText *text = new TText();
90  text->SetTextFont(62);
91  text->SetTextAlign(22);
92  text->SetTextSize(0.1);
93  char atext[] = " ";
94  Double_t x = 0;
95  Double_t dx = 1/16.0;
96  for (Int_t i=1;i<16;i++) {
97  x += dx;
98  snprintf(atext,7,"%d",i);
99  marker->SetMarkerStyle(i);
100  marker->DrawMarker(x,.25);
101  text->DrawText(x,.12,atext);
102  snprintf(atext,7,"%d",i+19);
103  marker->SetMarkerStyle(i+19);
104  marker->DrawMarker(x,.55);
105  text->DrawText(x,.42,atext);
106  snprintf(atext,7,"%d",i+34);
107  marker->SetMarkerStyle(i+34);
108  marker->DrawMarker(x,.85);
109  text->DrawText(x,.72,atext);
110  }
111  delete marker;
112  delete text;
113 }
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 /// Compute distance from point px,py to a marker.
117 ///
118 /// Compute the closest distance of approach from point px,py to this marker.
119 /// The distance is computed in pixels units.
120 
121 Int_t TMarker::DistancetoPrimitive(Int_t px, Int_t py)
122 {
123  Int_t pxm, pym;
124  if (TestBit(kMarkerNDC)) {
125  pxm = gPad->UtoPixel(fX);
126  pym = gPad->VtoPixel(fY);
127  } else {
128  pxm = gPad->XtoAbsPixel(gPad->XtoPad(fX));
129  pym = gPad->YtoAbsPixel(gPad->YtoPad(fY));
130  }
131  Int_t dist = (Int_t)TMath::Sqrt((px-pxm)*(px-pxm) + (py-pym)*(py-pym));
132 
133  //marker size = 1 is about 8 pixels
134  Int_t markerRadius = Int_t(4*fMarkerSize);
135  if (dist <= markerRadius) return 0;
136  if (dist > markerRadius+3) return 999;
137  return dist;
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Draw this marker with its current attributes.
142 
143 void TMarker::Draw(Option_t *option)
144 {
145  AppendPad(option);
146 
147 }
148 
149 ////////////////////////////////////////////////////////////////////////////////
150 /// Draw this marker with new coordinates.
151 
152 void TMarker::DrawMarker(Double_t x, Double_t y)
153 {
154  TMarker *newmarker = new TMarker(x, y, 1);
155  TAttMarker::Copy(*newmarker);
156  newmarker->SetBit(kCanDelete);
157  newmarker->AppendPad();
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// Execute action corresponding to one event.
162 ///
163 /// This member function is called when a marker is clicked with the locator
164 ///
165 /// If Left button is clicked on a marker, the marker is moved to
166 /// a new position when the mouse button is released.
167 
168 void TMarker::ExecuteEvent(Int_t event, Int_t px, Int_t py)
169 {
170  if (!gPad) return;
171 
172  TPoint p;
173  static Int_t pxold, pyold;
174  static Bool_t ndcsav;
175  Double_t dpx, dpy, xp1,yp1;
176  Bool_t opaque = gPad->OpaqueMoving();
177 
178  if (!gPad->IsEditable()) return;
179 
180  switch (event) {
181 
182  case kButton1Down:
183  ndcsav = TestBit(kMarkerNDC);
184  if (!opaque) {
185  gVirtualX->SetTextColor(-1); // invalidate current text color (use xor mode)
186  TAttMarker::Modify(); //Change marker attributes only if necessary
187  }
188  // No break !!!
189 
190  case kMouseMotion:
191  pxold = px; pyold = py;
192  gPad->SetCursor(kMove);
193  break;
194 
195  case kButton1Motion:
196  p.fX = pxold; p.fY = pyold;
197  if (!opaque) gVirtualX->DrawPolyMarker(1, &p);
198  p.fX = px; p.fY = py;
199  if (!opaque) gVirtualX->DrawPolyMarker(1, &p);
200  pxold = px; pyold = py;
201  if (opaque) {
202  if (ndcsav) this->SetNDC(kFALSE);
203  this->SetX(gPad->PadtoX(gPad->AbsPixeltoX(px)));
204  this->SetY(gPad->PadtoY(gPad->AbsPixeltoY(py)));
205  gPad->ShowGuidelines(this, event, 'i', true);
206  gPad->Modified(kTRUE);
207  gPad->Update();
208  }
209  break;
210 
211  case kButton1Up:
212  if (opaque) {
213  if (ndcsav && !this->TestBit(kMarkerNDC)) {
214  this->SetX((fX - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1()));
215  this->SetY((fY - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1()));
216  this->SetNDC();
217  }
218  gPad->ShowGuidelines(this, event);
219  } else {
220  if (TestBit(kMarkerNDC)) {
221  dpx = gPad->GetX2() - gPad->GetX1();
222  dpy = gPad->GetY2() - gPad->GetY1();
223  xp1 = gPad->GetX1();
224  yp1 = gPad->GetY1();
225  fX = (gPad->AbsPixeltoX(pxold)-xp1)/dpx;
226  fY = (gPad->AbsPixeltoY(pyold)-yp1)/dpy;
227  } else {
228  fX = gPad->PadtoX(gPad->AbsPixeltoX(px));
229  fY = gPad->PadtoY(gPad->AbsPixeltoY(py));
230  }
231  gPad->Modified(kTRUE);
232  gPad->Update();
233  gVirtualX->SetTextColor(-1);
234  }
235  break;
236  }
237 }
238 
239 ////////////////////////////////////////////////////////////////////////////////
240 /// List this marker with its attributes.
241 
242 void TMarker::ls(Option_t *) const
243 {
244  TROOT::IndentLevel();
245  printf("Marker X=%f Y=%f marker type=%d\n",fX,fY,fMarkerStyle);
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Paint this marker with its current attributes.
250 
251 void TMarker::Paint(Option_t *)
252 {
253  if (TestBit(kMarkerNDC)) {
254  Double_t u = gPad->GetX1() + fX*(gPad->GetX2()-gPad->GetX1());
255  Double_t v = gPad->GetY1() + fY*(gPad->GetY2()-gPad->GetY1());
256  PaintMarker(u,v);
257  } else {
258  PaintMarker(gPad->XtoPad(fX),gPad->YtoPad(fY));
259  }
260 }
261 
262 ////////////////////////////////////////////////////////////////////////////////
263 /// Draw this marker with new coordinates.
264 
265 void TMarker::PaintMarker(Double_t x, Double_t y)
266 {
267  TAttMarker::Modify(); //Change line attributes only if necessary
268  gPad->PaintPolyMarker(-1,&x,&y,"");
269 }
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 /// Draw this marker with new coordinates in NDC.
273 
274 void TMarker::PaintMarkerNDC(Double_t, Double_t)
275 {
276 }
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 /// Dump this marker with its attributes.
280 
281 void TMarker::Print(Option_t *) const
282 {
283  printf("Marker X=%f Y=%f",fX,fY);
284  if (GetMarkerColor() != 1) printf(" Color=%d",GetMarkerColor());
285  if (GetMarkerStyle() != 1) printf(" MarkerStyle=%d",GetMarkerStyle());
286  if (GetMarkerSize() != 1) printf(" MarkerSize=%f",GetMarkerSize());
287  printf("\n");
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Save primitive as a C++ statement(s) on output stream out
292 
293 void TMarker::SavePrimitive(std::ostream &out, Option_t * /*= ""*/)
294 {
295  if (gROOT->ClassSaved(TMarker::Class())) {
296  out<<" ";
297  } else {
298  out<<" TMarker *";
299  }
300  out<<"marker = new TMarker("<<fX<<","<<fY<<","<<fMarkerStyle<<");"<<std::endl;
301 
302  SaveMarkerAttributes(out,"marker",1,1,1);
303 
304  out<<" marker->Draw();"<<std::endl;
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Set NDC mode on if isNDC = kTRUE, off otherwise
309 
310 void TMarker::SetNDC(Bool_t isNDC)
311 {
312  ResetBit(kMarkerNDC);
313  if (isNDC) SetBit(kMarkerNDC);
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// Stream an object of class TMarker.
318 
319 void TMarker::Streamer(TBuffer &R__b)
320 {
321  if (R__b.IsReading()) {
322  UInt_t R__s, R__c;
323  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
324  if (R__v > 1) {
325  R__b.ReadClassBuffer(TMarker::Class(), this, R__v, R__s, R__c);
326  return;
327  }
328  //====process old versions before automatic schema evolution
329  TObject::Streamer(R__b);
330  TAttMarker::Streamer(R__b);
331  Float_t x,y;
332  R__b >> x; fX = x;
333  R__b >> y; fY = y;
334  //====end of old versions
335 
336  } else {
337  R__b.WriteClassBuffer(TMarker::Class(),this);
338  }
339 }
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 /// Return the bounding Box of the Line
343 
344 Rectangle_t TMarker::GetBBox()
345 {
346  Double_t size = this->GetMarkerSize();
347 
348  Rectangle_t BBox;
349  BBox.fX = gPad->XtoPixel(fX)+(Int_t)(2*size);
350  BBox.fY = gPad->YtoPixel(fY)-(Int_t)(2*size);
351  BBox.fWidth = 2*size;
352  BBox.fHeight = 2*size;
353  return (BBox);
354 }
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 /// Return the center of the BoundingBox as TPoint in pixels
358 
359 TPoint TMarker::GetBBoxCenter()
360 {
361  TPoint p;
362  p.SetX(gPad->XtoPixel(fX));
363  p.SetY(gPad->YtoPixel(fY));
364  return(p);
365 }
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Set center of the BoundingBox
369 
370 void TMarker::SetBBoxCenter(const TPoint &p)
371 {
372  fX = gPad->PixeltoX(p.GetX());
373  fY = gPad->PixeltoY(p.GetY() - gPad->VtoPixel(0));
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Set X coordinate of the center of the BoundingBox
378 
379 void TMarker::SetBBoxCenterX(const Int_t x)
380 {
381  fX = gPad->PixeltoX(x);
382 }
383 
384 ////////////////////////////////////////////////////////////////////////////////
385 /// Set Y coordinate of the center of the BoundingBox
386 
387 void TMarker::SetBBoxCenterY(const Int_t y)
388 {
389  fY = gPad->PixeltoY(y - gPad->VtoPixel(0));
390 }
391 
392 ////////////////////////////////////////////////////////////////////////////////
393 /// Set left hand side of BoundingBox to a value
394 /// (resize in x direction on left)
395 
396 void TMarker::SetBBoxX1(const Int_t x)
397 {
398  Double_t size = this->GetMarkerSize();
399  fX = gPad->PixeltoX(x + (Int_t)size);
400 }
401 
402 ////////////////////////////////////////////////////////////////////////////////
403 /// Set right hand side of BoundingBox to a value
404 /// (resize in x direction on right)
405 
406 void TMarker::SetBBoxX2(const Int_t x)
407 {
408  Double_t size = this->GetMarkerSize();
409  fX = gPad->PixeltoX(x - (Int_t)size);
410 }
411 
412 ////////////////////////////////////////////////////////////////////////////////
413 /// Set top of BoundingBox to a value (resize in y direction on top)
414 
415 void TMarker::SetBBoxY1(const Int_t y)
416 {
417  Double_t size = this->GetMarkerSize();
418  fY = gPad->PixeltoY(y - (Int_t)size - gPad->VtoPixel(0));
419 }
420 
421 ////////////////////////////////////////////////////////////////////////////////
422 /// Set bottom of BoundingBox to a value
423 /// (resize in y direction on bottom)
424 
425 void TMarker::SetBBoxY2(const Int_t y)
426 {
427  Double_t size = this->GetMarkerSize();
428  fY = gPad->PixeltoY(y + (Int_t)size - gPad->VtoPixel(0));
429 }