2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
4 /**************************************************************************
5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
7 * full copyright notice. *
8 **************************************************************************/
10 #include "AliEveITSModuleStepper.h"
11 #include "AliEveITSDigitsInfo.h"
12 #include "AliEveITSScaledModule.h"
14 #include <TEveManager.h>
15 #include <TEveGedEditor.h>
16 #include <TEveGridStepper.h>
17 #include <TEveTrans.h>
19 #include <TGLRnrCtx.h>
20 #include <TGLIncludes.h>
21 #include <TGLSelectRecord.h>
23 #include <TGLViewer.h>
27 #include <THLimitsFinder.h>
28 #include <TVirtualPad.h>
30 //______________________________________________________________________________
32 // Display scaled ITS modules in a paged layout, also providing
33 // GL-overaly control GUI.
36 ClassImp(AliEveITSModuleStepper)
38 AliEveITSModuleStepper::AliEveITSModuleStepper(AliEveITSDigitsInfo* di) :
39 TEveElementList("ITS 2DStore", "AliEveITSModuleStepper", kTRUE),
60 SetMainColorPtr(&fTextCol);
61 fAxis = new TGLAxis();
63 // override member from base TEveElementList
64 fChildClass = AliEveITSScaledModule::Class();
66 fDigitsInfo->IncRefCount();
68 fStepper = new TEveGridStepper();
69 fStepper->SetNs(5, 4);
71 fScaleInfo = new AliEveDigitScaleInfo();
72 fScaleInfo->IncRefCount();
74 gEve->GetGLViewer()->AddOverlayElement(this);
77 AliEveITSModuleStepper::~AliEveITSModuleStepper()
81 gEve->GetGLViewer()->RemoveOverlayElement(this);
83 fScaleInfo->DecRefCount();
84 fDigitsInfo->DecRefCount();
90 /******************************************************************************/
92 void AliEveITSModuleStepper::Capacity()
94 // Make sure we have just enough children (module representations)
95 // to store as many modules as required by the grid-stepper
98 Int_t n = fStepper->GetNx()*fStepper->GetNy();
99 if (n != GetNChildren())
102 for (Int_t m=0; m<n; ++m)
104 AddElement(new AliEveITSScaledModule(m, fDigitsInfo, fScaleInfo));
109 /******************************************************************************/
111 void AliEveITSModuleStepper::SetFirst(Int_t first)
113 // Se module ID which apply to first item in stepper.
115 Int_t lastpage = fModuleIDs.size()/Nxy();
116 if (fModuleIDs.size() % Nxy() ) lastpage++;
118 Int_t firstLastpage = (lastpage - 1)*Nxy();
119 if (first > firstLastpage) first = firstLastpage;
120 if (first < 0) first = 0;
125 void AliEveITSModuleStepper::Start()
133 void AliEveITSModuleStepper::Next()
137 SetFirst(fPosition + Nxy());
140 void AliEveITSModuleStepper::Previous()
142 // Go to previous page.
144 SetFirst(fPosition - Nxy());
147 void AliEveITSModuleStepper::End()
151 Int_t lastpage = fModuleIDs.size()/Nxy();
152 if (fModuleIDs.size() % Nxy()) lastpage++;
153 fPosition = (lastpage - 1)*Nxy();
159 /******************************************************************************/
161 void AliEveITSModuleStepper::DisplayDet(Int_t det, Int_t layer)
163 // Select modules to display by sub-det type / layer.
167 AliEveITSModuleSelection sel = AliEveITSModuleSelection();
170 fDigitsInfo->GetModuleIDs(&sel, fModuleIDs);
171 //in reder menu define a space between left and right pager
175 /******************************************************************************/
177 Int_t AliEveITSModuleStepper::GetCurrentPage() const
179 // Get number of current page.
181 Int_t idx = fPosition + 1;
183 if (idx % Nxy()) n++;
187 /******************************************************************************/
189 Int_t AliEveITSModuleStepper::GetPages()
191 // Get number of all pages.
193 Int_t n = fModuleIDs.size()/Nxy();
194 if (fModuleIDs.size() % Nxy()) n++;
198 /******************************************************************************/
200 void AliEveITSModuleStepper::Apply()
202 // Apply current settings to children modules.
204 gEve->DisableRedraw();
207 UInt_t idx = fPosition;
208 for(List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
210 if (idx < fModuleIDs.size())
212 AliEveITSScaledModule* mod = dynamic_cast<AliEveITSScaledModule*>(*childit);
213 mod->SetID(fModuleIDs[idx], kFALSE);
214 TEveTrans& tr = mod->RefMainTrans();
216 tr.RotateLF(3,2,TMath::PiOver2());
217 tr.RotateLF(1,3,TMath::PiOver2());
221 Float_t* fp = mod->GetFrame()->GetFramePoints();
222 // switch x,z it will be rotated afterwards
227 Double_t sx = fStepper->GetDx();
228 Double_t sy = (mx*fStepper->GetDx())/mz;
229 if (sy > fStepper->GetDy())
231 sy = fStepper->GetDy();
232 sx = (mz*fStepper->GetDx())/mx;
234 Float_t scale = (0.85*sx)/mz;
235 tr.Scale(scale, scale, scale);
238 fStepper->GetPosition(p);
239 tr.SetPos(p[0]+0.5*fStepper->GetDx(), p[1]+0.5*fStepper->GetDy(), p[2]+0.5*fStepper->GetDz());
241 if (mod->GetSubDetID() == 2)
242 mod->SetName(Form("SSD %d", idx));
243 else if (mod->GetSubDetID() == 1)
244 mod->SetName(Form("SDD %d", idx));
246 mod->SetName(Form("SPD %d", idx));
247 mod->SetRnrSelf(kTRUE);
254 (*childit)->SetRnrSelf(kFALSE);
260 gEve->EnableRedraw();
264 /******************************************************************************/
265 // Virtual event handlers from TGLOverlayElement
266 /******************************************************************************/
268 //______________________________________________________________________________
269 Bool_t AliEveITSModuleStepper::Handle(TGLRnrCtx & /*rnrCtx*/,
270 TGLOvlSelectRecord & rec,
273 // Handle overlay event.
274 // Return TRUE if event was handled.
276 switch (event->fType)
280 Int_t item = rec.GetN() < 2 ? -1 : (Int_t)rec.GetItem(1);
281 if (fActiveID != item) {
291 if (event->fCode != kButton1) {
294 switch (rec.GetItem(1))
310 AliEveDigitScaleInfo* si = fScaleInfo;
311 if (si->GetScale() < 5)
313 si->ScaleChanged(si->GetScale() + 1);
314 ElementChanged(kTRUE, kTRUE);
320 AliEveDigitScaleInfo* si = fScaleInfo;
321 if (si->GetScale() > 1)
323 si->ScaleChanged(si->GetScale() - 1);
324 ElementChanged(kTRUE, kTRUE);
329 gEve->GetEditor()->DisplayElement(*BeginChildren());
353 //______________________________________________________________________________
354 Bool_t AliEveITSModuleStepper::MouseEnter(TGLOvlSelectRecord& /*rec*/)
356 // Mouse has entered overlay area.
361 //______________________________________________________________________________
362 void AliEveITSModuleStepper::MouseLeave()
364 // Mouse has left overlay area.
370 /******************************************************************************/
371 // Protected sub-renderers
372 /******************************************************************************/
374 //______________________________________________________________________________
375 void AliEveITSModuleStepper::RenderText(const char* txt, Int_t id, const TGLFont &font, Float_t step)
377 // Render text for button id.
379 Float_t llx, lly, llz, urx, ury, urz;
380 font.BBox(txt, llx, lly, llz, urx, ury, urz);
381 (fActiveID == id && id > 0) ? TGLUtil::Color(fActiveCol) :TGLUtil::Color(fTextCol);
385 // center text in the step interval
388 glTranslatef((step-urx+llx)*0.5f-llx, 0, 0);
392 glTranslatef(step, 0, 0);
400 glTranslatef(urx, 0, 0);
404 //______________________________________________________________________________
405 void AliEveITSModuleStepper::RenderPalette(TEveRGBAPalette* p)
407 // Render color palette with number axis.
409 Float_t length = 7*fTextSize;
410 Float_t x = 1.5*fTextSize;
411 Float_t y = 0.2*fTextSize;
413 glTranslatef(x, 0.8*fTextSize, 0);
415 TGLCapabilitySwitch lights_off(GL_LIGHTING, kFALSE);
417 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
418 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
419 glDisable(GL_CULL_FACE);
421 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
423 glBegin(GL_QUAD_STRIP);
424 TGLUtil::Color4ubv(p->ColorFromValue(p->GetMinVal()));
427 if (p->GetMaxVal() > p->GetMinVal() + 1)
429 Float_t xs = length/(p->GetMaxVal() - p->GetMinVal());
431 for(Int_t i=p->GetMinVal() + 1; i<p->GetMaxVal(); i++)
433 TGLUtil::Color4ubv(p->ColorFromValue(i));
439 TGLUtil::Color4ubv(p->ColorFromValue(p->GetMaxVal()));
440 glVertex2f(length, 0);
441 glVertex2f(length, y);
444 glRotatef(-90, 1, 0, 0 );
445 Double_t v1[3] = {0., 0., 0.};
446 Double_t v2[3] = {length, 0, 0.};
447 fAxis->SetTextColor(kGray+1);
448 fAxis->SetLineColor(kGray+1);
449 fAxis->PaintGLAxis(v1, v2, p->GetMinVal(), p->GetMaxVal(), 5);
453 //______________________________________________________________________________
454 void AliEveITSModuleStepper::RenderMenu(Int_t curP, Int_t maxP, Int_t scaleX, Int_t scaleZ)
456 // Make UI to set page in stepper and UI to scale in the AliEveITSScaledModule.
458 TGLUtil::Color(fTextCol);
459 fTextFont.PreRender();
460 glTranslatef(0, fTextSize*0.3, 0);
463 glTranslatef(fTextSize*0.2, 0 , 0);
464 RenderText("9", 2, fSymbolFont); // last page
465 RenderText("3", 1, fSymbolFont);//last page
466 RenderText(Form("%d/%d", curP, maxP),-1, fTextFont, 2.7*fTextSize); //status
468 // bugg in webdings font , bbox does not give realistic value
469 Float_t llx, lly, llz, urx, ury, urz;
470 fSymbolFont.BBox("4", llx, lly, llz, urx, ury, urz);
471 glTranslatef(-llx, 0, 0);
473 RenderText("4", 3, fSymbolFont); // next page
474 RenderText(":",4, fSymbolFont); // last page
478 glTranslatef(fTextSize,0, 0);
479 RenderText(Form("Zoom:"), -1, fTextFont);
480 RenderText("6", 6, fSymbolFont);
481 RenderText("5", 5, fSymbolFont);
482 RenderText(Form("%dx%d", scaleX, scaleZ), -1, fTextFont, 2*fTextSize);
486 glTranslatef(fTextSize, 0, 0);
487 RenderText("SPD ", 8, fTextFont);
488 RenderText("SDD ", 9, fTextFont);
489 RenderText("SSD ", 10, fTextFont);
490 fTextFont.PostRender();
494 //______________________________________________________________________________
495 void AliEveITSModuleStepper::RenderModuleIDs()
497 // Render module-ids.
500 UInt_t idx = fPosition;
501 Float_t llx, lly, llz, urx, ury, urz;
502 fModuleFont.PreRender();
503 TGLUtil::Color(kWhite);
504 for (List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
506 if (idx < fModuleIDs.size())
508 AliEveITSScaledModule* mod = dynamic_cast<AliEveITSScaledModule*>(*childit);
509 TEveTrans& tr = mod->RefMainTrans();
511 x += fStepper->GetDx()*0.5;
512 y -= fStepper->GetDy()*0.5;
513 z += 0.4; // !!! MT hack - cross check with overlay rendering.
514 const char* txt = Form("%d",mod->GetID());
515 fModuleFont.BBox(txt, llx, lly, llz, urx, ury, urz);
516 glRasterPos3f(x, y, z);
517 glBitmap(0, 0, 0, 0,-urx, 0, 0);
518 fModuleFont.Render(txt);
522 fModuleFont.PostRender();
525 /******************************************************************************/
527 void AliEveITSModuleStepper::Render(TGLRnrCtx& rnrCtx)
529 // Render the overlay elements.
531 AliEveITSScaledModule* sm = dynamic_cast<AliEveITSScaledModule*>(*BeginChildren());
532 Int_t scale = fScaleInfo->GetScale() - 1;
533 Int_t cnx = 0, cnz = 0;
534 switch(sm->GetSubDetID())
537 cnx = fDigitsInfo->fSPDScaleX[scale], cnz = fDigitsInfo->fSPDScaleZ[scale];
540 cnx = fDigitsInfo->fSDDScaleX[scale], cnz = fDigitsInfo->fSDDScaleZ[scale];
543 cnx = fDigitsInfo->fSSDScale[scale], cnz = 1;
548 if (fTextFont.GetMode() == TGLFont::kUndef)
550 fTextFont = rnrCtx.GetFont(fTextSize, 4, TGLFont::kTexture);
551 fSymbolFont = rnrCtx.GetFont(72, 31, TGLFont::kTexture);
552 fModuleFont = rnrCtx.GetFont(14, 4, TGLFont::kPixmap);
557 glMatrixMode(GL_PROJECTION);
560 if (rnrCtx.Selection())
562 TGLRect rect(*rnrCtx.GetPickRectangle());
563 rnrCtx.GetCamera()->WindowToViewport(rect);
564 gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
565 (Int_t*) rnrCtx.GetCamera()->RefViewport().CArr());
567 glMatrixMode(GL_MODELVIEW);
570 glTranslatef(-1, -1, 0); // translate to lower left corner
571 Float_t scale = fMenuHeight/fTextSize*0.5; // scale text
572 glScalef(scale, scale, 1.);
576 RenderMenu(GetCurrentPage(), GetPages(), cnx, cnz);
579 Double_t ls = 1.6*scale*fTextSize;
580 fAxis->SetLabelsSize(ls);
581 fAxis->SetLabelsOffset(ls*1.2);
582 RenderPalette(sm->GetPalette());
585 glMatrixMode(GL_PROJECTION);
587 glMatrixMode(GL_MODELVIEW);