]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveDet/AliEveITSModuleStepper.cxx
Coverity
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveITSModuleStepper.cxx
1 // $Id$
2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
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  **************************************************************************/
9
10 #include "AliEveITSModuleStepper.h"
11 #include "AliEveITSDigitsInfo.h"
12 #include "AliEveITSScaledModule.h"
13
14 #include <TEveManager.h>
15 #include <TEveGedEditor.h>
16 #include <TEveGridStepper.h>
17 #include <TEveTrans.h>
18
19 #include <TGLRnrCtx.h>
20 #include <TGLIncludes.h>
21 #include <TGLSelectRecord.h>
22 #include <TGLUtil.h>
23 #include <TGLViewer.h>
24 #include <TGLAxis.h>
25
26 #include <TMath.h>
27 #include <THLimitsFinder.h>
28 #include <TVirtualPad.h>
29
30 #include <RVersion.h>
31
32 //______________________________________________________________________________
33 //
34 // Display scaled ITS modules in a paged layout, also providing
35 // GL-overaly control GUI.
36
37
38 ClassImp(AliEveITSModuleStepper)
39
40 AliEveITSModuleStepper::AliEveITSModuleStepper(AliEveITSDigitsInfo* di) :
41   TEveElementList("ITS 2DStore", "AliEveITSModuleStepper", kTRUE),
42
43   fDigitsInfo(di),
44   fScaleInfo(0),
45   fStepper(0),
46
47   fModuleIDs(),
48   fPosition(0),
49   fSubDet(-1),
50
51   fModuleFont(), fTextFont(), fSymbolFont(),
52   fAxis(0),
53
54   fMenuHeight(0.13),
55   fTextSize(64),
56   fTextCol(kGray+1),
57   fActiveCol(kRed-4),
58
59   fActiveID(-1)
60 {
61   // Constructor.
62
63   SetMainColorPtr(&fTextCol);
64   fAxis = new TGLAxis();
65
66   // override member from base TEveElementList
67   fChildClass = AliEveITSScaledModule::Class();
68
69   fDigitsInfo->IncRefCount();
70
71   fStepper = new TEveGridStepper();
72   fStepper->SetNs(5, 4);
73
74   fScaleInfo = new AliEveDigitScaleInfo();
75   fScaleInfo->IncRefCount();
76
77   gEve->GetDefaultGLViewer()->AddOverlayElement(this);
78 }
79
80 AliEveITSModuleStepper::~AliEveITSModuleStepper()
81 {
82   // Destructor.
83
84   gEve->GetDefaultGLViewer()->RemoveOverlayElement(this);
85
86   fScaleInfo->DecRefCount();
87   fDigitsInfo->DecRefCount();
88
89   delete fStepper;
90   delete fAxis;
91 }
92
93 /******************************************************************************/
94
95 void AliEveITSModuleStepper::Capacity()
96 {
97   // Make sure we have just enough children (module representations)
98   // to store as many modules as required by the grid-stepper
99   // configuration.
100
101   Int_t n = fStepper->GetNx()*fStepper->GetNy();
102   if (n != NumChildren())
103   {
104     DestroyElements();
105     for (Int_t m=0; m<n; ++m)
106     {
107       AddElement(new AliEveITSScaledModule(m, fDigitsInfo, fScaleInfo));
108     }
109   }
110 }
111
112 /******************************************************************************/
113
114 void AliEveITSModuleStepper::SetFirst(Int_t first)
115 {
116   // Se module ID which apply to first item in stepper.
117
118   Int_t lastpage = fModuleIDs.size()/Nxy();
119   if (fModuleIDs.size() % Nxy() ) lastpage++;
120
121   Int_t firstLastpage = (lastpage - 1)*Nxy();
122   if (first > firstLastpage) first = firstLastpage;
123   if (first < 0) first = 0;
124   fPosition = first;
125   Apply();
126 }
127
128 void AliEveITSModuleStepper::Start()
129 {
130   // Go to first page.
131
132   fPosition = 0;
133   Apply();
134 }
135
136 void AliEveITSModuleStepper::Next()
137 {
138   // Go to next page.
139
140   SetFirst(fPosition + Nxy());
141 }
142
143 void AliEveITSModuleStepper::Previous()
144 {
145   // Go to previous page.
146
147   SetFirst(fPosition - Nxy());
148 }
149
150 void AliEveITSModuleStepper::End()
151 {
152   // Go to last page.
153
154   Int_t lastpage = fModuleIDs.size()/Nxy();
155   if (fModuleIDs.size() % Nxy()) lastpage++;
156   fPosition = (lastpage - 1)*Nxy();
157
158   fStepper->Reset();
159   Apply();
160 }
161
162 /******************************************************************************/
163
164 void AliEveITSModuleStepper::DisplayDet(Int_t det, Int_t layer)
165 {
166   // Select modules to display by sub-det type / layer.
167
168   fSubDet = det;
169   fModuleIDs.clear();
170   AliEveITSModuleSelection sel = AliEveITSModuleSelection();
171   sel.SetType (det);
172   sel.SetLayer(layer);
173   fDigitsInfo->GetModuleIDs(&sel, fModuleIDs);
174   //in reder menu define a space between left and right pager
175   Start();
176 }
177
178 /******************************************************************************/
179
180 Int_t AliEveITSModuleStepper::GetCurrentPage() const
181 {
182   // Get number of current page.
183
184   Int_t idx = fPosition + 1;
185   Int_t n   = idx/Nxy();
186   if (idx % Nxy()) n++;
187   return n;
188 }
189
190 /******************************************************************************/
191
192 Int_t AliEveITSModuleStepper::GetPages()
193 {
194   // Get number of all pages.
195
196   Int_t n = fModuleIDs.size()/Nxy();
197   if (fModuleIDs.size() % Nxy()) n++;
198   return n;
199 }
200
201 /******************************************************************************/
202
203 void  AliEveITSModuleStepper::Apply()
204 {
205   // Apply current settings to children modules.
206
207   gEve->DisableRedraw();
208   Capacity();
209
210   UInt_t idx = fPosition;
211   for(List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
212   {
213     if (idx < fModuleIDs.size())
214     {
215       AliEveITSScaledModule* mod = dynamic_cast<AliEveITSScaledModule*>(*childit);
216       mod->SetID(fModuleIDs[idx], kFALSE);
217       TEveTrans& tr = mod->RefMainTrans();
218       tr.UnitTrans();
219       tr.RotateLF(3,2,TMath::PiOver2());
220       tr.RotateLF(1,3,TMath::PiOver2());
221
222       // scaling
223       Float_t mz, mx;
224       Float_t* fp = mod->GetFrame()->GetFramePoints();
225       // switch x,z it will be rotated afterwards
226       mx = -2*fp[0];
227       mz = -2*fp[2];
228
229       // fit width first
230       Double_t sx = fStepper->GetDx();
231       Double_t sy = (mx*fStepper->GetDx())/mz;
232       if (sy > fStepper->GetDy())
233       {
234         sy =  fStepper->GetDy();
235         sx =  (mz*fStepper->GetDx())/mx;
236       }
237       Float_t scale = (0.85*sx)/mz;
238       tr.Scale(scale, scale, scale);
239
240       Float_t  p[3];
241       fStepper->GetPosition(p);
242       tr.SetPos(p[0]+0.5*fStepper->GetDx(), p[1]+0.5*fStepper->GetDy(), p[2]+0.5*fStepper->GetDz());
243
244       if (mod->GetSubDetID() == 2)
245         mod->SetName(Form("SSD %d", idx));
246       else if (mod->GetSubDetID() == 1)
247         mod->SetName(Form("SDD %d", idx));
248       else
249         mod->SetName(Form("SPD %d", idx));
250       mod->SetRnrSelf(kTRUE);
251
252       fStepper->Step();
253       idx++;
254     }
255     else {
256       (*childit)->SetRnrSelf(kFALSE);
257     }
258   }
259
260   fStepper->Reset();
261   ElementChanged();
262   gEve->EnableRedraw();
263 }
264
265
266 /******************************************************************************/
267 // Virtual event handlers from TGLOverlayElement
268 /******************************************************************************/
269
270 //______________________________________________________________________________
271 Bool_t AliEveITSModuleStepper::Handle(TGLRnrCtx          & /*rnrCtx*/,
272                                       TGLOvlSelectRecord & rec,
273                                       Event_t            * event)
274 {
275   // Handle overlay event.
276   // Return TRUE if event was handled.
277
278   switch (event->fType)
279   {
280     case kMotionNotify:
281     {
282       Int_t item = rec.GetN() < 2 ? -1 : (Int_t)rec.GetItem(1);
283       if (fActiveID != item) {
284         fActiveID = item;
285         return kTRUE;
286       } else {
287         return kFALSE;
288       }
289       break;
290     }
291     case kButtonPress:
292     {
293       if (event->fCode != kButton1) {
294         return kFALSE;
295       }
296       switch (rec.GetItem(1))
297       {
298         case 1:
299           Previous();
300           break;
301         case 2:
302           Start();
303           break;
304         case 3:
305           Next();
306           break;
307         case 4:
308           End();
309           break;
310         case 5:
311         {
312           AliEveDigitScaleInfo* si = fScaleInfo;
313           if (si->GetScale() < 5)
314           {
315             si->ScaleChanged(si->GetScale() + 1);
316             ElementChanged(kTRUE, kTRUE);
317           }
318           break;
319         }
320         case 6:
321         {
322           AliEveDigitScaleInfo* si = fScaleInfo;
323           if (si->GetScale() > 1)
324           {
325             si->ScaleChanged(si->GetScale() - 1);
326             ElementChanged(kTRUE, kTRUE);
327           }
328           break;
329         }
330         case 7:
331           gEve->GetEditor()->DisplayElement(*BeginChildren());
332           break;
333
334         case 8:
335           DisplayDet(0, -1);
336           break;
337         case 9:
338           DisplayDet(1, -1);
339           break;
340         case 10:
341           DisplayDet(2, -1);
342           break;
343         default:
344           break;
345       }
346       return kTRUE;
347       break;
348     }
349     default:
350       break;
351   } // end switch
352   return kFALSE;
353 }
354
355 //______________________________________________________________________________
356 Bool_t AliEveITSModuleStepper::MouseEnter(TGLOvlSelectRecord& /*rec*/)
357 {
358   // Mouse has entered overlay area.
359
360   return kTRUE;
361 }
362
363 //______________________________________________________________________________
364 void AliEveITSModuleStepper::MouseLeave()
365 {
366   // Mouse has left overlay area.
367
368   fActiveID = -1;
369 }
370
371
372 /******************************************************************************/
373 // Protected sub-renderers
374 /******************************************************************************/
375
376 //______________________________________________________________________________
377 void AliEveITSModuleStepper::RenderText(const char* txt, Int_t id, const TGLFont &font, Float_t step)
378 {
379   // Render text for button id.
380
381   Float_t llx, lly, llz, urx, ury, urz;
382   font.BBox(txt, llx, lly, llz, urx, ury, urz);
383   (fActiveID == id && id > 0) ? TGLUtil::Color(fActiveCol) :TGLUtil::Color(fTextCol);
384
385   if (step > 0)
386   {
387     // center text in the step interval
388     glPushMatrix();
389     if (step>urx)
390     glTranslatef((step-urx+llx)*0.5f-llx, 0, 0);
391     glLoadName(id);
392     font.Render(txt);
393     glPopMatrix();
394     glTranslatef(step, 0, 0);
395   }
396   else 
397   {
398     glLoadName(id);
399     glPushMatrix();
400     font.Render(txt);
401     glPopMatrix();
402     glTranslatef(urx, 0, 0);
403   }
404 }
405
406 //______________________________________________________________________________
407 void AliEveITSModuleStepper::RenderPalette(TEveRGBAPalette* p)
408 {
409   // Render color palette with number axis.
410
411   Float_t length = 7*fTextSize;
412   Float_t x = 1.5*fTextSize;
413   Float_t y = 0.2*fTextSize;
414
415   glTranslatef(x, 0.8*fTextSize, 0);
416
417   TGLCapabilitySwitch lights_off(GL_LIGHTING, kFALSE);
418
419   glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
420   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
421   glDisable(GL_CULL_FACE);
422   glEnable(GL_BLEND);
423   glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
424
425   glBegin(GL_QUAD_STRIP);
426   TGLUtil::Color4ubv(p->ColorFromValue(p->GetMinVal()));
427   glVertex2f(0, 0);
428   glVertex2f(0, y);
429   if (p->GetMaxVal() > p->GetMinVal() + 1)
430   {
431     Float_t xs = length/(p->GetMaxVal() - p->GetMinVal());
432     Float_t x0 = xs;
433     for(Int_t i=p->GetMinVal() + 1; i<p->GetMaxVal(); i++)
434     {
435       TGLUtil::Color4ubv(p->ColorFromValue(i));
436       glVertex2f(x0, 0);
437       glVertex2f(x0, y);
438       x0+=xs;
439     }
440   }
441   TGLUtil::Color4ubv(p->ColorFromValue(p->GetMaxVal()));
442   glVertex2f(length, 0);
443   glVertex2f(length, y);
444   glEnd();
445
446   glRotatef(-90, 1, 0, 0 );
447   Double_t v1[3] = {0., 0., 0.};
448   Double_t v2[3] = {length, 0, 0.};
449   fAxis->SetTextColor(kGray+1);
450   fAxis->SetLineColor(kGray+1);
451   fAxis->PaintGLAxis(v1, v2, p->GetMinVal(), p->GetMaxVal(), 5);
452   glPopAttrib();
453 }
454
455 //______________________________________________________________________________
456 void AliEveITSModuleStepper::RenderMenu(Int_t curP, Int_t maxP, Int_t scaleX, Int_t scaleZ)
457 {
458   // Make UI to set page in stepper and UI to scale in the AliEveITSScaledModule.
459
460   TGLUtil::Color(fTextCol);
461   fTextFont.PreRender();
462   glTranslatef(0, fTextSize*0.3, 0);
463   {
464     // pager
465     glTranslatef(fTextSize*0.2, 0 , 0);
466     RenderText("9", 2, fSymbolFont); // last page
467     RenderText("3", 1, fSymbolFont);//last page
468     RenderText(Form("%d/%d", curP, maxP),-1, fTextFont, 2.7*fTextSize); //status
469     {
470       // bugg in webdings font , bbox does not give realistic value
471       Float_t llx, lly, llz, urx, ury, urz;
472       fSymbolFont.BBox("4", llx, lly, llz, urx, ury, urz);
473       glTranslatef(-llx, 0, 0);
474     }
475     RenderText("4", 3, fSymbolFont); // next page
476     RenderText(":",4, fSymbolFont); // last page
477   }
478   {
479     // scale
480     glTranslatef(fTextSize,0, 0);
481     RenderText(Form("Zoom:"), -1, fTextFont);
482     RenderText("6", 6, fSymbolFont);
483     RenderText("5", 5, fSymbolFont);
484     RenderText(Form("%dx%d", scaleX, scaleZ), -1, fTextFont, 2*fTextSize);
485   }
486   {
487     // detectors
488     glTranslatef(fTextSize, 0, 0);
489     RenderText("SPD ", 8, fTextFont);
490     RenderText("SDD ", 9, fTextFont);
491     RenderText("SSD ", 10, fTextFont);
492     fTextFont.PostRender();
493   }
494 }
495
496 //______________________________________________________________________________
497 void AliEveITSModuleStepper::RenderModuleIDs()
498 {
499   // Render module-ids.
500
501   Double_t x, y, z;
502   UInt_t idx = fPosition;
503   Float_t llx, lly, llz, urx, ury, urz;
504   fModuleFont.PreRender();
505   TGLUtil::Color(kWhite);
506   for (List_i childit=fChildren.begin(); childit!=fChildren.end(); ++childit)
507   {
508     if (idx < fModuleIDs.size())
509     {
510       AliEveITSScaledModule* mod = dynamic_cast<AliEveITSScaledModule*>(*childit);
511       TEveTrans& tr = mod->RefMainTrans();
512       tr.GetPos(x,y,z);
513       x += fStepper->GetDx()*0.5;
514       y -= fStepper->GetDy()*0.5;
515       z += 0.4; // !!! MT hack - cross check with overlay rendering.
516       const char* txt = Form("%d",mod->GetID());
517       fModuleFont.BBox(txt, llx, lly, llz, urx, ury, urz);
518       glRasterPos3f(x, y, z);
519       glBitmap(0, 0, 0, 0,-urx, 0, 0);
520       fModuleFont.Render(txt);
521       idx++;
522     }
523   }
524   fModuleFont.PostRender();
525 }
526
527 /******************************************************************************/
528
529 void AliEveITSModuleStepper::Render(TGLRnrCtx& rnrCtx)
530 {
531   // Render the overlay elements.
532
533   AliEveITSScaledModule* sm = dynamic_cast<AliEveITSScaledModule*>(*BeginChildren());
534   Int_t scaleIdx = fScaleInfo->GetScale() - 1;
535   Int_t cnx = 0, cnz = 0;
536   switch(sm->GetSubDetID())
537   {
538     case 0:
539       cnx = fDigitsInfo->fSPDScaleX[scaleIdx];
540       cnz = fDigitsInfo->fSPDScaleZ[scaleIdx];
541       break;
542     case 1:
543       cnx = fDigitsInfo->fSDDScaleX[scaleIdx];
544       cnz = fDigitsInfo->fSDDScaleZ[scaleIdx];
545       break;
546     case 2:
547       cnx = fDigitsInfo->fSSDScale[scaleIdx];
548       cnz = 1;
549       break;
550   }
551
552   // init fonts
553   if (fTextFont.GetMode() == TGLFont::kUndef)
554   {
555 #if ROOT_VERSION_CODE >= 332547
556     rnrCtx.RegisterFont(fTextSize, 4, TGLFont::kTexture, fTextFont);
557     rnrCtx.RegisterFont(72,       31, TGLFont::kTexture, fSymbolFont);
558     rnrCtx.RegisterFont(14,        4, TGLFont::kPixmap,  fModuleFont);
559 #else
560     fTextFont = rnrCtx.GetFont(fTextSize, 4, TGLFont::kTexture);
561     fSymbolFont =  rnrCtx.GetFont(72, 31, TGLFont::kTexture);
562     fModuleFont =  rnrCtx.GetFont(14, 4, TGLFont::kPixmap);
563 #endif
564   }
565
566   {
567     // toolbar
568     glMatrixMode(GL_PROJECTION);
569     glPushMatrix();
570     glLoadIdentity();
571     if (rnrCtx.Selection())
572     {
573       TGLRect rect(*rnrCtx.GetPickRectangle());
574       rnrCtx.GetCamera()->WindowToViewport(rect);
575       gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(),
576                     (Int_t*) rnrCtx.GetCamera()->RefViewport().CArr());
577     }
578     glMatrixMode(GL_MODELVIEW);
579     glPushMatrix();
580     glLoadIdentity();
581     glTranslatef(-1, -1, 0); // translate to lower left corner
582     Float_t txtScale = fMenuHeight/fTextSize*0.5; // scale text
583     glScalef(txtScale, txtScale, 1.);
584
585     //menu
586     glPushName(0);
587     RenderMenu(GetCurrentPage(), GetPages(), cnx, cnz);
588     glPopName();
589     //palette
590     Double_t labelSize = 1.6*txtScale*fTextSize;
591     fAxis->SetLabelsSize(labelSize);
592     fAxis->SetLabelsOffset(1.2*labelSize);
593     RenderPalette(sm->GetPalette());
594
595     glPopMatrix();
596     glMatrixMode(GL_PROJECTION);
597     glPopMatrix();
598     glMatrixMode(GL_MODELVIEW);
599   }
600   RenderModuleIDs();
601 }