CMS 3D CMS Logo

CmsAnnotation.cc
Go to the documentation of this file.
1 #include <sstream>
2 
3 #include "TGLIncludes.h"
4 #include "TGLCamera.h"
5 #include "TGLRnrCtx.h"
6 #include "TGLSelectRecord.h"
7 #include "TGLViewerBase.h"
8 #include "TGLViewer.h"
9 #include "TImage.h"
10 #include "TEveManager.h"
11 
15 
16 CmsAnnotation::CmsAnnotation(TGLViewerBase* parent, Float_t posx, Float_t posy)
17  : TGLOverlayElement(TGLOverlayElement::kUser),
18  fPosX(posx),
19  fPosY(posy),
20  fMouseX(0),
21  fMouseY(0),
22  fDrag(kNone),
23  fParent(nullptr),
24  fSize(0.2),
25  fSizeDrag(0.0),
26  fActive(false),
27  fAllowDestroy(false) {
28  // Constructor.
29  // Create annotation as plain text
30 
31  parent->AddOverlayElement(this);
32  fParent = (TGLViewer*)parent;
33 }
34 
36  // Destructor.
37 
38  fParent->RemoveOverlayElement(this);
39 }
40 
41 void CmsAnnotation::Render(TGLRnrCtx& rnrCtx) {
42  if (rnrCtx.GetCamera()->RefViewport().Width() == 0 || rnrCtx.GetCamera()->RefViewport().Height() == 0)
43  return;
44 
45  static UInt_t ttid_black = 0;
46  static UInt_t ttid_white = 0;
47 
48  bool whiteBg = rnrCtx.ColorSet().Background().GetColorIndex() == kWhite;
49  UInt_t& ttid = whiteBg ? ttid_white : ttid_black;
50 
51  if ((whiteBg == false && ttid == 0) || (whiteBg && ttid == 0)) {
52  TImage* imgs[3];
53  TString base = whiteBg ? "White" : "Black";
54  imgs[0] = TImage::Open(FWCheckBoxIcon::coreIcondir() + "CMSLogo" + base + "Bg.png");
55  imgs[1] = TImage::Open(FWCheckBoxIcon::coreIcondir() + "CMSLogo" + base + "BgM.png");
56  imgs[2] = TImage::Open(FWCheckBoxIcon::coreIcondir() + "CMSLogo" + base + "BgS.png");
57 
58  glGenTextures(1, &ttid);
59  glBindTexture(GL_TEXTURE_2D, ttid);
60 
61  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
62  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
63  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
64  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
65  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
66  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
67 
68  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
69  glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
70 
71  for (int i = 0; i < 3; i++)
72  glTexImage2D(GL_TEXTURE_2D,
73  i,
74  GL_RGBA,
75  imgs[i]->GetWidth(),
76  imgs[i]->GetHeight(),
77  0,
78  GL_BGRA,
79  GL_UNSIGNED_BYTE,
80  imgs[i]->GetArgbArray());
81 
82  glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
83 
84  for (int i = 0; i < 3; i++)
85  delete imgs[i];
86  }
87 
88  glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
89  TGLCapabilitySwitch lights_off(GL_LIGHTING, kFALSE);
90 
91  // reset matrix
92  glMatrixMode(GL_PROJECTION);
93  glPushMatrix();
94  glLoadIdentity();
95 
96  if (rnrCtx.Selection()) {
97  TGLRect rect(*rnrCtx.GetPickRectangle());
98  rnrCtx.GetCamera()->WindowToViewport(rect);
99  gluPickMatrix(rect.X(), rect.Y(), rect.Width(), rect.Height(), (Int_t*)rnrCtx.GetCamera()->RefViewport().CArr());
100  }
101  const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
102  glOrtho(vp.X(), vp.Width(), vp.Y(), vp.Height(), 0, 1);
103  glMatrixMode(GL_MODELVIEW);
104  glPushMatrix();
105  glLoadIdentity();
106 
107  // move to pos
108  Float_t posX = vp.Width() * fPosX;
109  Float_t posY = vp.Height() * fPosY;
110  glTranslatef(posX, posY, -0.99);
111 
112  glDisable(GL_DEPTH_TEST);
113  glEnable(GL_BLEND);
114  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
115 
116  glEnable(GL_TEXTURE_2D);
117  glBindTexture(GL_TEXTURE_2D, ttid);
118 
119  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
120 
121  // logo
122  glPushName(kMove);
123  TGLUtil::Color(rnrCtx.ColorSet().Background().GetColorIndex());
124  glBegin(GL_QUADS);
125  Float_t z = 0.9;
126  Float_t a = fSize * vp.Height();
127  glTexCoord2f(0, 1);
128  glVertex3f(0, -a, z);
129  glTexCoord2f(1, 1);
130  glVertex3f(a, -a, z);
131  glTexCoord2f(1, 0);
132  glVertex3f(a, 0, z);
133  glTexCoord2f(0, 0);
134  glVertex3f(0, 0, z);
135  glEnd();
136  glPopName();
137 
138  glDisable(GL_TEXTURE_2D);
139 
140  if (fActive) {
141  // resize button
142  glPushMatrix();
143  glBegin(GL_QUADS);
144  Float_t a = fSize * vp.Height();
145  TGLUtil::ColorTransparency(rnrCtx.ColorSet().Markup().GetColorIndex(), 95);
146  glTexCoord2f(0, 1);
147  glVertex3f(0, -a, z);
148  glTexCoord2f(1, 1);
149  glVertex3f(a, -a, z);
150  glTexCoord2f(1, 0);
151  glVertex3f(a, 0, z);
152  glTexCoord2f(0, 0);
153  glVertex3f(0, 0, z);
154  glEnd();
155 
156  glTranslatef(a, -a, 0);
157  a *= 0.2;
158  z = 0.95;
159  glPushName(kResize);
160  TGLUtil::ColorTransparency(rnrCtx.ColorSet().Markup().GetColorIndex(), 100);
161  glBegin(GL_QUADS);
162  glVertex3f(0, 0, z);
163  glVertex3f(0, a, z);
164  glVertex3f(-a, a, z);
165  glVertex3f(-a, 0, z);
166  glEnd();
167  {
168  glTranslatef(-a / 3, a / 3, 0);
169  glBegin(GL_LINES);
170  TGLUtil::ColorTransparency(rnrCtx.ColorSet().Markup().GetColorIndex(), 40);
171  Float_t s = a / 3;
172  glVertex3f(0, 0, z);
173  glVertex3f(0, s, z);
174  glVertex3f(0, 0, z);
175  glVertex3f(-s, 0, z);
176  glEnd();
177  }
178  glPopName();
179  glPopMatrix();
180 
181  // delete
182  if (fAllowDestroy) {
183  glPushName(7);
184  TGLUtil::ColorTransparency(rnrCtx.ColorSet().Markup().GetColorIndex(), 100);
185  glTranslatef(0, -a, 0);
186  glBegin(GL_QUADS);
187  glVertex3f(0, 0, z);
188  glVertex3f(a, 0, z);
189  glVertex3f(a, a, z);
190  glVertex3f(0, a, z);
191  glEnd();
192  {
193  glBegin(GL_LINES);
194  TGLUtil::ColorTransparency(rnrCtx.ColorSet().Markup().GetColorIndex(), 40);
195  Float_t s = a / 3;
196  glVertex3f(s, s, z);
197  glVertex3f(a - s, a - s, z);
198  glVertex3f(s, a - s, z);
199  glVertex3f(a - s, s, z);
200  glEnd();
201  }
202  glPopName();
203  }
204  }
205 
206  glEnable(GL_DEPTH_TEST);
207  glMatrixMode(GL_PROJECTION);
208  glPopMatrix();
209  glMatrixMode(GL_MODELVIEW);
210  glPopMatrix();
211 
212  glPopAttrib();
213 }
214 
215 Bool_t CmsAnnotation::Handle(TGLRnrCtx& rnrCtx, TGLOvlSelectRecord& selRec, Event_t* event) {
216  // Handle overlay event.
217  // Return TRUE if event was handled.
218 
219  if (selRec.GetN() < 2)
220  return kFALSE;
221  int recID = selRec.GetItem(1);
222 
223  switch (event->fType) {
224  case kButtonPress: {
225  fMouseX = event->fX;
226  fMouseY = event->fY;
227  fDrag = (recID == kResize) ? kResize : kMove;
228  fSizeDrag = fSize;
229  return kTRUE;
230  }
231  case kButtonRelease: {
232  fDrag = kNone;
233  if (recID == 7) {
234  fParent->RequestDraw(rnrCtx.ViewerLOD());
235  delete this;
236  return kTRUE;
237  }
238  break;
239  }
240  case kMotionNotify: {
241  const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
242  if (vp.Width() == 0 || vp.Height() == 0)
243  return false;
244  if (fDrag != kNone) {
245  if (fDrag == kMove) {
246  fPosX += (Float_t)(event->fX - fMouseX) / vp.Width();
247  fPosY -= (Float_t)(event->fY - fMouseY) / vp.Height();
248  fMouseX = event->fX;
249  fMouseY = event->fY;
250 
251  Float_t h = fSize;
252  Float_t w = fSize / vp.Aspect();
253 
254  // Make sure we don't go offscreen (use fDraw variables set in draw)
255  if (fPosX < 0)
256  fPosX = 0;
257  else if (fPosX + w > 1.0f)
258  fPosX = 1.0f - w;
259  if (fPosY < h)
260  fPosY = h;
261  else if (fPosY > 1.0f)
262  fPosY = 1.0f;
263  } else {
264  using namespace TMath;
265  Float_t oovpw = 1.0f / vp.Width(), oovph = 1.0f / vp.Height();
266 
267  Float_t xw = oovpw * Min(Max(0, event->fX), vp.Width());
268  Float_t yw = oovph * Min(Max(0, vp.Height() - event->fY), vp.Height());
269 
270  Float_t rx = Max((xw - fPosX) / (oovpw * fMouseX - fPosX), 0.0f);
271  Float_t ry = Max((yw - fPosY) / (oovph * (vp.Height() - fMouseY) - fPosY), 0.0f);
272 
273  fSize = Max(fSizeDrag * Min(rx, ry), 0.01f);
274  }
275  }
276  return kTRUE;
277  }
278  default: {
279  return kFALSE;
280  }
281  }
282 
283  return false;
284 }
285 
286 //______________________________________________________________________________
287 Bool_t CmsAnnotation::MouseEnter(TGLOvlSelectRecord& /*rec*/) {
288  // Mouse has entered overlay area.
289 
290  fActive = kTRUE;
291  return kTRUE;
292 }
293 
294 //______________________________________________________________________
296  // Mouse has left overlay area.
297 
298  fActive = kFALSE;
299 }
300 
301 //______________________________________________________________________
302 bool CmsAnnotation::getVisible() const { return GetState() == TGLOverlayElement::kActive; }
303 
304 //______________________________________________________________________
306  SetState(x ? (TGLOverlayElement::kActive) : (TGLOverlayElement::kInvisible));
307  fParent->Changed();
308  gEve->Redraw3D();
309 }
310 
311 //______________________________________________________________________________
312 
314  std::stringstream s;
315  s << fSize;
316  iTo.addKeyValue("LogoSize", FWConfiguration(s.str()));
317 
318  std::stringstream x;
319  x << fPosX;
320  iTo.addKeyValue("LogoPosX", FWConfiguration(x.str()));
321 
322  std::stringstream y;
323  y << fPosY;
324  iTo.addKeyValue("LogoPosY", FWConfiguration(y.str()));
325 }
326 
328  const FWConfiguration* value;
329  value = iFrom.valueForKey("LogoSize");
330  if (value)
331  fSize = atof(value->value().c_str());
332 
333  value = iFrom.valueForKey("LogoPosX");
334  if (value)
335  fPosX = atof(value->value().c_str());
336 
337  value = iFrom.valueForKey("LogoPosY");
338  if (value)
339  fPosY = atof(value->value().c_str());
340 }
static const TString & coreIcondir()
virtual void addTo(FWConfiguration &) const
T w() const
virtual void setFrom(const FWConfiguration &)
bool getVisible() const
Bool_t MouseEnter(TGLOvlSelectRecord &selRec) override
void Render(TGLRnrCtx &rnrCtx) override
double f[11][100]
TGLViewer * fParent
Definition: CmsAnnotation.h:49
~CmsAnnotation() override
Definition: value.py:1
CmsAnnotation(TGLViewerBase *parent, Float_t posx, Float_t posy)
EDrag fDrag
last mouse position
Definition: CmsAnnotation.h:47
FWConfiguration & addKeyValue(const std::string &, const FWConfiguration &)
Bool_t Handle(TGLRnrCtx &rnrCtx, TGLOvlSelectRecord &selRec, Event_t *event) override
void MouseLeave() override
const FWConfiguration * valueForKey(const std::string &iKey) const
double a
Definition: hdecay.h:121
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
void setVisible(bool x)
Definition: event.py:1
Float_t fSizeDrag
relative size to viewport width
Definition: CmsAnnotation.h:52