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 <TEveGLText.h>
18 #include <TEveTrans.h>
23 #include <TBuffer3D.h>
24 #include <TBuffer3DTypes.h>
25 #include <TVirtualPad.h>
26 #include <TVirtualViewer3D.h>
28 #include <TGLRnrCtx.h>
29 #include <TGLSelectRecord.h>
31 // #include <FTFont.h>
33 #include <TGLViewer.h>
36 //______________________________________________________________________________
38 // Display scaled ITS modules in a paged layout, also providing
39 // GL-overaly control GUI.
42 ClassImp(AliEveITSModuleStepper)
44 AliEveITSModuleStepper::AliEveITSModuleStepper(AliEveITSDigitsInfo* di) :
45 TEveElementList("ITS 2DStore", "AliEveITSModuleStepper", kTRUE),
78 // override member from base TEveElementList
79 fChildClass = AliEveITSScaledModule::Class();
81 SetMainColorPtr(&fWCol);
83 fDigitsInfo->IncRefCount();
85 fStepper = new TEveGridStepper();
86 fStepper->SetNs(5, 4);
88 fScaleInfo = new AliEveDigitScaleInfo();
89 fScaleInfo->IncRefCount();
91 fAxis = new TGLAxis();
92 fAxis->SetLineColor(4);
93 fAxis->SetTextColor(fFontCol);
95 fText = new TGLText();
96 fText->SetTextColor(fFontCol);
97 fText->SetGLTextFont(40);
98 fText->SetGLTextAngles(0, 0, 0);
99 fText->SetTextSize(fTextSize);
101 gEve->GetGLViewer()->AddOverlayElement(this);
104 AliEveITSModuleStepper::~AliEveITSModuleStepper()
108 gEve->GetGLViewer()->RemoveOverlayElement(this);
110 fScaleInfo->DecRefCount();
111 fDigitsInfo->DecRefCount();
119 /******************************************************************************/
121 void AliEveITSModuleStepper::Capacity()
123 // Make sure we have just enough children (module representations)
124 // to store as many modules as required by the grid-stepper
127 Int_t N = fStepper->GetNx()*fStepper->GetNy();
128 if (N != GetNChildren())
131 for (Int_t m=0; m<N; m++)
133 AddElement(new AliEveITSScaledModule(m, fDigitsInfo, fScaleInfo));
138 /******************************************************************************/
140 void AliEveITSModuleStepper::SetFirst(Int_t first)
142 Int_t lastpage = fIDs.size()/Nxy();
143 if(fIDs.size() % Nxy() ) lastpage++;
145 Int_t firstLastpage = (lastpage - 1)*Nxy();
146 if(first > firstLastpage) first = firstLastpage;
147 if(first < 0) first = 0;
152 void AliEveITSModuleStepper::Start()
160 void AliEveITSModuleStepper::Next()
164 SetFirst(fPosition + Nxy());
167 void AliEveITSModuleStepper::Previous()
169 // Go to previous page.
171 SetFirst(fPosition - Nxy());
174 void AliEveITSModuleStepper::End()
178 Int_t lastpage = fIDs.size()/Nxy();
179 if (fIDs.size() % Nxy()) lastpage++;
180 fPosition = (lastpage - 1)*Nxy();
186 /******************************************************************************/
188 void AliEveITSModuleStepper::DisplayDet(Int_t det, Int_t layer)
190 // Select modules to display by sub-det type / layer.
194 AliEveITSModuleSelection sel = AliEveITSModuleSelection();
197 fDigitsInfo->GetModuleIDs(&sel, fIDs);
198 //in reder menu define a space between left and right pager
199 fPagerGap = 1.2*TextLength(Form("%d/%d",GetPages(), GetPages()));
203 /******************************************************************************/
205 void AliEveITSModuleStepper::DisplayTheta(Float_t min, Float_t max)
207 // Select modules to display by theta range.
210 AliEveITSModuleSelection sel = AliEveITSModuleSelection();
211 sel.SetThetaRange(min, max);
212 fDigitsInfo->GetModuleIDs(&sel, fIDs);
216 /******************************************************************************/
218 Int_t AliEveITSModuleStepper::GetCurrentPage()
220 // Get number of current page.
222 Int_t idx = fPosition + 1;
224 if (idx % Nxy()) n++;
228 /******************************************************************************/
230 Int_t AliEveITSModuleStepper::GetPages()
232 // Get number of all pages.
234 Int_t n = fIDs.size()/Nxy();
235 if(fIDs.size() % Nxy()) n++;
239 /******************************************************************************/
241 void AliEveITSModuleStepper::Apply()
243 // Apply current settings to children modules.
245 // printf("AliEveITSModuleStepper::Apply fPosition %d \n", fPosition);
246 gEve->DisableRedraw();
249 UInt_t idx = fPosition;
250 for(List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
252 if(idx < fIDs.size())
254 AliEveITSScaledModule* mod = dynamic_cast<AliEveITSScaledModule*>(*childit);
255 mod->SetID(fIDs[idx], kFALSE);
256 TEveTrans& tr = mod->RefHMTrans();
258 tr.RotateLF(3,2,TMath::PiOver2());
259 tr.RotateLF(1,3,TMath::PiOver2());
263 Float_t* fp = mod->GetFrame()->GetFramePoints();
264 // switch x,z it will be rotated afterwards
269 Double_t sx = fStepper->GetDx();
270 Double_t sy = (mx*fStepper->GetDx())/mz;
271 if(sy > fStepper->GetDy())
273 // printf("fit width \n");
274 sy = fStepper->GetDy();
275 sx = (mz*fStepper->GetDx())/mx;
277 Float_t scale = (fExpandCell*sx)/mz;
278 tr.Scale(scale, scale, scale);
281 fStepper->GetPosition(p);
282 tr.SetPos(p[0]+0.5*fStepper->GetDx(), p[1]+0.5*fStepper->GetDy(), p[2]+0.5*fStepper->GetDz());
284 if(mod->GetSubDetID() == 2)
285 mod->SetName(Form("SSD %d", idx));
286 else if(mod->GetSubDetID() == 1)
287 mod->SetName(Form("SDD %d", idx));
289 mod->SetName(Form("SPD %d", idx));
290 mod->SetRnrSelf(kTRUE);
297 (*childit)->SetRnrSelf(kFALSE);
303 gEve->EnableRedraw();
306 /******************************************************************************/
308 void AliEveITSModuleStepper::Render(TGLRnrCtx& rnrCtx)
310 // Render the overlay elements.
312 // render everyting in relative coordinates
313 glMatrixMode(GL_PROJECTION);
316 if (rnrCtx.Selection())
319 // glLoadMatrix(rnrCtx.GetCamera()->GetProjMBase());
320 TGLRect rect(*rnrCtx.GetPickRectangle());
321 rnrCtx.GetCamera()->WindowToViewport(rect);
322 gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
323 (Int_t*) rnrCtx.GetCamera()->RefViewport().CArr());
326 glMatrixMode(GL_MODELVIEW);
331 glGetBooleanv(GL_LIGHTING, &lightp);
332 if (lightp) glDisable(GL_LIGHTING);
334 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
335 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
336 glDisable(GL_CULL_FACE);
338 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
340 RenderPalette(fPaletteLength, 1.6*fWWidth, fWHeight*0.6);
344 if (lightp) glEnable(GL_LIGHTING);
346 glMatrixMode(GL_PROJECTION);
349 glMatrixMode(GL_MODELVIEW);
354 /******************************************************************************/
355 // Protected sub-renderers
356 /******************************************************************************/
358 //______________________________________________________________________________
359 Float_t AliEveITSModuleStepper::TextLength(const char* txt)
361 // Calculate length of text txt.
363 Float_t llx, lly, llz, urx, ury, urz;
364 fText->BBox(txt, llx, lly, llz, urx, ury, urz);
365 return (urx-llx)*fTextSize;
368 //______________________________________________________________________________
369 void AliEveITSModuleStepper::RenderString(TString string, Int_t id)
371 // Render text for button id.
373 Float_t txtY = fWHeight*0.5;
374 Float_t txtl = TextLength(string.Data());
376 if(id > 0) glLoadName(id);
377 if(id>0 && fWActive == id)
378 fText->SetTextColor(fWActiveCol);
380 fText->SetTextColor(fFontCol);
386 fText->SetTextColor(fWActiveCol);
388 fText->SetTextColor(fFontCol);
391 Float_t ss = fWWidth*0.4;
392 fText->PaintGLText(ss, txtY, -0.8, string.Data());
394 Float_t bw =2*ss+txtl;
395 RenderFrame(bw,fWHeight*2,id);
396 glTranslatef( bw, 0, 0);
400 fText->SetTextColor(fFontCol);
401 fText->PaintGLText(0, txtY, -0.8, string.Data());
402 glTranslatef(txtl, 0, 0);
406 //______________________________________________________________________________
407 void AliEveITSModuleStepper::RenderFrame(Float_t dx, Float_t dy, Int_t id)
409 // Render frame for button id, taking into account if it is currently
412 if (fRnrFrame == kFALSE)return;
414 glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
415 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
418 TEveUtil::TEveUtil::ColorFromIdx(fWActiveCol, color);
420 TEveUtil:: TEveUtil::ColorFromIdx(fWCol, color);
424 glVertex2f(0, 0); glVertex2f(dx, 0);
425 glVertex2f(dx, dy); glVertex2f(0, dy);
430 //______________________________________________________________________________
431 void AliEveITSModuleStepper::RenderSymbol(Float_t dx, Float_t dy, Int_t id)
433 // Render an overlay / GUI symbol, based on button id:
434 // 1 ~ <, 2 ~ <<, 3 ~ >, 4 ~ >>, 5 ~ ^, 6 ~ v.
440 TEveUtil::TEveUtil::ColorFromIdx(fWActiveCol, color);
442 TEveUtil::TEveUtil::ColorFromIdx(fWCol, color);
445 Float_t xs = dx/4, ys = dy/4;
448 glVertex2f(0,ys); glVertex2f(0, ys*3);
449 glVertex2f(dx, ys*3); glVertex2f(dx, ys);
454 glBegin(GL_TRIANGLES);
459 // glVertex2f(xs*2.5, ys*3); glVertex2f(xs*1.5, ys*2); glVertex2f(xs*2.5, ys);
460 glVertex2f(xs*3, ys*3); glVertex2f(xs*1, ys*2); glVertex2f(xs*3, ys);
466 glVertex2f(xs*2, ys*3); glVertex2f(xs, ys*2); glVertex2f(xs*2, ys);
467 glVertex2f(xs*3, ys*3); glVertex2f(xs*2, ys*2); glVertex2f(xs*3, ys);
473 //glVertex2f(xs*1.5, ys); glVertex2f(xs*2.5, ys*2); glVertex2f(xs*1.5, ys*3);
474 glVertex2f(xs*1, ys); glVertex2f(xs*3, ys*2); glVertex2f(xs*1, ys*3);
480 glVertex2f(xs, ys); glVertex2f(xs*2, ys*2); glVertex2f(xs, ys*3);
481 glVertex2f(xs*2, ys); glVertex2f(xs*3, ys*2); glVertex2f(xs*2, ys*3);
487 glVertex2f(xs, ys*2.5); glVertex2f(xs*2, ys*3.5); glVertex2f(xs*3, ys*2.5);
493 glVertex2f(xs, ys*1.5); glVertex2f(xs*2, ys*0.5); glVertex2f(xs*3, ys*1.5);
504 //______________________________________________________________________________
505 void AliEveITSModuleStepper::RenderPalette(Float_t dx, Float_t x, Float_t y)
507 // Render color palette with number axis.
511 glTranslatef(1 -x- dx, -1+y*4, 0);
512 AliEveITSModule* qs = dynamic_cast<AliEveITSModule*>(*BeginChildren());
513 TEveRGBAPalette* p = qs->GetPalette();
514 glBegin(GL_QUAD_STRIP);
515 glColor4ubv(p->ColorFromValue(p->GetMinVal()));
518 if (p->GetMaxVal() > p->GetMinVal() + 1)
520 Float_t xs = dx/(p->GetMaxVal() - p->GetMinVal());
522 for(Int_t i=p->GetMinVal() + 1; i<p->GetMaxVal(); i++)
524 glColor4ubv(p->ColorFromValue(i));
530 glColor4ubv(p->ColorFromValue(p->GetMaxVal()));
535 if (p->GetMaxVal() > p->GetMinVal())
537 glRotatef(-90,1, 0, 0 );
538 Double_t v1[3] = {0., 0., 0.};
539 Double_t v2[3] = {dx, 0, 0.};
540 fAxis->SetLabelsSize(fTextSize/dx);
541 fAxis->PaintGLAxis(v1, v2, p->GetMinVal(), p->GetMaxVal(), 206);
546 //______________________________________________________________________________
547 void AliEveITSModuleStepper::RenderMenu()
549 // Render menu: page control, scale control, detector type buttons.
551 Float_t ww = 2*fWWidth;
552 Float_t wh = 2*fWHeight;
556 glColor4f(a, a, a, a);
557 Float_t H = 1.9*wh*(1+ 2*fWOff);
560 glVertex3f(-1, -1, 0.1); glVertex3f(-1, -1+H, 0.1);
561 glVertex3f(1 , -1+H, 0.1); glVertex3f( 1, -1 , 0.1);
565 Float_t y_base = -1 + wh*0.35;
566 glTranslatef(-1, y_base, 0.);
570 glTranslatef(ww, 0, 0.);
571 fText->SetTextSize(fTextSize);
572 Float_t soff = ww*1.3;
573 glTranslatef(0, fWOff*wh, 0);
574 RenderSymbol(ww, wh, 2);
575 RenderFrame(ww,wh,2);
576 glTranslatef(soff, 0, 0);
577 RenderSymbol(ww, wh, 1);
578 RenderFrame(ww,wh,1);
579 glTranslatef(soff, 0, 0);
582 const char* txt = Form("%d/%d ", GetCurrentPage(), GetPages());
583 Float_t dx = (fPagerGap - TextLength(txt))*0.5;
584 fText->SetTextColor(fFontCol);
585 fText->PaintGLText(dx, wh*0.25, -0.8, txt);
587 glTranslatef(fPagerGap, 0, 0);
589 RenderSymbol(ww, wh, 3);
590 RenderFrame(ww,wh,3);
591 glTranslatef(soff, 0, 0);
592 RenderSymbol(ww, wh, 4);
593 RenderFrame(ww,wh,4);
594 glTranslatef(2*ww, 0, 0);
599 AliEveITSDigitsInfo* di = fDigitsInfo;
600 Int_t scale = fScaleInfo->GetScale() - 1;
601 AliEveITSScaledModule* sm = dynamic_cast<AliEveITSScaledModule*>(*BeginChildren());
602 Int_t cnx = 0, cnz = 0;
603 switch(sm->GetSubDetID())
606 cnx = di->fSPDScaleX[scale], cnz = di->fSPDScaleZ[scale];
609 cnx = di->fSDDScaleX[scale], cnz = di->fSDDScaleZ[scale];
612 cnx = di->fSSDScale[scale], cnz = 1;
615 glTranslatef(10*ww,0, 0);
616 RenderString(Form("Zoom: "));
618 glTranslatef(0, 0.2*wh, 0);
619 RenderSymbol(ww, wh*0.9, 5);
620 glTranslatef(0, 0.4*wh, 0);
621 RenderFrame(ww, wh*0.5, 5);
623 RenderSymbol(ww, wh*0.9, 6);
624 RenderFrame(ww, wh*0.5, 6);
625 glTranslatef(ww, 0, 0);
626 RenderString(Form("%dx%d ", cnx, cnz));
631 glTranslatef(18*ww, 0, 0);
633 RenderString("SPD", 8);
634 glTranslatef(bs, 0, 0);
635 RenderString("SDD", 9);
636 glTranslatef(bs, 0, 0);
637 RenderString("SSD", 10);
643 //______________________________________________________________________________
644 void AliEveITSModuleStepper::RenderCellIDs()
646 // Render module-ids under their cells.
648 fText->SetTextSize(fStepper->GetDy()*0.1);
649 fText->SetTextColor(fFontCol);
652 UInt_t idx = fPosition;
653 for (List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
655 if(idx < fIDs.size())
657 AliEveITSScaledModule* mod = dynamic_cast<AliEveITSScaledModule*>(*childit);
658 TEveTrans& tr = mod->RefHMTrans();
659 TString name = Form("%d",mod->GetID());
661 x += fStepper->GetDx()*0.5;
662 y -= fStepper->GetDy()*0.5;
663 z += 0.4; // !!! MT hack - cross check with overlay rendering.
664 Float_t llx, lly, llz, urx, ury, urz;
665 fText->BBox(name, llx, lly, llz, urx, ury, urz);
666 tr.GetScale(sx, sy, sz);
667 fText->PaintGLText(x-(urx-llx)*sx, y, z, name);
674 /******************************************************************************/
675 // Virtual event handlers from TGLOverlayElement
676 /******************************************************************************/
678 //______________________________________________________________________________
679 Bool_t AliEveITSModuleStepper::Handle(TGLRnrCtx & /*rnrCtx*/,
680 TGLOvlSelectRecord & rec,
683 // Handle overlay event.
684 // Return TRUE if event was handled.
686 switch (event->fType)
690 Int_t item = rec.GetN() < 2 ? -1 : (Int_t)rec.GetItem(1);
691 if (fWActive != item) {
701 if (event->fCode != kButton1) {
704 switch (rec.GetItem(1))
720 AliEveDigitScaleInfo* si = fScaleInfo;
721 if(si->GetScale() < 5)
723 si->ScaleChanged(si->GetScale() + 1);
724 ElementChanged(kTRUE, kTRUE);
730 AliEveDigitScaleInfo* si = fScaleInfo;
731 if(si->GetScale() > 1)
733 si->ScaleChanged(si->GetScale() - 1);
734 ElementChanged(kTRUE, kTRUE);
739 gEve->GetEditor()->DisplayElement(*BeginChildren());
763 //______________________________________________________________________________
764 Bool_t AliEveITSModuleStepper::MouseEnter(TGLOvlSelectRecord& /*rec*/)
766 // Mouse has entered overlay area.
771 //______________________________________________________________________________
772 void AliEveITSModuleStepper::MouseLeave()
774 // Mouse has left overlay area.