Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGLAnnotation.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Matevz and Alja Tadel 20/02/2009
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TGLAnnotation.h"
13
14#include "TGLIncludes.h"
15#include "TROOT.h"
16#include "TColor.h"
17#include "TGLUtil.h"
18#include "TGLCamera.h"
19#include "TGLRnrCtx.h"
20#include "TGLSelectRecord.h"
21#include "TGLViewerBase.h"
22#include "TObjString.h"
23#include "TGTextEdit.h"
24#include "TGButton.h"
25#include "TGLViewer.h"
26
27#include "TMath.h"
28
29#include <KeySymbols.h>
30
31/** \class TGLAnnotation
32\ingroup opengl
33GL-overlay annotation.
34*/
35
36
39
40////////////////////////////////////////////////////////////////////////////////
41
44
45 fPosX(posx), fPosY(posy),
46 fMouseX(0), fMouseY(0),
47 fDrag(kNone),
48 fDrawW(0), fDrawH(0), fTextSizeDrag(0),
49 fActive(kFALSE),
50 fMainFrame(nullptr), fTextEdit(nullptr),
51
52 fParent(nullptr),
53
54 fText(text),
55 fTextSize(0.03),
56 fTextAlign(TGLFont::kLeft),
57 fBackColor(fgBackColor),
58 fTextColor(fgTextColor),
59 fTransparency(100),
60 fDrawRefLine(kFALSE),
61 fUseColorSet(kTRUE),
62 fAllowClose(kTRUE)
63{
64 // Constructor.
65 // Create annotation as plain text
66
67 parent->AddOverlayElement(this);
68 fParent = (TGLViewer*)parent;
69}
70
71////////////////////////////////////////////////////////////////////////////////
72
75 fPosX(posx), fPosY(posy),
76 fMouseX(0), fMouseY(0),
77 fDrag(kNone),
78 fDrawW(0), fDrawH(0), fTextSizeDrag(0),
79 fActive(kFALSE),
80 fMainFrame(nullptr), fTextEdit(nullptr),
81
82 fParent(nullptr),
83
84 fText(text),
85 fTextSize(0.03),
86 fTextAlign(TGLFont::kLeft),
87 fBackColor(fgBackColor),
88 fTextColor(fgTextColor),
89 fTransparency(40),
90 fDrawRefLine(kTRUE),
91 fUseColorSet(kTRUE),
92 fAllowClose(kTRUE)
93{
94 // Constructor.
95 // Create annotation by picking an object.
96
97 fPointer = ref;
98 parent->AddOverlayElement(this);
99 fParent = (TGLViewer*)parent;
100}
101
102////////////////////////////////////////////////////////////////////////////////
103/// Destructor.
104
110
111////////////////////////////////////////////////////////////////////////////////
112/// Handle overlay event.
113/// Return TRUE if event was handled.
114
117 Event_t* event)
118{
119 if (selRec.GetN() < 2) return kFALSE;
120 Int_t recID = selRec.GetItem(1);
121 switch (event->fType)
122 {
123 case kButtonPress:
124 {
125 fMouseX = event->fX;
126 fMouseY = event->fY;
127 fDrag = (recID == kResizeID) ? kResize : kMove;
129 return kTRUE;
130 }
131 case kButtonRelease:
132 {
133 fDrag = kNone;
134 if (recID == kDeleteID)
135 {
137 delete this;
138 v->RequestDraw(rnrCtx.ViewerLOD());
139 }
140 else if (recID == kEditID)
141 {
142 MakeEditor();
143 }
144 return kTRUE;
145 }
146 case kMotionNotify:
147 {
148 const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
149 if (vp.Width() == 0 || vp.Height() == 0) return kFALSE;
150
151 if (fDrag == kMove)
152 {
153 fPosX += (Float_t)(event->fX - fMouseX) / vp.Width();
154 fPosY -= (Float_t)(event->fY - fMouseY) / vp.Height();
155 fMouseX = event->fX;
156 fMouseY = event->fY;
157 // Make sure we don't go offscreen (use fDraw variables set in draw)
158 if (fPosX < 0)
159 fPosX = 0;
160 else if (fPosX + fDrawW > 1.0f)
161 fPosX = 1.0f - fDrawW;
162 if (fPosY < fDrawH)
163 fPosY = fDrawH;
164 else if (fPosY > 1.0f)
165 fPosY = 1.0f;
166 }
167 else if (fDrag == kResize)
168 {
169 using namespace TMath;
170 Float_t oovpw = 1.0f / vp.Width(), oovph = 1.0f / vp.Height();
171
172 Float_t xw = oovpw * Min(Max(0, event->fX), vp.Width());
173 Float_t yw = oovph * Min(Max(0, vp.Height() - event->fY), vp.Height());
174
175 Float_t rx = Max((xw - fPosX) / (oovpw * fMouseX - fPosX), 0.0f);
176 Float_t ry = Max((yw - fPosY) / (oovph*(vp.Height() - fMouseY) - fPosY), 0.0f);
177
178 fTextSize = Max(fTextSizeDrag * Min(rx, ry), 0.01f);
179 }
180 return kTRUE;
181 }
182 default:
183 {
184 return kFALSE;
185 }
186 }
187}
188
189////////////////////////////////////////////////////////////////////////////////
190/// Mouse has entered overlay area.
191
197
198////////////////////////////////////////////////////////////////////////////////
199/// Mouse has left overlay area.
200
205
206////////////////////////////////////////////////////////////////////////////////
207/// Render the annotation.
208
210{
211 const TGLRect& vp = rnrCtx.RefCamera().RefViewport();
212 if (vp.Width() == 0 && vp.Height() == 0)
213 return;
214
217 glDepthRange(0, 0.001);
218
219
226
227 // prepare colors
230
231 if (fUseColorSet)
232 {
233 fgCol = rnrCtx.ColorSet().Markup().GetColorIndex();
234
235 TColor* c1 = gROOT->GetColor(rnrCtx.ColorSet().Markup().GetColorIndex());
236 TColor* c2 = gROOT->GetColor(rnrCtx.ColorSet().Background().GetColorIndex());
237
238 if (c1 && c2) {
239 Float_t f1 = 0.5, f2 = 0.5;
240 bgCol = TColor::GetColor(c1->GetRed() *f1 + c2->GetRed() *f2,
241 c1->GetGreen()*f1 + c2->GetGreen()*f2,
242 c1->GetBlue() *f1 + c2->GetBlue() *f2);
243 }
244 }
245
246 // reset matrix
247 rnrCtx.ProjectionMatrixPushIdentity();
248
249 glPushMatrix();
250 // set ortho camera to [0,1] [0.1]
252 glTranslatef(-1.0f, -1.0f, 0.0f);
253 glScalef(2.0f, 2.0f, 1.0f);
254
256 glPolygonOffset(0.1f, 1.0f);
257
258 glPushMatrix();
259
260 TGLUtil::LineWidth(1.0f);
261
262 // move to pos
263 glTranslatef(fPosX, fPosY, 0.0f);
264
265 TObjArray *lines = fText.Tokenize("\n");
268
270 {
271 // get unscaled text size
273 rnrCtx.RegisterFontNoScale(fs, "arial", TGLFont::kTexture, fFont);
276
277 Float_t llx, lly, llz, urx, ury, urz;
278 widthTxt = heightTxt = 0;
279 while ((osl = (TObjString*) line_iter()) != nullptr)
280 {
281 fFont.BBox(osl->GetString().Data(), llx, lly, llz, urx, ury, urz);
284 }
285 widthTxt += 2.0f * descent;
286 heightTxt += 2.0f * descent;
287
288 // keep proportions
290 sx = sy / vp.Aspect();
293 }
294 glScalef(sx, sy, 1.0f);
295
297
298 Float_t x1, x2, y1, y2;
299 Float_t z3 = 0.0f; // main background
300 Float_t z2 = -0.01f; // outlines and text
301 Float_t z1 = -0.02f; // button on top of text
302 Float_t z0 = -0.03f; // button on top of text
303
304 // main background
306 x1 = 0.0f;
307 x2 = widthTxt;
308 y1 = -heightTxt;
309 y2 = 0.0f;
312 glVertex3f(x1, y1, z3);
313 glVertex3f(x2, y1, z3);
314 glVertex3f(x2, y2, z3);
315 glVertex3f(x1, y2, z3);
316 glEnd();
317 // main polygon outline
319 glBegin(GL_LINE_LOOP);
320 glVertex3f(x1, y1, z2);
321 glVertex3f(x2, y1, z2);
322 glVertex3f(x2, y2, z2);
323 glVertex3f(x1, y2, z2);
324 glEnd();
325
326 // annotation text
329 glPushMatrix();
330 Float_t tx = 0;
331 line_iter.Reset();
332 while ((osl = (TObjString*) line_iter()) != nullptr)
333 {
334 if (fTextAlign == TGLFont::kLeft) {
335 tx = 0;
336 }
337 else if (fTextAlign == TGLFont::kCenterH) {
338 tx = 0.5f * widthTxt - descent ;
339 }
340 else {
341 tx = widthTxt - 2.0f * descent;
342 }
343 glTranslatef(0.0f, -line_height, 0.0f);
344 fFont.Render(osl->GetString(), tx+descent, 0, z2, fTextAlign, TGLFont::kTop) ;
345 }
346 glPopMatrix();
348
349 delete lines;
350
351 // buttons
352 if (fActive)
353 {
354 Float_t bbox[6];
356 fFont.BBox("X", bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5]);
359 x2 = bbox[3] + 2.0f * descent;
360 if (fAllowClose)
361 {
364 }
366
367 x1 = 0.0f;
368 y1 = 0.0f;
370 {
371 // edit button
373 // polygon
376 glVertex3f(x1, y1, z3);
377 glVertex3f(x2, y1, z3);
378 glVertex3f(x2, y2, z3);
379 glVertex3f(x1, y2, z3);
380 glEnd();
381 // outline
383 glBegin(GL_LINE_LOOP);
384 glVertex3f(x1, y1, z0);
385 glVertex3f(x2, y1, z0);
386 glVertex3f(x2, y2, z0);
387 glVertex3f(x1, y2, z0);
388 glEnd();
389 }
390 x1 += x2;
391 x2 += x2;
392 if (fAllowClose)
393 {
394 // close button
396 // polygon
399 glVertex3f(x1, y1, z3);
400 glVertex3f(x2, y1, z3);
401 glVertex3f(x2, y2, z3);
402 glVertex3f(x1, y2, z3);
403 glEnd();
404 // outline
406 glBegin(GL_LINE_LOOP);
407 glVertex3f(x1, y1, z0);
408 glVertex3f(x2, y1, z0);
409 glVertex3f(x2, y2, z0);
410 glVertex3f(x1, y2, z0);
411 glEnd();
412 }
413 {
414 // resize button
416 // polygon
418 x2 = widthTxt;
419 y1 = -heightTxt;
423 glVertex3f(x1, y1, z1);
424 glVertex3f(x2, y1, z1);
425 glVertex3f(x2, y2, z1);
426 glVertex3f(x1, y2, z1);
427 glEnd();
428 // draw resize corner lines
430 glBegin(GL_LINES);
431 Float_t aOff = 0.25*line_height;
432 glVertex3f(x1+aOff, y1+aOff, z0);
433 glVertex3f(x2-aOff, y1+aOff, z0);
434 glVertex3f(x2-aOff, y1+aOff, z0);
435 glVertex3f(x2-aOff, y2-aOff, z0);
436 glEnd();
437 }
438 }
439
440 glPopName();
441
442 glPopMatrix();
443
444 if (fDrawRefLine)
445 {
446 TGLVertex3 op = rnrCtx.RefCamera().WorldToViewport(fPointer);
447 op[0] /= vp.Width(); op[1] /= vp.Height();
448
449 Float_t fx = op[0] < fPosX ? 0.0f : (op[0] > fPosX + fDrawW ? 1.0f : 0.5f);
450 Float_t fy = op[1] < fPosY-fDrawH ? 1.0f : (op[1] > fPosY ? 0.0f : 0.5f);
451
452 if (fx != 0.5f || fy != 0.5f)
453 {
456 glBegin(GL_LINES);
458 glVertex3f(op[0], op[1], z3);
459 glEnd();
460 }
461 }
462
463 glPopMatrix();
464 rnrCtx.ProjectionMatrixPop();
465
467 glPopAttrib();
468}
469
470////////////////////////////////////////////////////////////////////////////////
471/// Returns transparency of annotation outline.
472/// If annotation is selected enforce visibility of outline.
473
475{
476 if (fActive)
477 return TMath::Min(70, fTransparency);
478 else
479 return fTransparency;
480}
481
482////////////////////////////////////////////////////////////////////////////////
483/// Show the annotation editor.
484
486{
487 if (fMainFrame == nullptr)
488 {
489 fMainFrame = new TGMainFrame(gClient->GetRoot(), 1000, 1000);
490 fMainFrame->SetWindowName("Annotation Editor");
491
493
494 fTextEdit = new TGTextEdit(vf, 1000, 1000, kSunkenFrame);
496
498
499 TGTextButton* btt1 = new TGTextButton(hf, "OK");
500 hf->AddFrame(btt1, new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
501
502 TGTextButton* btt2 = new TGTextButton(hf, "Cancel");
503 hf->AddFrame(btt2, new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
504
505 btt1->Connect("Clicked()", "TGLAnnotation", this, "UpdateText()");
506 btt2->Connect("Clicked()", "TGLAnnotation", this, "CloseEditor()");
507
508 vf->AddFrame(hf, new TGLayoutHints(kLHintsBottom | kLHintsRight | kLHintsExpandX, 2, 2, 5, 1));
509
513 }
514
515 TGText *tgt = new TGText();
516 tgt->LoadBuffer(fText.Data());
518
519 Int_t nrow = tgt->RowCount();
520 Int_t h = nrow*20;
522 fMainFrame->Resize(TMath::Max(100, w+30), TMath::Max(100, h+40));
523
526}
527
528////////////////////////////////////////////////////////////////////////////////
529/// Close the annotation editor.
530
535
536////////////////////////////////////////////////////////////////////////////////
537/// Modify the annotation text from the text-edit widget.
538
@ kButtonRelease
Definition GuiTypes.h:60
@ kButtonPress
Definition GuiTypes.h:60
@ kMotionNotify
Definition GuiTypes.h:61
@ kSunkenFrame
Definition GuiTypes.h:383
const Handle_t kNone
Definition GuiTypes.h:88
#define h(i)
Definition RSha256.hxx:106
short Color_t
Color number (short)
Definition RtypesCore.h:99
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
@ kOrange
Definition Rtypes.h:68
@ kAzure
Definition Rtypes.h:68
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gClient
Definition TGClient.h:157
@ kDeepCleanup
Definition TGFrame.h:42
@ kLHintsRight
Definition TGLayout.h:26
@ kLHintsExpandY
Definition TGLayout.h:31
@ kLHintsBottom
Definition TGLayout.h:29
@ kLHintsExpandX
Definition TGLayout.h:30
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize fs
Option_t Option_t TPoint TPoint const char text
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:411
The color creation and management class.
Definition TColor.h:22
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1926
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
Add frame to the composite frame using the specified layout hints.
Definition TGFrame.cxx:1109
void MapSubwindows() override
Map all sub windows that are part of the composite frame.
Definition TGFrame.cxx:1156
void Layout() override
Layout the elements of the composite frame.
Definition TGFrame.cxx:1249
void SetCleanup(Int_t mode=kLocalCleanup) override
Turn on automatic cleanup of child frames in dtor.
Definition TGFrame.cxx:1064
void Resize(UInt_t w=0, UInt_t h=0) override
Resize the frame.
Definition TGFrame.cxx:597
void MapWindow() override
map window
Definition TGFrame.h:206
void UnmapWindow() override
unmap window
Definition TGFrame.h:208
A composite frame that layout their children in horizontal way.
Definition TGFrame.h:387
static Color_t fgBackColor
TGLAnnotation(const TGLAnnotation &)=delete
Bool_t MouseEnter(TGLOvlSelectRecord &selRec) override
Mouse has entered overlay area.
Bool_t Handle(TGLRnrCtx &rnrCtx, TGLOvlSelectRecord &selRec, Event_t *event) override
Handle overlay event.
static Color_t fgTextColor
TGMainFrame * fMainFrame
Float_t fTextSize
Bool_t fDrawRefLine
void MakeEditor()
Show the annotation editor.
void UpdateText()
Modify the annotation text from the text-edit widget.
Color_t fTextColor
TGTextEdit * fTextEdit
TGLViewer * fParent
void CloseEditor()
Close the annotation editor.
TGLFont::ETextAlignH_e fTextAlign
Char_t GetLineTransparency() const
Returns transparency of annotation outline.
~TGLAnnotation() override
Destructor.
void MouseLeave() override
Mouse has left overlay area.
Bool_t fUseColorSet
EDrag fDrag
last mouse position
void Render(TGLRnrCtx &rnrCtx) override
Render the annotation.
Float_t fTextSizeDrag
width and height when drawing
Char_t fTransparency
Color_t fBackColor
TGLVector3 fPointer
text-size at start of drag
static Int_t GetFontSize(Int_t ds)
Get availabe font size.
A wrapper class for FTFont.
Float_t GetDescent() const
Get font's descent. The returned value is positive.
Float_t GetLineHeight() const
Get font's line-height.
void BBox(const char *txt, Float_t &llx, Float_t &lly, Float_t &llz, Float_t &urx, Float_t &ury, Float_t &urz) const
Get bounding box.
void Render(const char *txt, Double_t x, Double_t y, Double_t angle, Double_t mgn) const
virtual void PostRender() const
Reset GL state after FTFont rendering.
virtual void PreRender(Bool_t autoLight=kTRUE, Bool_t lightOn=kFALSE) const
Set-up GL state before FTFont rendering.
An overlay element.
Definition TGLOverlay.h:23
Selection record for overlay objects.
Viewport (pixel base) 2D rectangle class.
Definition TGLUtil.h:422
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
Definition TGLRnrCtx.h:41
static void ColorTransparency(Color_t color_index, Char_t transparency=0)
Set color from color_index and ROOT-style transparency (default 0).
Definition TGLUtil.cxx:1732
static void Color(const TGLColor &color)
Set color from TGLColor.
Definition TGLUtil.cxx:1688
static Float_t LineWidth()
Get the line-width, taking the global scaling into account.
Definition TGLUtil.cxx:1934
3 component (x/y/z) vector class.
Definition TGLUtil.h:248
3 component (x/y/z) vertex class.
Definition TGLUtil.h:84
Base class for GL viewers.
virtual void AddOverlayElement(TGLOverlayElement *el)
Add overlay element.
Base GL viewer object - used by both standalone and embedded (in pad) GL.
Definition TGLViewer.h:55
void RequestDraw(Short_t LOD=TGLRnrCtx::kLODMed)
Post request for redraw of viewer at level of detail 'LOD' Request is directed via cross thread gVirt...
void RemoveOverlayElement(TGLOverlayElement *el) override
Remove overlay element.
This class describes layout hints used by the layout classes.
Definition TGLayout.h:50
Defines top level windows that interact with the system Window Manager.
Definition TGFrame.h:399
void SetWindowName(const char *name=nullptr) override
Set window name. This is typically done via the window manager.
Definition TGFrame.cxx:1780
Yield an action as soon as it is clicked.
Definition TGButton.h:142
A TGTextEdit is a specialization of TGTextView.
Definition TGTextEdit.h:22
Long_t ReturnLongestLineWidth() override
Return width of longest line in widget.
TGText * GetText() const
Definition TGTextView.h:115
virtual void SetText(TGText *text)
Adopt a new text buffer. The text will be deleted by this object.
A TGText is a multi line text buffer.
Definition TGText.h:57
TString AsString()
Returns content as ROOT string.
Definition TGText.cxx:1236
A composite frame that layout their children in vertical way.
Definition TGFrame.h:376
An array of TObjects.
Definition TObjArray.h:31
Collectable string class.
Definition TObjString.h:28
const char * Data() const
Definition TString.h:384
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2270
return c1
Definition legend1.C:41
TF1 * f1
Definition legend1.C:11
return c2
Definition legend2.C:14
TMath.
Definition TMathBase.h:35
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:704
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:251
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Event structure.
Definition GuiTypes.h:174
EGEventType fType
of event (see EGEventType)
Definition GuiTypes.h:175
Int_t fY
pointer x, y coordinates in event window
Definition GuiTypes.h:178
Int_t fX
Definition GuiTypes.h:178