]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Reve/DigitSet.cxx
720e99abe13592a91381a5b3b7f3f7530d8b2ae6
[u/mrichter/AliRoot.git] / EVE / Reve / DigitSet.cxx
1 // $Header$
2
3 #include "DigitSet.h"
4
5 #include "ReveManager.h"
6
7 #include <TColor.h>
8
9 #include <TBuffer3D.h>
10 #include <TBuffer3DTypes.h>
11 #include <TVirtualPad.h>
12 #include <TVirtualViewer3D.h>
13
14 using namespace Reve;
15
16 //______________________________________________________________________________
17 // DigitSet
18 //
19 // Base-class for displaying a digit collection.
20 // Provdies common services for:
21 // - specifying signal / color per digit
22 // - specifying object reference per digit
23 // - controlling palette and thresholds (external object RGBAPalette)
24 // - showing a frame around the digits (external object FrameBox)
25 // - specifying transformation matrix for the whole collection
26 //   by data-member of class ZTrans.
27 //
28 // See also:
29 //   QuadSet: rectangle, hexagon or line per digit
30 //   BoxSet   a 3D box per digit
31
32 ClassImp(DigitSet)
33
34 //______________________________________________________________________________
35 DigitSet::DigitSet(const Text_t* n, const Text_t* t) :
36   RenderElement   (),
37   TNamed          (n, t),
38
39   fDefaultValue   (kMinInt),
40   fValueIsColor   (kFALSE),
41   fOwnIds         (kFALSE),
42   fPlex           (),
43   fLastDigit      (0),
44
45   fFrame          (0),
46   fPalette        (0),
47   fRenderMode     (RM_Fill),
48   fDisableLigting (kTRUE),
49   fEmitSignals    (kFALSE),
50   fHistoButtons   (kTRUE),
51   fHMTrans        ()
52 {
53   // Constructor.
54 }
55
56 //______________________________________________________________________________
57 DigitSet::~DigitSet()
58 {
59   // Destructor.
60   // Unreference frame and palette. Destroy referenced objects if they
61   // are owned by the DigitSet.
62
63   SetFrame(0);
64   SetPalette(0);
65   if (fOwnIds)
66     ReleaseIds();
67 }
68
69 /******************************************************************************/
70
71 //______________________________________________________________________________
72 DigitSet::DigitBase* DigitSet::NewDigit()
73 {
74   // Protected method called whenever a new digit is added.
75
76   fLastDigit = new (fPlex.NewAtom()) DigitBase(fDefaultValue);
77   return fLastDigit;
78 }
79
80 //______________________________________________________________________________
81 void DigitSet::ReleaseIds()
82 {
83   // Protected method. Release and delete the referenced objects, the
84   // ownership is *NOT* checked.
85
86   VoidCPlex::iterator qi(fPlex);
87   while (qi.next()) {
88     DigitBase& q = * (DigitBase*) qi();
89     if (q.fId.GetObject()) {
90       delete q.fId.GetObject();
91       q.fId = 0;
92     }
93   }
94 }
95
96 /******************************************************************************/
97 /******************************************************************************/
98
99 //______________________________________________________________________________
100 void DigitSet::SetMainColor(Color_t color)
101 {
102   // Override from RenderElement, forward to Frame.
103
104   if (fFrame) {
105     fFrame->SetFrameColor(color);
106     fFrame->UpdateBackPtrItems();
107   }
108   gReve->Redraw3D();
109 }
110
111 /******************************************************************************/
112 /******************************************************************************/
113
114 //______________________________________________________________________________
115 void DigitSet::RefitPlex()
116 {
117   // Instruct underlying memory allocator to regroup itself into a
118   // contiguous memory chunk.
119
120   fPlex.Refit();
121 }
122
123 /******************************************************************************/
124
125 //______________________________________________________________________________
126 void DigitSet::ScanMinMaxValues(Int_t& min, Int_t& max)
127 {
128   // Iterate over the digits and detmine min and max signal values.
129
130   if (fValueIsColor || fPlex.Size() == 0) return;
131   min = kMaxInt;
132   max = kMinInt;
133   for (Int_t c=0; c<fPlex.VecSize(); ++c)
134   {
135     Char_t* a = fPlex.Chunk(c);
136     Int_t   n = fPlex.NAtoms(c);
137     while (n--)
138     {
139       Int_t v = ((DigitBase*)a)->fValue;
140       if (v < min) min = v;
141       if (v > max) max = v;
142       a += fPlex.S();
143     }
144   }
145   if (min == max)
146     --min;
147 }
148
149 /******************************************************************************/
150
151 //______________________________________________________________________________
152 void DigitSet::DigitValue(Int_t value)
153 {
154   // Set signal value for the last digit added.
155
156   fLastDigit->fValue = value;
157 }
158
159 //______________________________________________________________________________
160 void DigitSet::DigitColor(Color_t ci)
161 {
162   // Set color for the last digit added.
163
164   ColorFromIdx(ci, (UChar_t*) & fLastDigit->fValue, kTRUE);
165 }
166
167 //______________________________________________________________________________
168 void DigitSet::DigitColor(UChar_t r, UChar_t g, UChar_t b, UChar_t a)
169 {
170   // Set color for the last digit added.
171
172   UChar_t* x = (UChar_t*) & fLastDigit->fValue;
173   x[0] = r; x[1] = g; x[2] = b; x[3] = a;
174 }
175
176 //______________________________________________________________________________
177 void DigitSet::DigitColor(UChar_t* rgba)
178 {
179   // Set color for the last digit added.
180
181   UChar_t* x = (UChar_t*) & fLastDigit->fValue;
182   x[0] = rgba[0]; x[1] = rgba[1]; x[2] = rgba[2]; x[3] = rgba[3];
183 }
184
185 //______________________________________________________________________________
186 void DigitSet::DigitId(TObject* id)
187 {
188   // Set external object reference for the last digit added.
189
190   fLastDigit->fId = id;
191 }
192
193 /******************************************************************************/
194 /******************************************************************************/
195
196 //______________________________________________________________________________
197 void DigitSet::Paint(Option_t* /*option*/)
198 {
199   // Paint this object. Only direct rendering is supported.
200
201   static const Exc_t eH("DigitSet::Paint ");
202
203   TBuffer3D buff(TBuffer3DTypes::kGeneric);
204
205   // Section kCore
206   buff.fID           = this;
207   buff.fColor        = fFrame ? fFrame->GetFrameColor() : 1;
208   buff.fTransparency = 0;
209   fHMTrans.SetBuffer3D(buff);
210   buff.SetSectionsValid(TBuffer3D::kCore);
211
212   Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
213   if (reqSections != TBuffer3D::kNone)
214     Error(eH, "only direct GL rendering supported.");
215 }
216
217 //______________________________________________________________________________
218 void DigitSet::DigitSelected(Int_t idx)
219 {
220   // Called from renderer when a digit with index idx is selected.
221
222   if (fEmitSignals) {
223     CtrlClicked(this, idx);
224   } else {
225     DigitBase* qb = GetDigit(idx);
226     TObject* obj = qb->fId.GetObject();
227     printf("DigitSet::DigitSelected idx=%d, value=%d, obj=0x%lx\n",
228            idx, qb->fValue, (ULong_t)obj);
229     if (obj)
230       obj->Print();
231   }
232 }
233
234 //______________________________________________________________________________
235 void DigitSet::CtrlClicked(DigitSet* qs, Int_t idx)
236 {
237   // Emit a CtrlClicked signal.
238
239   Long_t args[2];
240   args[0] = (Long_t) qs;
241   args[1] = (Long_t) idx;
242
243   Emit("CtrlClicked(Reve::DigitSet*, Int_t)", args);
244 }
245
246 /******************************************************************************/
247 // Getters / Setters for Frame, RGBAPalette, ZTrans
248 /******************************************************************************/
249
250 //______________________________________________________________________________
251 void DigitSet::SetFrame(FrameBox* b)
252 {
253   // Set FrameBox pointer.
254
255   if (fFrame == b) return;
256   if (fFrame) fFrame->DecRefCount(this);
257   fFrame = b;
258   if (fFrame) {
259     fFrame->IncRefCount(this);
260     SetMainColorPtr(fFrame->PtrFrameColor());
261   } else {
262     SetMainColorPtr(0);
263   }
264 }
265
266 //______________________________________________________________________________
267 void DigitSet::SetPalette(RGBAPalette* p)
268 {
269   // Set RGBAPalette pointer.
270
271   if (fPalette == p) return;
272   if (fPalette) fPalette->DecRefCount();
273   fPalette = p;
274   if (fPalette) fPalette->IncRefCount();
275 }
276
277 //______________________________________________________________________________
278 RGBAPalette* DigitSet::AssertPalette()
279 {
280   // Make sure the RGBAPalette pointer is not null.
281   // If it is not set, a new one is instantiated and the range is set
282   // to current min/max signal values.
283
284   if (fPalette == 0) {
285     fPalette = new RGBAPalette;
286     if (!fValueIsColor) {
287       Int_t min, max;
288       ScanMinMaxValues(min, max);
289       fPalette->SetLimits(min, max);
290       fPalette->SetMinMax(min, max);
291     }
292   }
293   return fPalette;
294 }