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