/*************************************************************************** * Copyright (C) 2004 by Olivier Stezowski * * stezow(AT)ipnl.in2p3.fr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /** \file Level.cpp compiled in libGWPHYSICS.so */ #ifndef Gw_Level #include "Level.h" #endif #ifndef ROOT_TCanvas //#include #include #endif #ifndef ROOT_TROOT #include #endif #ifndef ROOT_TClass #include #endif #ifndef ROOT_TVirtualX #include #endif using namespace Gw; ClassImp(Level); const Short_t Level::fgkMaxLevelLabel = 4; const Int_t Level::fgkMaxColor = 4; const Int_t Level::fgkMaxStyle = 2; Style_t Level::fgDefaultStyle[fgkMaxStyle] = {1, 2}; Color_t Level::fgDefaultColor[fgkMaxColor] = {9, 2, 1, 6}; Float_t Level::fgDefaultLabelSize = 0.03; Color_t Level::fgDefaultLabelColor = 1; Bool_t Level::fgMovable = false; //__________________________________________________________ Level::Level() : TLine(), fVisLabel("0000"), fPosLabel("0123"), fLabel0(), fLabel1(), fLabel2(), fLabel3(), fExtra(), fHasExtra(false), fDefaultStyle(kKnown), fDefaultColor(kPlus), fLog("Level"), fIsSelected(false), fIsVisible(true), fIsModified(false), fDY(0.0) { TLine::SetX1(0); TLine::SetX2(0); TLine::SetY1(0); TLine::SetY2(0); fExtra.SetX1(0); fExtra.SetX2(0); fExtra.SetLineColor(17); fExtra.SetLineStyle(2); fExtra.SetBit(TObject::kInvalidObject); fLabel0.SetX(0); fLabel0.SetY(0); fLabel0.SetTextAlign(21); fLabel0.SetBit(TObject::kCannotPick); fLabel1.SetX(0); fLabel1.SetY(0); fLabel1.SetTextAlign(21); fLabel1.SetBit(TObject::kCannotPick); fLabel2.SetX(0); fLabel2.SetY(0); fLabel2.SetTextAlign(23); fLabel2.SetBit(TObject::kCannotPick); fLabel3.SetX(0); fLabel3.SetY(0); fLabel3.SetTextAlign(23); fLabel3.SetBit(TObject::kCannotPick); fLabel0.SetTextSize(GetDefaultLabelSize()); fLabel1.SetTextSize(GetDefaultLabelSize()); fLabel2.SetTextSize(GetDefaultLabelSize()); fLabel3.SetTextSize(GetDefaultLabelSize()); fLabel0.SetTextFont(132); fLabel1.SetTextFont(132); fLabel2.SetTextFont(132); fLabel3.SetTextFont(132); } //__________________________________________________________ Level::~Level() { } //__________________________________________________________ void Level::SetStyle(EDefaultStyle style) { Style_t st = GetDefaultStyle(style); SetLineStyle(st); fDefaultStyle = style; } //__________________________________________________________ void Level::SetColor(EDefaultColor color) { Color_t co = GetDefaultColor(color); SetLineColor(co); fDefaultColor = color; } //__________________________________________________________ void Level::SetLabelsSize(Float_t size) { fLabel0.SetTextSize(size); fLabel1.SetTextSize(size); fLabel2.SetTextSize(size); fLabel3.SetTextSize(size); } //__________________________________________________________ void Level::SetLabelsColor(Color_t color) { fLabel0.SetTextColor(color); fLabel1.SetTextColor(color); fLabel2.SetTextColor(color); fLabel3.SetTextColor(color); } //__________________________________________________________ void Level::SetExtraLine(Double_t x1, Double_t x2) { SetExtraLineX1(x1); SetExtraLineX2(x2); } //__________________________________________________________ void Level::SetExtraLineX1(Double_t x1) { if ( fExtra.TestBit(TObject::kInvalidObject) ) { // not yet initialised fExtra.SetBit(TObject::kCannotPick); fExtra.SetX1(TLine::GetX1());fExtra.SetX2(TLine::GetX2()); fExtra.SetBit(TObject::kInvalidObject, false); } if ( x1 < GetX1() ) { fExtra.SetX1(x1); fExtra.SetX2(TMath::Max(TLine::GetX1(),fExtra.GetX2())); fHasExtra = true; } } //__________________________________________________________ void Level::SetExtraLineX2(Double_t x2) { if ( fExtra.TestBit(TObject::kInvalidObject) ) { // not yet initialised fExtra.SetBit(TObject::kCannotPick); fExtra.SetX1(TLine::GetX1());fExtra.SetX2(TLine::GetX2()); fExtra.SetBit(TObject::kInvalidObject, false); } if ( x2 > GetX2() ) { fExtra.SetX2(x2); fExtra.SetX1(TMath::Min(TLine::GetX2(),fExtra.GetX1())); fHasExtra = true; } } //__________________________________________________________ void Level::SetVisLabel(const char *s) { TString st = s; Short_t end = (st.Length() < fgkMaxLevelLabel) ? st.Length(): fgkMaxLevelLabel; for( Short_t i = 0; i < end; i++ ) { if ( st[i] == '0' ) { fVisLabel[i] = '0'; } else { fVisLabel[i] = '1'; } } } //__________________________________________________________ void Level::SetPosLabel(const char *s) { TString st = s; Short_t end = (st.Length() < fgkMaxLevelLabel) ? st.Length(): fgkMaxLevelLabel; for( Short_t i = 0; i < end; ++i ) { if (st.CountChar(st[i]) > 1) { fPosLabel = "0123"; fLog.SetProcessMethod("SetPosLabel(const char* )"); fLog << warning << Form("Unambiguous position label pattern, set to %s", fPosLabel.Data()) << dolog; return; } } fPosLabel = s; } //__________________________________________________________ void Level::SetLabel(const char *label, Int_t which) { if (which < 0 || which >= fgkMaxLevelLabel) return; switch (which) { case 0: fLabel0.SetText(fLabel0.GetX(),fLabel0.GetY(),label); break; case 1: fLabel1.SetText(fLabel1.GetX(),fLabel1.GetY(),label); break; case 2: fLabel2.SetText(fLabel2.GetX(),fLabel2.GetY(),label); break; case 3: fLabel3.SetText(fLabel3.GetX(),fLabel3.GetY(),label); break; } } //__________________________________________________________ void Level::SetLabels(const char *l0, const char *l1, const char *l2, const char *l3) { fLabel0.SetText(fLabel0.GetX(),fLabel0.GetY(),l0); fLabel1.SetText(fLabel1.GetX(),fLabel1.GetY(),l1); fLabel2.SetText(fLabel2.GetX(),fLabel2.GetY(),l2); fLabel3.SetText(fLabel3.GetX(),fLabel3.GetY(),l3); } //__________________________________________________________ void Level::ExtraLine(Bool_t extra) { fHasExtra = extra; if (fHasExtra) fExtra.SetBit(TObject::kInvalidObject, false); else fExtra.SetBit(TObject::kInvalidObject, true); } //__________________________________________________________ void Level::SetDefaultLabels() { SetLabelsSize(Level::GetDefaultLabelSize()); SetLabelsColor(Level::GetDefaultLabelColor()); SetLabels(GetLabel0(), GetLabel1(), GetLabel2(), GetLabel3()); } //__________________________________________________________ TLatex & Level::GetLabel(Int_t which) { if ( which <= 0 ) return fLabel0; if ( which == 1 ) return fLabel1; if ( which == 2 ) return fLabel2; return fLabel3; } //__________________________________________________________ void Level::SetX1(Double_t x1) { Double_t dx = x1-TLine::GetX1(); TLine::SetX1(x1); for (Int_t i = 0; i <= 3; i+=3) { Int_t idx = fPosLabel[i] - '0'; GetLabel(idx).SetX(GetLabel(idx).GetX()+dx); } } //__________________________________________________________ void Level::SetX2(Double_t x2) { Double_t dx = x2-TLine::GetX2(); TLine::SetX2(x2); for (Int_t i = 1; i <= 2; ++i) { Int_t idx = fPosLabel[i] - '0'; GetLabel(idx).SetX(GetLabel(idx).GetX()+dx); } } //__________________________________________________________ void Level::SetY1(Double_t y1) { Double_t dy = y1-TLine::GetY1(); for (Int_t i = 0; i < fgkMaxLevelLabel; ++i) { Int_t align = 21; if (i > 1) align = 23; Int_t idx = fPosLabel[i] - '0'; GetLabel(idx).SetY(GetLabel(idx).GetY()+dy); GetLabel(idx).SetTextAlign(align); } // a level is always horizontal TLine::SetY1(y1); TLine::SetY2(y1); } //__________________________________________________________ void Level::SetY2(Double_t y2) { Double_t dy = y2-TLine::GetY2(); for (Int_t i = 0; i < fgkMaxLevelLabel; ++i) { Int_t align = 21; if (i > 1) align = 23; Int_t idx = fPosLabel[i] - '0'; GetLabel(idx).SetY(GetLabel(idx).GetY()+dy); GetLabel(idx).SetTextAlign(align); } // a level is always horizontal TLine::SetY1(y2); TLine::SetY2(y2); fExtra.SetY1(y2); fExtra.SetY2(y2); } //__________________________________________________________ Int_t Level::Compare(const TObject *lev) const { if ( GetY1() == ((Level *)lev)->GetY1() ) return 0; else if ( GetY1() < ((Level *)lev)->GetY1() ) return -1; else return 1; } //__________________________________________________________ void Level::Paint(Option_t* option) { if ( !IsVisible() ) return; if (!fExtra.TestBit(TObject::kInvalidObject)) fExtra.Paint(option); TLine::Paint(option); Int_t idx = 0; if ( fVisLabel[0] == '1' ) { idx = fPosLabel[0] -'0'; GetLabel(idx).Paint(option); } if ( fVisLabel[1] == '1' ) { idx = fPosLabel[1] - '0'; GetLabel(idx).Paint(option); } if ( fVisLabel[2] == '1' ) { idx = fPosLabel[2] -'0'; GetLabel(idx).Paint(option); } if ( fVisLabel[3] == '1' ) { idx = fPosLabel[3] - '0'; GetLabel(idx).Paint(option); } } //__________________________________________________________ void Level::Draw(Option_t* option) { if ( !IsVisible() ) return; TLine::Draw(option); //fExtra.Draw(option); Int_t idx = 0; if ( fVisLabel[0] == '1' ) { idx = fPosLabel[0] -'0'; GetLabel(idx).Draw(option); } if ( fVisLabel[1] == '1' ) { idx = fPosLabel[1] - '0'; GetLabel(idx).Draw(option); } if ( fVisLabel[2] == '1' ) { idx = fPosLabel[2] -'0'; GetLabel(idx).Draw(option); } if ( fVisLabel[3] == '1' ) { idx = fPosLabel[3] - '0'; GetLabel(idx).Draw(option); } } //__________________________________________________________ void Level::ExecuteEvent(Int_t event, Int_t px, Int_t py) { // Execute action corresponding to one event. // This member function is called when a line is clicked with the locator // // If Left button clicked on one of the line end points, this point // follows the cursor until button is released. // // if Middle button clicked, the line is moved parallel to itself // until the button is released. if ( !IsMovable() ) return; Int_t kMaxDiff = 20; static Int_t d1,d2,px1,px2,py1,py2; static Int_t pxold, pyold, px1old, py1old, px2old, py2old; static Bool_t p1, p2, pL; Double_t dpx,dpy,xp1,yp1; Int_t dx, dy; Double_t vx0,vx1,vx2,vx3,vy0,vy1,vy2,vy3; vx0 = fLabel0.GetX() - GetX1(); vy0 = fLabel0.GetY() - GetY1(); // offsets label 0 vx1 = fLabel1.GetX() - GetX2(); vy1 = fLabel1.GetY() - GetY1(); // offsets label 1 vx2 = fLabel2.GetX() - GetX2(); vy2 = fLabel2.GetY() - GetY1(); // offsets label 2 vx3 = fLabel3.GetX() - GetX1(); vy3 = fLabel3.GetY() - GetY1(); // offsets label 3 if (!gPad->IsEditable()) return; switch (event) { case kButton1Down: gVirtualX->SetLineColor(-1); TAttLine::Modify(); //Change line attributes only if necessary /* fall through */ case kMouseMotion: if (TestBit(kLineNDC)) { px1 = gPad->UtoPixel(fX1); py1 = gPad->VtoPixel(fY1); px2 = gPad->UtoPixel(fX2); py2 = gPad->VtoPixel(fY2); } else { px1 = gPad->XtoAbsPixel(gPad->XtoPad(fX1)); py1 = gPad->YtoAbsPixel(gPad->YtoPad(fY1)); px2 = gPad->XtoAbsPixel(gPad->XtoPad(fX2)); py2 = gPad->YtoAbsPixel(gPad->YtoPad(fY2)); } p1 = p2 = pL = kFALSE; d1 = TMath::Abs(px1 - px) + TMath::Abs(py1-py); //simply take sum of pixels differences if (d1 < kMaxDiff) { //*-*================>OK take point number 1 px1old = px1; py1old = py1; p1 = kTRUE; gPad->SetCursor(kPointer); return; } d2 = TMath::Abs(px2 - px) + TMath::Abs(py2-py); //simply take sum of pixels differences if (d2 < kMaxDiff) { //*-*================>OK take point number 2 px2old = px2; py2old = py2; p2 = kTRUE; gPad->SetCursor(kPointer); return; } pL = kTRUE; pxold = px; pyold = py; gPad->SetCursor(kMove); break; case kButton1Motion: if (p1) { gVirtualX->DrawLine(px1old, py1old, px2, py2); gVirtualX->DrawLine(px, py, px2, py2); px1old = px; py1old = py; } if (p2) { gVirtualX->DrawLine(px1, py1, px2old, py2old); gVirtualX->DrawLine(px1, py1, px, py); px2old = px; py2old = py; } if (pL) { gVirtualX->DrawLine(px1, py1, px2, py2); dx = px-pxold; dy = py-pyold; px1 += dx; py1 += dy; px2 += dx; py2 += dy; gVirtualX->DrawLine(px1, py1, px2, py2); pxold = px; pyold = py; } break; case kButton1Up: if (TestBit(kLineNDC)) { dpx = gPad->GetX2() - gPad->GetX1(); dpy = gPad->GetY2() - gPad->GetY1(); xp1 = gPad->GetX1(); yp1 = gPad->GetY1(); if (p1) { fX1 = (gPad->AbsPixeltoX(px)-xp1)/dpx; fY1 = (gPad->AbsPixeltoY(py)-yp1)/dpy; fY2 = fY1; } if (p2) { fX2 = (gPad->AbsPixeltoX(px)-xp1)/dpx; fY2 = (gPad->AbsPixeltoY(py)-yp1)/dpy; fY1 = fY2; } if (pL) { fX1 = (gPad->AbsPixeltoX(px1)-xp1)/dpx; fY1 = (gPad->AbsPixeltoY(py1)-yp1)/dpy; fX2 = (gPad->AbsPixeltoX(px2)-xp1)/dpx; fY2 = (gPad->AbsPixeltoY(py2)-yp1)/dpy; } if (fX1 <= fX2 ) { //vx = fLabel0.GetX()-fX1; fLabel0.SetX(fX1+vx0); fLabel0.SetY(fY1+vy0); fLabel1.SetX(fX2); fLabel1.SetY(fY1); fLabel2.SetX(fX2); fLabel2.SetY(fY1); fLabel3.SetX(fX1); fLabel3.SetY(fY1); } else { fLabel1.SetX(fX1); fLabel1.SetY(fY1); fLabel0.SetX(fX2+vx0); fLabel0.SetY(fY1+vy0); fLabel3.SetX(fX2); fLabel3.SetY(fY1); fLabel2.SetX(fX1); fLabel2.SetY(fY1); } } else { if (p1) { fX1 = gPad->PadtoX(gPad->AbsPixeltoX(px)); fY1 = gPad->PadtoY(gPad->AbsPixeltoY(py)); fY2 = fY1; } if (p2) { fX2 = gPad->PadtoX(gPad->AbsPixeltoX(px)); fY2 = gPad->PadtoY(gPad->AbsPixeltoY(py)); fY1 = fY2; } if (pL) { fX1 = gPad->PadtoX(gPad->AbsPixeltoX(px1)); fY1 = gPad->PadtoY(gPad->AbsPixeltoY(py1)); fX2 = gPad->PadtoX(gPad->AbsPixeltoX(px2)); fY2 = gPad->PadtoY(gPad->AbsPixeltoY(py2)); } if (fX1 > fX2) { Double_t fX3; fX3 = fX1; fX1 = fX2; fX2 = fX3; } fLabel0.SetX(fX1+vx0); fLabel0.SetY(fY1+vy0); fLabel1.SetX(fX2+vx1); fLabel1.SetY(fY1+vy1); fLabel2.SetX(fX2+vx2); fLabel2.SetY(fY1+vy2); fLabel3.SetX(fX1+vx3); fLabel3.SetY(fY1+vy3); if (fHasExtra) { if (fExtra.GetX1() < fX1) fExtra.SetX2(fX1); if (fExtra.GetX2() > fX2) fExtra.SetX1(fX2); fExtra.SetY1(fY1); fExtra.SetY2(fY1); } /*if (fX1 <= fX2 ) { fLabel0.SetX(fX1+vx0); fLabel0.SetY(fY1+vy0); fLabel1.SetX(fX2); fLabel1.SetY(fY1); fLabel2.SetX(fX2); fLabel2.SetY(fY1); fLabel3.SetX(fX1); fLabel3.SetY(fY1); } else { fLabel1.SetX(fX1); fLabel1.SetY(fY1); fLabel0.SetX(fX2+vx0); fLabel0.SetY(fY1+vy0); fLabel3.SetX(fX2); fLabel3.SetY(fY1); fLabel2.SetX(fX1); fLabel2.SetY(fY1); }*/ } gPad->Modified(kTRUE); gVirtualX->SetLineColor(-1); break; case kButton1Locate: ExecuteEvent(kButton1Down, px, py); while (1) { px = py = 0; event = gVirtualX->RequestLocator(1,1,px,py); ExecuteEvent(kButton1Motion, px, py); if (event != -1) { // button is released ExecuteEvent(kButton1Up, px, py); return; } } } }