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