TDiamond.cxx

Go to the documentation of this file.
00001 // @(#)root/graf:$Id: TDiamond.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Rene Brun   22/06/96
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include <stdlib.h>
00013 
00014 #include "Riostream.h"
00015 #include "TBufferFile.h"
00016 #include "TROOT.h"
00017 #include "TDiamond.h"
00018 #include "TVirtualPad.h"
00019 #include "TVirtualX.h"
00020 #include "TMath.h"
00021 
00022 
00023 ClassImp(TDiamond)
00024 
00025 //______________________________________________________________________________
00026 //
00027 // A diamond is defined by :
00028 //   - Its central left coordinates x1,y1
00029 //   - Its top central coordinates x2,y2
00030 //
00031 // A diamond has line attributes (see TAttLine)
00032 //   and fill area attributes (see TAttFill).
00033 //
00034 // Like for the class TPaveText, a TDiamond may have one or more line(s)
00035 // of text inside.
00036 //Begin_Html
00037 /*
00038 <img src="gif/diamond.gif">
00039 */
00040 //End_Html
00041 //
00042 
00043 //______________________________________________________________________________
00044 TDiamond::TDiamond(): TPaveText()
00045 {
00046    // Diamond default constructor.
00047 
00048 }
00049 
00050 //______________________________________________________________________________
00051 TDiamond::TDiamond(Double_t x1, Double_t y1,Double_t x2, Double_t  y2)
00052      :TPaveText(x1,y1,x2,y2)
00053 {
00054    // Diamond standard constructor.
00055 }
00056 
00057 //______________________________________________________________________________
00058 TDiamond::~TDiamond()
00059 {
00060    // Diamond destructor.
00061 
00062 }
00063 
00064 //______________________________________________________________________________
00065 TDiamond::TDiamond(const TDiamond &diamond) : TPaveText()
00066 {
00067    // Copy constructor.
00068 
00069    TBufferFile b(TBuffer::kWrite);
00070    TDiamond *p = (TDiamond*)(&diamond);
00071    p->Streamer(b);
00072    b.SetReadMode();
00073    b.SetBufferOffset(0);
00074    Streamer(b);
00075 }
00076 
00077 //______________________________________________________________________________
00078 Int_t TDiamond::DistancetoPrimitive(Int_t px, Int_t py)
00079 {
00080    // Compute distance from point px,py to a diamond.
00081    //
00082    //  Compute the closest distance of approach from point px,py to the
00083    //  edges of this diamond.
00084    //  The distance is computed in pixels units.
00085 
00086    return TPaveText::DistancetoPrimitive(px,py);
00087 }
00088 
00089 //______________________________________________________________________________
00090 void TDiamond::Draw(Option_t *option)
00091 {
00092    // Draw this diamond with its current attributes.
00093 
00094    AppendPad(option);
00095 
00096 }
00097 
00098 //______________________________________________________________________________
00099 void TDiamond::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00100 {
00101    // Execute action corresponding to one event.
00102    //
00103    //  This member function is called when a Diamond object is clicked.
00104    //
00105    //  If the mouse is clicked inside the diamond, the diamond is moved.
00106    //
00107    //  If the mouse is clicked on the 4 tops (pL,pR,pTop,pBot), the diamond is rscaled.
00108    //
00109    //
00110    //                           pTop
00111    //                        +---------+
00112    //                        |   / \   |
00113    //                        |  /   \  |
00114    //                        | /     \ |
00115    //                      pL|/pinside\|pR
00116    //                        |\       /|
00117    //                        | \     / |
00118    //                        |  \   /  |
00119    //                        |   \ /   |
00120    //                        +---------+
00121    //                            pBot
00122 
00123    const Int_t kMaxDiff = 5;
00124    const Int_t kMinSize = 20;
00125 
00126    static Int_t px1, px2, py1, py2, pxl, pyl, pxt, pyt, pxold, pyold;
00127    static Int_t px1p, px2p, py1p, py2p;
00128    static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
00129    static Double_t x1c,x2c,x3c,x4c;
00130    static Bool_t pTop, pL, pR, pBot, pINSIDE;
00131    static Int_t i,x[5], y[5];
00132    Int_t  wx, wy;
00133    TVirtualPad  *parent;
00134    Bool_t doing_again = kFALSE;
00135    Bool_t opaque  = gPad->OpaqueMoving();
00136    Bool_t ropaque = gPad->OpaqueResizing();
00137 
00138    if (!gPad->IsEditable()) return;
00139 
00140    parent = gPad;
00141 
00142 again:
00143 
00144    switch (event) {
00145 
00146    case kButton1Down:
00147 
00148       gVirtualX->SetLineColor(-1);
00149       TAttLine::Modify();  //Change line attributes only if necessary
00150       if (GetFillColor())
00151          gVirtualX->SetLineColor(GetFillColor());
00152       else
00153          gVirtualX->SetLineColor(1);
00154       gVirtualX->SetLineWidth(2);
00155 
00156       // No break !!!
00157 
00158    case kMouseMotion:
00159 
00160       px1 = gPad->XtoAbsPixel(GetX1());
00161       py1 = gPad->YtoAbsPixel(GetY1());
00162       px2 = gPad->XtoAbsPixel(GetX2());
00163       py2 = gPad->YtoAbsPixel(GetY2());
00164 
00165       if (px1 < px2) {
00166          pxl = px1;
00167          pxt = px2;
00168       } else {
00169          pxl = px2;
00170          pxt = px1;
00171       }
00172       if (py1 < py2) {
00173          pyl = py1;
00174          pyt = py2;
00175       } else {
00176          pyl = py2;
00177          pyt = py1;
00178       }
00179 
00180       px1p = parent->XtoAbsPixel(parent->GetX1()) + parent->GetBorderSize();
00181       py1p = parent->YtoAbsPixel(parent->GetY1()) - parent->GetBorderSize();
00182       px2p = parent->XtoAbsPixel(parent->GetX2()) - parent->GetBorderSize();
00183       py2p = parent->YtoAbsPixel(parent->GetY2()) + parent->GetBorderSize();
00184 
00185       pTx = pBx = (pxl+pxt)/2;
00186       pLy = pRy = (pyl+pyt)/2;
00187       pTy = pyl;
00188       pBy = pyt;
00189       pLx = pxl;
00190       pRx = pxt;
00191 
00192       pTop = pL = pR = pBot = pINSIDE = kFALSE;
00193 
00194       if ((TMath::Abs(px-(pxl+pxt)/2) < kMaxDiff) &&
00195           (TMath::Abs(py - pyl) < kMaxDiff)) {             // top edge
00196          pxold = pxl; pyold = pyl; pTop = kTRUE;
00197          gPad->SetCursor(kTopSide);
00198       }
00199 
00200       if ((TMath::Abs(px-(pxl+pxt)/2) < kMaxDiff) &&
00201           (TMath::Abs(py - pyt) < kMaxDiff)) {             // bottom edge
00202          pxold = pxt; pyold = pyt; pBot = kTRUE;
00203          gPad->SetCursor(kBottomSide);
00204       }
00205 
00206       if ((TMath::Abs(py-(pyl+pyt)/2) < kMaxDiff) &&
00207           (TMath::Abs(px - pxl) < kMaxDiff)) {             // left edge
00208          pxold = pxl; pyold = pyl; pL = kTRUE;
00209          gPad->SetCursor(kLeftSide);
00210       }
00211 
00212       if ((TMath::Abs(py-(pyl+pyt)/2) < kMaxDiff) &&
00213           (TMath::Abs(px - pxt) < kMaxDiff)) {             // right edge
00214          pxold = pxt; pyold = pyt; pR = kTRUE;
00215          gPad->SetCursor(kRightSide);
00216       }
00217 
00218       x1c = (py-pTy)*(pTx-pLx)/(pTy-pLy)+pTx;
00219       x2c = (py-pTy)*(pRx-pTx)/(pRy-pTy)+pTx;
00220       x3c = (py-pRy)*(pRx-pBx)/(pRy-pBy)+pRx;
00221       x4c = (py-pBy)*(pBx-pLx)/(pBy-pLy)+pBx;
00222 
00223       if (px > x1c+kMaxDiff && px < x2c-kMaxDiff &&
00224           px > x4c+kMaxDiff && px < x3c-kMaxDiff) {    // inside box
00225          pxold = px; pyold = py; pINSIDE = kTRUE;
00226          if (event == kButton1Down)
00227             gPad->SetCursor(kMove);
00228          else
00229             gPad->SetCursor(kCross);
00230       }
00231 
00232       fResizing = kFALSE;
00233       if (pTop || pL || pR || pBot)
00234          fResizing = kTRUE;
00235 
00236       if (!pTop && !pL && !pR && !pBot && !pINSIDE)
00237          gPad->SetCursor(kCross);
00238 
00239       break;
00240 
00241    case kButton1Motion:
00242 
00243       wx = wy = 0;
00244       x[0] = x[2] = x[4] = (px1+px2)/2;
00245       x[1] = px2;
00246       x[3] = px1;
00247       y[0] = y[4] = py1;
00248       y[2] = py2;
00249       y[1] = y[3] = (py1+py2)/2;
00250       if (pTop) {
00251          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00252          py2 += py - pyold;
00253          if (py2 > py1-kMinSize) { py2 = py1-kMinSize; wy = py2; }
00254          if (py2 < py2p) { py2 = py2p; wy = py2; }
00255          y[2] = py2;
00256          y[1] = y[3] = (py1+py2)/2;
00257          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00258       }
00259       if (pBot) {
00260          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00261          py1 += py - pyold;
00262          if (py1 < py2+kMinSize) { py1 = py2+kMinSize; wy = py1; }
00263          if (py1 > py1p) { py1 = py1p; wy = py1; }
00264          y[0] = y[4] = py1;
00265          y[1] = y[3] = (py1+py2)/2;
00266          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00267       }
00268       if (pL) {
00269          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00270          px1 += px - pxold;
00271          if (px1 > px2-kMinSize) { px1 = px2-kMinSize; wx = px1; }
00272          if (px1 < px1p) { px1 = px1p; wx = px1; }
00273          x[3] = px1;
00274          x[0] = x[2] = x[4] = (px1+px2)/2;
00275          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00276       }
00277       if (pR) {
00278          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00279          px2 += px - pxold;
00280          if (px2 < px1+kMinSize) { px2 = px1+kMinSize; wx = px2; }
00281          if (px2 > px2p) { px2 = px2p; wx = px2; }
00282          x[1] = px2;
00283          x[0] = x[2] = x[4] = (px1+px2)/2;
00284          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00285       }
00286       if (pINSIDE) {
00287          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00288          Int_t dx = px - pxold;
00289          Int_t dy = py - pyold;
00290          px1 += dx; py1 += dy; px2 += dx; py2 += dy;
00291          if (px1 < px1p) { dx = px1p - px1; px1 += dx; px2 += dx; wx = px+dx; }
00292          if (px2 > px2p) { dx = px2 - px2p; px1 -= dx; px2 -= dx; wx = px-dx; }
00293          if (py1 > py1p) { dy = py1 - py1p; py1 -= dy; py2 -= dy; wy = py-dy; }
00294          if (py2 < py2p) { dy = py2p - py2; py1 += dy; py2 += dy; wy = py+dy; }
00295          x[0] = x[2] = x[4] = (px1+px2)/2;
00296          x[1] = px2;
00297          x[3] = px1;
00298          y[0] = y[4] = py1;
00299          y[2] = py2;
00300          y[1] = y[3] = (py1+py2)/2;
00301          for (i=0;i<4;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00302       }
00303 
00304       if (wx || wy) {
00305          if (wx) px = wx;
00306          if (wy) py = wy;
00307          gVirtualX->Warp(px, py);
00308       }
00309 
00310       pxold = px;
00311       pyold = py;
00312 
00313       if ((pINSIDE && opaque) || (fResizing && ropaque)) {
00314          event = kButton1Up;
00315          doing_again = kTRUE;
00316          goto again;
00317       }
00318 
00319       break;
00320 
00321    case kButton1Up:
00322 
00323       if (pTop || pBot || pL || pR || pINSIDE) {
00324          fX1 = gPad->AbsPixeltoX(px1);
00325          fY1 = gPad->AbsPixeltoY(py1);
00326          fX2 = gPad->AbsPixeltoX(px2);
00327          fY2 = gPad->AbsPixeltoY(py2);
00328       }
00329 
00330       if (pINSIDE) {
00331          // if it was not a pad that was moved then it must have been
00332          // a box or something like that so we have to redraw the pad
00333          if (parent == gPad) gPad->Modified(kTRUE);
00334          if (!doing_again) gPad->SetCursor(kCross);
00335       }
00336 
00337       if (pTop || pL || pR || pBot)
00338          gPad->Modified(kTRUE);
00339 
00340       gVirtualX->SetLineColor(-1);
00341       gVirtualX->SetLineWidth(-1);
00342 
00343       break;
00344 
00345    case kButton1Locate:
00346 
00347       ExecuteEvent(kButton1Down, px, py);
00348 
00349       while (1) {
00350          px = py = 0;
00351          event = gVirtualX->RequestLocator(1, 1, px, py);
00352 
00353          ExecuteEvent(kButton1Motion, px, py);
00354 
00355          if (event != -1) {                     // button is released
00356             ExecuteEvent(kButton1Up, px, py);
00357             return;
00358          }
00359       }
00360    }
00361 }
00362 
00363 //______________________________________________________________________________
00364 void TDiamond::Paint(Option_t *)
00365 {
00366    // Paint this diamond with its current attributes.
00367 
00368    Double_t x[7],y[7],depx,depy;
00369    Double_t x1 = fX1;
00370    Double_t y1 = fY1;
00371    Double_t x2 = fX2;
00372    Double_t y2 = fY2;
00373    Int_t fillstyle = GetFillStyle();
00374    Int_t fillcolor = GetFillColor();
00375    Int_t linecolor = GetLineColor();
00376    if (fBorderSize) {
00377       Double_t wy = gPad->PixeltoY(0) - gPad->PixeltoY(fBorderSize);
00378       Double_t wx = gPad->PixeltoX(fBorderSize) - gPad->PixeltoX(0);
00379       // Draw the frame top right
00380       if (y2-y1>x2-x1) {
00381          depx = wx;
00382          depy = 0;
00383          }
00384       else if (y2-y1<x2-x1) {
00385          depx = 0;
00386          depy = -wy;
00387          }
00388       else {
00389          depx = wx;
00390          depy = -wy;
00391       }
00392       x[0] = x[2] = (x1+x2)/2+depx;
00393       x[1] = x2+depx;
00394       x[3] = x1+depx;
00395       y[0] = y2+depy;
00396       y[2] = y1+depy;
00397       y[1] = y[3] =(y1+y2)/2+depy;
00398       x[4] = x[0]; y[4] = y[0];
00399       SetFillStyle(fillstyle);
00400       SetFillColor(linecolor);
00401       TAttFill::Modify();  //Change fill area attributes only if necessary
00402       gPad->PaintFillArea(4,x,y);
00403    }
00404    x[0] = x[2] = (x1+x2)/2;
00405    x[1] = x2;
00406    x[3] = x1;
00407    y[0] = y2;
00408    y[2] = y1;
00409    y[1] = y[3] = (y1+y2)/2;
00410    x[4] = x[0]; y[4] =y[0];
00411    SetLineColor(linecolor);
00412    SetFillColor(fillcolor);
00413    TAttLine::Modify();  //Change line attributes only if necessary
00414    TAttFill::Modify();  //Change fill area attributes only if necessary
00415    gPad->PaintFillArea(4,x,y);
00416    gPad->PaintPolyLine(5,x,y);
00417 
00418    // Paint list of primitives (test,etc)
00419    PaintPrimitives(kDiamond);
00420 }
00421 
00422 //______________________________________________________________________________
00423 void TDiamond::SavePrimitive(ostream &out, Option_t * /*= ""*/)
00424 {
00425    // Save primitive as a C++ statement(s) on output stream out.
00426 
00427    if (gROOT->ClassSaved(TDiamond::Class())) {
00428       out<<"   ";
00429    } else {
00430       out<<"   TDiamond *";
00431    }
00432    out<<"diamond = new TDiamond("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2<<");"<<endl;
00433 
00434    SaveFillAttributes(out,"diamond",0,1001);
00435    SaveLineAttributes(out,"diamond",1,1,1);
00436    SaveTextAttributes(out,"diamond",11,0,1,62,0.05);
00437 
00438    SaveLines(out,"diamond");
00439    out<<"   diamond->Draw();"<<endl;
00440 }

Generated on Tue Jul 5 14:14:27 2011 for ROOT_528-00b_version by  doxygen 1.5.1