00001 #include "GfxDigit.h"
00002 #include "GfxDigitList.h"
00003 #include "GfxDigitListCfg.h"
00004 #include "ViewState.h"
00005 #include <Midad/Base/Mint.h>
00006 #include <Midad/Util/Util.h>
00007
00008 #include <UgliGeometry/UgliGeomHandle.h>
00009 #include <UgliGeometry/UgliStripHandle.h>
00010
00011 #include <CandDigit/CandDigitHandle.h>
00012 #include <Plex/PlexSEIdAltL.h>
00013
00014 #include <MessageService/MsgService.h>
00015 CVSID("$Id: GfxDigit.cxx,v 1.7 2005/02/02 14:52:23 tagg Exp $");
00016
00017 #include <TEllipse.h>
00018 #include <TBox.h>
00019 #include <TPad.h>
00020
00021 #include <iostream>
00022 using namespace std;
00023
00024 ClassImp(GfxDigit)
00025
00026 #if 0
00027 GfxDigit::GfxDigit()
00028 : fDigit(0)
00029 ,fParent(0)
00030 ,fImp(0)
00031 {
00032 }
00033 #endif
00034 GfxDigit::GfxDigit(const CandDigitHandle& csh, GfxDigitList& parent)
00035 : fDigit(&csh)
00036 ,fItem(0)
00037 ,fParent(&parent)
00038 ,fImp(0)
00039 {
00040 }
00041 GfxDigit::GfxDigit(const CandDigitHandle& csh,
00042 const PlexSEIdAltLItem& itm, GfxDigitList& parent)
00043 : fDigit(&csh)
00044 ,fItem(&itm)
00045 ,fParent(&parent)
00046 ,fImp(0)
00047 {
00048
00049
00050
00051
00052 }
00053 GfxDigit::GfxDigit(const GfxDigit& rhs)
00054 : TObject()
00055 , fDigit(rhs.fDigit), fItem(rhs.fItem), fParent(rhs.fParent), fImp(0)
00056 {
00057 }
00058 GfxDigit& GfxDigit::operator=(const GfxDigit& rhs)
00059 {
00060 if (this == &rhs) return *this;
00061 fDigit = rhs.fDigit;
00062 fItem = rhs.fItem;
00063 fParent = rhs.fParent;
00064 fImp = 0;
00065 return *this;
00066 }
00067
00068 GfxDigit::~GfxDigit()
00069 {
00070 this->Clear();
00071 }
00072
00073 void GfxDigit::Clear(const Option_t*)
00074 {
00075 if (fImp) delete fImp; fImp = 0;
00076 }
00077
00078 bool GfxDigit::GetRealCoords(double& cx, double& cy, double& dx, double& dy)
00079 {
00080 UgliGeomHandle ugh(*fDigit->GetVldContext());
00081 UgliStripHandle ush;
00082
00083 if (!fItem) {
00084 ush = ugh.GetStripHandle(fDigit->GetPlexSEIdAltL().GetBestItem().GetSEId());
00085 }
00086 else {
00087 ush = ugh.GetStripHandle(fItem->GetSEId());
00088 }
00089
00090 if (!ush.IsValid()) return false;
00091
00092 cx = ush.GlobalPos(0).Z();
00093 cy = ush.GetTPos();
00094 dx = ush.GetHalfThickness();
00095 dy = ush.GetHalfWidth();
00096 return true;
00097 }
00098 bool GfxDigit::GetDiscreteCoords(double& cx, double& cy, double& dx, double& dy)
00099 {
00100 PlexStripEndId seid;
00101
00102 if (!fItem) {
00103 seid = fDigit->GetPlexSEIdAltL().GetBestItem().GetSEId();
00104 }
00105 else {
00106 seid = fItem->GetSEId();
00107 }
00108 cx = seid.GetPlane();
00109 cy = seid.GetStrip();
00110 dx = 0.5;
00111 dy = 0.5;
00112 if (fItem)
00113 MSG("Midad",Msg::kVerbose) << seid.AsString()
00114 << " cx = " << cx
00115 << " cy = " << cy << endl;
00116 return true;
00117 }
00118
00119 float GfxDigit::GetRelativeValue(GfxDigitListCfg::MeasureScale_t ms)
00120 {
00121 if (ms == GfxDigitListCfg::kCharge) {
00122 RangeDouble& qrange = fParent->GetMint().GetChargeRange();
00123 double den = qrange.Min() - qrange.Max();
00124 if (den > 0)
00125 return (fDigit->GetCharge() - qrange.Min()) / den;
00126 }
00127 else {
00128 RangeDouble& trange = fParent->GetMint().GetTimeRange();
00129 double den = trange.Max() - trange.Min();
00130 if (den > 0)
00131 return (fDigit->GetTime() - trange.Min()) / den;
00132 }
00133 return 1.0;
00134 }
00135
00136 void GfxDigit::ModifyCoords(double& cx, double& cy, double& dx, double& dy)
00137 {
00138 int strip_sign = 0;
00139
00140 StripEnd::StripEnd_t end;
00141 if (!fItem) {
00142 end = fDigit->GetPlexSEIdAltL().GetBestItem().GetSEId().GetEnd();
00143 }
00144 else {
00145 end = fItem->GetSEId().GetEnd();
00146 }
00147 if (end == StripEnd::kNegative) strip_sign = -1;
00148 if (end == StripEnd::kPositive) strip_sign = +1;
00149
00150 GfxDigitListCfg& cfg = fParent->GetCfg();
00151
00152
00153 GfxDigitListCfg::SizeBy_t sb = cfg.GetSizeBy();
00154 double size_scale = this->GetRelativeValue(cfg.GetSizeIs());
00155
00156 size_scale *= cfg.GetSizeFactor();
00157
00158 switch (sb) {
00159 case GfxDigitListCfg::kFixed:
00160
00161 break;
00162 case GfxDigitListCfg::kLinear:
00163 dx *= size_scale;
00164 dy *= size_scale;
00165 break;
00166 case GfxDigitListCfg::kLogLinear:
00167 dx *= logify_relative(size_scale);
00168 dy *= logify_relative(size_scale);
00169 break;
00170 case GfxDigitListCfg::kLogArea:
00171 dx *= logify_relative(sqrt(size_scale));
00172 dy *= logify_relative(sqrt(size_scale));
00173 break;
00174 case GfxDigitListCfg::kArea: default:
00175 dx *= sqrt(size_scale);
00176 dy *= sqrt(size_scale);
00177 break;
00178 }
00179
00180
00181 GfxDigitListCfg::DigitEnd_t si = cfg.GetStripEnd();
00182 switch (si) {
00183 case GfxDigitListCfg::kHalf:
00184 dy *= strip_sign * 0.5;
00185 cy += dy;
00186 break;
00187 case GfxDigitListCfg::kBowTie:
00188 dx *= strip_sign * 0.5;
00189 dy *= strip_sign * 0.5;
00190 cx += dx;
00191 cy += dy;
00192 break;
00193 case GfxDigitListCfg::kFull:
00194
00195 case GfxDigitListCfg::kBit:
00196
00197 default:
00198
00199 break;
00200 }
00201 }
00202
00203 bool GfxDigit::SetColor()
00204 {
00205 int color = 0;
00206 if (!fItem) {color = fParent->GetDigitColor(*fDigit); }
00207 else {color = fParent->GetDigitColor(*fDigit, *fItem);}
00208
00209 if (!color) {
00210 return false;
00211 }
00212
00213 TAttFill* att_fill = dynamic_cast<TAttFill*>(fImp);
00214 if (!att_fill) return false;
00215 att_fill->SetFillColor(color);
00216
00217 if (!fItem) {
00218 att_fill->SetFillStyle(1001);
00219 }
00220 else {
00221 att_fill->SetFillStyle(0);
00222 const PlexSEIdAltLItem& best = fDigit->GetPlexSEIdAltL().GetBestItem();
00223 if ( fItem == &best) att_fill->SetFillStyle(1001);
00224 }
00225
00226 TAttLine* att_line = dynamic_cast<TAttLine*>(fImp);
00227 if (!att_line) return false;
00228 att_line->SetLineColor(color);
00229 return true;
00230 }
00231
00232 void GfxDigit::Configure()
00233 {
00234
00235
00236 if (fImp) { delete fImp; fImp = 0; }
00237
00238 GfxDigitListCfg& cfg = fParent->GetCfg();
00239
00240 fCx = fCy = fDx = fDy = 0.0;
00241
00242
00243 switch (fParent->GetViewState()->GetSpatialMetric()) {
00244 case ViewState::metric_is_continuous:
00245 this->GetRealCoords(fCx,fCy,fDx,fDy);
00246 break;
00247 case ViewState::metric_is_discreet: default:
00248 this->GetDiscreteCoords(fCx,fCy,fDx,fDy);
00249 break;
00250 }
00251
00252
00253 double dx = fDx, dy = fDy;
00254 if (cfg.GetScaleIs() == GfxDigitListCfg::kAbsolute) {
00255 fDx = 1.0;
00256 fDy = 4.0;
00257 this->ModifyCoords(fCx,fCy,fDx,fDy);
00258 this->RelToAbs(dx,dy);
00259 }
00260 else {
00261 this->ModifyCoords(fCx,fCy,fDx,fDy);
00262 }
00263
00264 switch (cfg.GetShapeIs()) {
00265 case GfxDigitListCfg::kEllipse:
00266 fImp = new TEllipse(fCx,fCy,dx,dy);
00267 break;
00268 default:
00269 fImp = new TBox(fCx+dx,fCy+dy,fCx-dx,fCy-dy);
00270 break;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 }
00282
00283
00284 void GfxDigit::ExecuteEvent(int event, int px, int py)
00285 {
00286 fParent->ExecuteEventDigit(event,px,py,this);
00287 }
00288 void GfxDigit::Paint(Option_t* option)
00289 {
00290 if (!fImp) return;
00291
00292 if (fParent->DigitsHidden()) return;
00293
00294 if (!this->SetColor()) return;
00295
00296 GfxDigitListCfg& cfg = fParent->GetCfg();
00297 if (cfg.GetScaleIs() == GfxDigitListCfg::kAbsolute) {
00298 double dx, dy;
00299 this->RelToAbs(dx,dy);
00300
00301 switch (cfg.GetShapeIs()) {
00302 case GfxDigitListCfg::kEllipse: {
00303 TEllipse* el= dynamic_cast<TEllipse*>(fImp);
00304 el->SetR1(dx);
00305 el->SetR2(dy);
00306 el->Paint(option);
00307 break;
00308 }
00309 default:
00310 TBox* box = dynamic_cast<TBox*>(fImp);
00311 box->SetX1(fCx+dx);
00312 box->SetY1(fCy+dy);
00313 box->SetX2(fCx-dx);
00314 box->SetY2(fCy-dy);
00315 box->Paint();
00316 break;
00317 }
00318 }
00319 else {
00320 fImp->Paint(option);
00321 }
00322 }
00323 int GfxDigit::DistancetoPrimitive(int px, int py)
00324 {
00325 if (fImp) return fImp->DistancetoPrimitive(px,py);
00326 return 0xdead;
00327 }
00328
00329 void GfxDigit::RelToAbs(double& dx, double& dy)
00330 {
00331 dx = gPad->AbsPixeltoX((int)fDx) - gPad->AbsPixeltoX(0);
00332 dy = gPad->AbsPixeltoY((int)fDy) - gPad->AbsPixeltoY(0);
00333
00334 }
00335
00336 void GfxDigit::ConfigGui(void)
00337 {
00338 if (!fParent) return;
00339 GfxDigitListCfg& cfg = fParent->GetCfg();
00340 cfg.GuiConfig();
00341 }