37 ClassImp(TGLAnnotation);
39 Color_t TGLAnnotation::fgBackColor = kAzure + 10;
40 Color_t TGLAnnotation::fgTextColor = kOrange;
44 TGLAnnotation::TGLAnnotation(TGLViewerBase *parent,
const char *text, Float_t posx, Float_t posy) :
45 TGLOverlayElement(TGLOverlayElement::kAnnotation),
47 fPosX(posx), fPosY(posy),
48 fMouseX(0), fMouseY(0),
50 fDrawW(0), fDrawH(0), fTextSizeDrag(0),
52 fMainFrame(0), fTextEdit(0),
58 fTextAlign(TGLFont::kLeft),
59 fBackColor(fgBackColor),
60 fTextColor(fgTextColor),
69 parent->AddOverlayElement(
this);
70 fParent = (TGLViewer*)parent;
75 TGLAnnotation::TGLAnnotation(TGLViewerBase *parent,
const char *text, Float_t posx, Float_t posy, TGLVector3 ref) :
76 TGLOverlayElement(TGLOverlayElement::kAnnotation),
77 fPosX(posx), fPosY(posy),
78 fMouseX(0), fMouseY(0),
80 fDrawW(0), fDrawH(0), fTextSizeDrag(0),
82 fMainFrame(0), fTextEdit(0),
88 fTextAlign(TGLFont::kLeft),
89 fBackColor(fgBackColor),
90 fTextColor(fgTextColor),
100 parent->AddOverlayElement(
this);
101 fParent = (TGLViewer*)parent;
107 TGLAnnotation::~TGLAnnotation()
109 fParent->RemoveOverlayElement(
this);
117 Bool_t TGLAnnotation::Handle(TGLRnrCtx& rnrCtx,
118 TGLOvlSelectRecord& selRec,
121 if (selRec.GetN() < 2)
return kFALSE;
122 Int_t recID = selRec.GetItem(1);
123 switch (event->fType)
129 fDrag = (recID == kResizeID) ? kResize : kMove;
130 fTextSizeDrag = fTextSize;
136 if (recID == kDeleteID)
138 TGLViewer *v = fParent;
140 v->RequestDraw(rnrCtx.ViewerLOD());
142 else if (recID == kEditID)
150 const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
151 if (vp.Width() == 0 || vp.Height() == 0)
return kFALSE;
155 fPosX += (Float_t)(event->fX - fMouseX) / vp.Width();
156 fPosY -= (Float_t)(event->fY - fMouseY) / vp.Height();
162 else if (fPosX + fDrawW > 1.0f)
163 fPosX = 1.0f - fDrawW;
166 else if (fPosY > 1.0f)
169 else if (fDrag == kResize)
171 using namespace TMath;
172 Float_t oovpw = 1.0f / vp.Width(), oovph = 1.0f / vp.Height();
174 Float_t xw = oovpw * Min(Max(0, event->fX), vp.Width());
175 Float_t yw = oovph * Min(Max(0, vp.Height() -
event->fY), vp.Height());
177 Float_t rx = Max((xw - fPosX) / (oovpw * fMouseX - fPosX), 0.0f);
178 Float_t ry = Max((yw - fPosY) / (oovph*(vp.Height() - fMouseY) - fPosY), 0.0f);
180 fTextSize = Max(fTextSizeDrag * Min(rx, ry), 0.01f);
194 Bool_t TGLAnnotation::MouseEnter(TGLOvlSelectRecord& )
203 void TGLAnnotation::MouseLeave()
211 void TGLAnnotation::Render(TGLRnrCtx& rnrCtx)
213 const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
214 if (vp.Width() == 0 && vp.Height() == 0)
217 Float_t old_depth_range[2];
218 glGetFloatv(GL_DEPTH_RANGE, old_depth_range);
219 glDepthRange(0, 0.001);
222 glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
223 TGLCapabilitySwitch lights_off(GL_LIGHTING, kFALSE);
224 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
225 glDisable(GL_CULL_FACE);
227 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
230 Color_t bgCol = fBackColor;
231 Color_t fgCol = fTextColor;
235 fgCol = rnrCtx.ColorSet().Markup().GetColorIndex();
237 TColor* c1 = gROOT->GetColor(rnrCtx.ColorSet().Markup().GetColorIndex());
238 TColor* c2 = gROOT->GetColor(rnrCtx.ColorSet().Background().GetColorIndex());
241 Float_t f1 = 0.5, f2 = 0.5;
242 bgCol = TColor::GetColor(c1->GetRed() *f1 + c2->GetRed() *f2,
243 c1->GetGreen()*f1 + c2->GetGreen()*f2,
244 c1->GetBlue() *f1 + c2->GetBlue() *f2);
249 rnrCtx.ProjectionMatrixPushIdentity();
254 glTranslatef(-1.0f, -1.0f, 0.0f);
255 glScalef(2.0f, 2.0f, 1.0f);
257 glEnable(GL_POLYGON_OFFSET_FILL);
258 glPolygonOffset(0.1f, 1.0f);
262 TGLUtil::LineWidth(1.0f);
265 glTranslatef(fPosX, fPosY, 0.0f);
267 TObjArray *lines = fText.Tokenize(
"\n");
268 TIter line_iter(lines);
271 Float_t widthTxt, heightTxt, sx, sy, descent, line_height;
274 Int_t fs = TGLFontManager::GetFontSize(TMath::Nint(vp.Height()*fTextSize), 12, 64);
275 rnrCtx.RegisterFontNoScale(fs,
"arial", TGLFont::kTexture, fFont);
276 descent = fFont.GetDescent();
277 line_height = fFont.GetLineHeight();
279 Float_t llx, lly, llz, urx, ury, urz;
280 widthTxt = heightTxt = 0;
281 while ((osl = (TObjString*) line_iter()) != 0)
283 fFont.BBox(osl->GetString().Data(), llx, lly, llz, urx, ury, urz);
284 widthTxt = TMath::Max(widthTxt, urx);
285 heightTxt += line_height;
287 widthTxt += 2.0f * descent;
288 heightTxt += 2.0f * descent;
291 sy = fTextSize / (line_height + descent);
292 sx = sy / vp.Aspect();
293 fDrawW = sx*widthTxt;
294 fDrawH = sy*heightTxt;
296 glScalef(sx, sy, 1.0f);
300 Float_t x1, x2, y1, y2;
312 TGLUtil::ColorTransparency(bgCol, fTransparency);
314 glVertex3f(x1, y1, z3);
315 glVertex3f(x2, y1, z3);
316 glVertex3f(x2, y2, z3);
317 glVertex3f(x1, y2, z3);
320 TGLUtil::ColorTransparency(fgCol, GetLineTransparency());
321 glBegin(GL_LINE_LOOP);
322 glVertex3f(x1, y1, z2);
323 glVertex3f(x2, y1, z2);
324 glVertex3f(x2, y2, z2);
325 glVertex3f(x1, y2, z2);
329 TGLUtil::Color(fgCol);
334 while ((osl = (TObjString*) line_iter()) != 0)
336 if (fTextAlign == TGLFont::kLeft) {
339 else if (fTextAlign == TGLFont::kCenterH) {
340 tx = 0.5f * widthTxt - descent ;
343 tx = widthTxt - 2.0f * descent;
345 glTranslatef(0.0f, -line_height, 0.0f);
346 fFont.Render(osl->GetString(), tx+descent, 0, z2, fTextAlign, TGLFont::kTop) ;
358 fFont.BBox(
"X", bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5]);
360 fFont.Render(
"E", descent, descent, z2, fTextAlign, TGLFont::kTop);
361 x2 = bbox[3] + 2.0f * descent;
364 glLoadName(kDeleteID);
365 fFont.Render(
"X", x2 + descent, descent, z2, fTextAlign, TGLFont::kTop);
371 y2 = line_height + descent;
376 TGLUtil::ColorTransparency(bgCol, fTransparency);
378 glVertex3f(x1, y1, z3);
379 glVertex3f(x2, y1, z3);
380 glVertex3f(x2, y2, z3);
381 glVertex3f(x1, y2, z3);
384 TGLUtil::ColorTransparency(fgCol, GetLineTransparency());
385 glBegin(GL_LINE_LOOP);
386 glVertex3f(x1, y1, z0);
387 glVertex3f(x2, y1, z0);
388 glVertex3f(x2, y2, z0);
389 glVertex3f(x1, y2, z0);
397 glLoadName(kDeleteID);
399 TGLUtil::ColorTransparency(bgCol, fTransparency);
401 glVertex3f(x1, y1, z3);
402 glVertex3f(x2, y1, z3);
403 glVertex3f(x2, y2, z3);
404 glVertex3f(x1, y2, z3);
407 TGLUtil::ColorTransparency(fgCol, GetLineTransparency());
408 glBegin(GL_LINE_LOOP);
409 glVertex3f(x1, y1, z0);
410 glVertex3f(x2, y1, z0);
411 glVertex3f(x2, y2, z0);
412 glVertex3f(x1, y2, z0);
417 glLoadName(kResizeID);
419 x1 = widthTxt - line_height;
422 y2 = -heightTxt + line_height;
423 TGLUtil::ColorTransparency(bgCol, fTransparency);
425 glVertex3f(x1, y1, z1);
426 glVertex3f(x2, y1, z1);
427 glVertex3f(x2, y2, z1);
428 glVertex3f(x1, y2, z1);
431 TGLUtil::ColorTransparency(fgCol, GetLineTransparency());
433 Float_t aOff = 0.25*line_height;
434 glVertex3f(x1+aOff, y1+aOff, z0);
435 glVertex3f(x2-aOff, y1+aOff, z0);
436 glVertex3f(x2-aOff, y1+aOff, z0);
437 glVertex3f(x2-aOff, y2-aOff, z0);
448 TGLVertex3 op = rnrCtx.RefCamera().WorldToViewport(fPointer);
449 op[0] /= vp.Width(); op[1] /= vp.Height();
451 Float_t fx = op[0] < fPosX ? 0.0f : (op[0] > fPosX + fDrawW ? 1.0f : 0.5f);
452 Float_t fy = op[1] < fPosY-fDrawH ? 1.0f : (op[1] > fPosY ? 0.0f : 0.5f);
454 if (fx != 0.5f || fy != 0.5f)
456 TGLUtil::ColorTransparency(bgCol, fTransparency);
457 TGLUtil::LineWidth(2);
459 glVertex3f(fPosX + fx*fDrawW, fPosY - fy*fDrawH, z3);
460 glVertex3f(op[0], op[1], z3);
466 rnrCtx.ProjectionMatrixPop();
468 glDepthRange(old_depth_range[0], old_depth_range[1]);
476 Char_t TGLAnnotation::GetLineTransparency()
const
479 return TMath::Min(70, fTransparency);
481 return fTransparency;
487 void TGLAnnotation::MakeEditor()
491 fMainFrame =
new TGMainFrame(gClient->GetRoot(), 1000, 1000);
492 fMainFrame->SetWindowName(
"Annotation Editor");
494 TGVerticalFrame* vf =
new TGVerticalFrame(fMainFrame);
496 fTextEdit =
new TGTextEdit(vf, 1000, 1000, kSunkenFrame);
497 vf->AddFrame(fTextEdit,
new TGLayoutHints(kLHintsExpandX|kLHintsExpandY));
499 TGHorizontalFrame* hf =
new TGHorizontalFrame(vf);
501 TGTextButton* btt1 =
new TGTextButton(hf,
"OK");
502 hf->AddFrame(btt1,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
504 TGTextButton* btt2 =
new TGTextButton(hf,
"Cancel");
505 hf->AddFrame(btt2,
new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
507 btt1->Connect(
"Clicked()",
"TGLAnnotation",
this,
"UpdateText()");
508 btt2->Connect(
"Clicked()",
"TGLAnnotation",
this,
"CloseEditor()");
510 vf->AddFrame(hf,
new TGLayoutHints(kLHintsBottom | kLHintsRight | kLHintsExpandX, 2, 2, 5, 1));
512 fMainFrame->AddFrame(vf,
new TGLayoutHints(kLHintsExpandX|kLHintsExpandY));
513 fMainFrame->SetCleanup(kDeepCleanup);
514 fMainFrame->MapSubwindows();
517 TGText *tgt =
new TGText();
518 tgt->LoadBuffer(fText.Data());
519 fTextEdit->SetText(tgt);
521 Int_t nrow = tgt->RowCount();
523 Int_t w = fTextEdit->ReturnLongestLineWidth();
524 fMainFrame->Resize(TMath::Max(100, w+30), TMath::Max(100, h+40));
526 fMainFrame->Layout();
527 fMainFrame->MapWindow();
533 void TGLAnnotation::CloseEditor()
535 fMainFrame->UnmapWindow();
541 void TGLAnnotation::UpdateText()
543 fText = fTextEdit->GetText()->AsString();
544 fMainFrame->UnmapWindow();
545 fParent->RequestDraw();