Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
overlay_drag.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_eve_7
3/// Interactive overlay annotations: framed REveText boxes floating in front of
4/// the 3D scene, which can be dragged and resized in the browser.
5///
6/// An overlay scene is a normal REveScene flagged with SetIsOverlay(true). Its
7/// contents are drawn by a dedicated orthographic camera into a fixed screen
8/// box, after and in front of the 3D scene.
9///
10/// Coordinates in the overlay box are fractions of the viewport:
11///
12/// (0,0) = bottom-left corner, (1,1) = top-right corner
13///
14/// Font size is a fraction of viewport height. A client with a differently
15/// shaped window sees the boxes at the same relative position but covering a
16/// different fraction of its width.
17///
18/// Interaction, once SetPickable(true) is set:
19///
20/// hover over a box -> it lightens, and if it is resizable a small
21/// square grip appears in its bottom-right corner
22/// drag the box -> move it
23/// drag the corner grip -> resize it (font size and frame together)
24///
25/// SetPickable() governs moving, SetResizable() governs resizing, so a header can
26/// be repositioned while keeping its size. The logo, an REveLogo, moves and
27/// resizes the same way.
28///
29/// Moving and resizing are client-local. Nothing is sent to the server, so two
30/// browsers on the same session arrange their annotations independently.
31///
32/// \macro_code
33///
34/// \author Matevz Tadel
35
36#include <ROOT/REveElement.hxx>
37#include <ROOT/REveGeoShape.hxx>
38#include <ROOT/REveJetCone.hxx>
39#include <ROOT/REveLogo.hxx>
40#include <ROOT/REveManager.hxx>
41#include <ROOT/REveScene.hxx>
42#include <ROOT/REveText.hxx>
43#include <ROOT/REveViewer.hxx>
44
45#include "TColor.h"
46#include "TGeoTube.h"
47#include "TROOT.h"
48#include "TMath.h"
49#include "TRandom.h"
50
51using namespace ROOT::Experimental;
52
53/// Ships with ROOT in TROOT::GetDataDir()/fonts.
54static const char *kOvlFont = "LiberationSerif-Regular";
55
56const Double_t kR_min = 240;
57const Double_t kR_max = 250;
58const Double_t kZ_d = 300;
59
60//------------------------------------------------------------------------------
61
62/// One framed annotation box. `x`, `y` and `size` are all fractions of the
63/// viewport, per the coordinate note above.
64REveText *makeAnnotation(REveElement *holder, const char *name, const char *text, float x, float y, float size,
65 Color_t text_color, Color_t frame_color, Color_t fill_color, bool resizable = true)
66{
67 auto t = new REveText(name);
68 t->SetText(text);
69 t->SetFont(kOvlFont);
70 t->SetFontWeight(0.05f); // stands in for the bold face ROOT does not ship
71 t->SetMode(1); // 1 = screen mode: position is in the (0,1) overlay box
72 t->SetFontSize(size);
73 t->SetPosition(REveVector(x, y, 0.0));
74 t->SetTextColor(text_color);
75
76 // Frame: a filled, outlined plate behind the glyphs. The whole plate is the
77 // pick target, so framed text is easier to grab.
78 t->SetDrawFrame(true);
79 t->SetFillColor(fill_color);
80 t->SetFillAlpha(170); // 0..255; translucent so the scene stays visible
81 t->SetLineColor(frame_color);
82 t->SetLineAlpha(255);
83 t->SetLineWidth(0.06); // in units of line height
84 t->SetExtraBorder(0.25); // padding around the text, in font-size units
85
86 // Required for drag and resize: without it the element is not in the picking
87 // pass at all and mouse events pass straight through to the camera controls.
88 t->SetPickable(true);
89 // A non-resizable element can still be moved. The corner grip is drawn only
90 // on resizable elements, and only while hovered.
91 t->SetResizable(resizable);
92
93 holder->AddElement(t);
94 return t;
95}
96
97/// A little 3D content to annotate, and to prove the overlay stays in front of it.
98void makeSceneContent(REveManager *eveMng)
99{
100 auto b = new REveGeoShape("Barrel");
101 b->SetShape(new TGeoTube(kR_min, kR_max, kZ_d));
102 b->SetMainColor(kCyan);
103 b->SetMainTransparency(60);
104 b->SetNSegments(64);
105 eveMng->GetGlobalScene()->AddElement(b);
106
107 TRandom &r = *gRandom;
108 auto jets = new REveElement("Jets");
109 for (int i = 0; i < 4; ++i) {
110 auto jet = new REveJetCone(Form("Jet_%d", i));
111 jet->SetCylinder(2 * kR_max, 2 * kZ_d);
112 jet->AddEllipticCone(r.Uniform(-2.5, 2.5), r.Uniform(0, TMath::TwoPi()), r.Uniform(0.05, 0.2),
113 r.Uniform(0.05, 0.25));
114 jet->SetFillColor(kPink - 8);
115 jet->SetLineColor(kBlack);
116 jets->AddElement(jet);
117 }
118 eveMng->GetEventScene()->AddElement(jets);
119}
120
121//------------------------------------------------------------------------------
122
123void overlay_drag()
124{
125 auto eveMng = REveManager::Create();
126
127 // Make the printed URL reusable, so it can be opened in two browser windows.
128 // Dragging an annotation in one does not move it in the other. This also
129 // accepts non-local clients without a connection key, so use it only for
130 // local development.
131 eveMng->AllowMultipleRemoteConnections(false, false);
132
133 // Generate the SDF atlas from the font in TROOT::GetDataDir()/fonts. This does
134 // nothing once the .png and .js.gz exist. ROOT ships no bold Liberation face,
135 // so makeAnnotation() uses SetFontWeight() instead.
136 std::string rf = std::string(TROOT::GetDataDir().Data()) + "/fonts/";
137 REveText::AssertSdfFont(kOvlFont, rf + kOvlFont + ".ttf");
138
139 makeSceneContent(eveMng);
140
141 // An overlay scene is an ordinary scene, added to a viewer like any other and
142 // then flagged as an overlay.
143 REveScene *os = eveMng->SpawnNewScene("Overlay scene", "Draggable annotations");
144 ((REveViewer *)(eveMng->GetViewers()->FirstChild()))->AddScene(os);
145 os->SetIsOverlay(true);
146
147 // The browser fetches images over HTTP, so the directory holding them is
148 // registered with SetImageDir(). Any readable directory works. The icons that
149 // ship with ROOT are found through TROOT::GetIconPath(), in a build tree and in
150 // an installation. See REveLogo::SetFile() for the other image sources.
151 REveLogo::SetImageDir(TROOT::GetIconPath().Data());
152
153 auto logo = new REveLogo("Root6Icon.png", "Logo");
154 logo->SetPosition(0.88, 0.86); // (0,1) overlay box; the image is centred here
155 logo->SetSize(110); // height in CSS pixels; width follows the image
156 logo->SetOpacity(0.75); // a watermark: it brightens when hovered
157 os->AddElement(logo);
158
159 auto holder = new REveElement("annotations");
160
161 // Muted colours, with a saturated blue frame marking the interactive boxes.
162 // clang-format off
163 const Color_t kInk = TColor::GetColor("#1f2d36"); // deep slate text
164 const Color_t kIce = TColor::GetColor("#f2f7f9"); // plate, a cool white
165 const Color_t kQuiet = TColor::GetColor("#8fa6b2"); // frame, static label
166 const Color_t kLive = TColor::GetColor("#3f7d96"); // frame, interactive
167 // clang-format on
168
169 makeAnnotation(holder, "Title", "Run 123456 / Event 42", 0.03, 0.95, 0.035, kInk, kQuiet, kIce, false);
170 makeAnnotation(holder, "DragMe", "drag me anywhere", 0.03, 0.85, 0.030, kInk, kLive, kIce);
171 makeAnnotation(holder, "ResizeMe", "hover me, then grab the corner", 0.03, 0.76, 0.030, kInk, kLive, kIce);
172
173 // Multi-line: embed newlines in the text. The box grows downwards, one line
174 // height per line. The resize grip keeps its single-line size.
175 makeAnnotation(holder, "Legend", "legend\n cyan barrel\n pink jet cones", 0.03, 0.67, 0.030, kInk, kLive, kIce);
176
177 makeAnnotation(holder, "InFront", "always in front of the geometry", 0.34, 0.28, 0.026, kInk, kQuiet, kIce, false);
178
179 os->AddElement(holder);
180
181 eveMng->Show();
182}
#define b(i)
Definition RSha256.hxx:100
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
short Color_t
Color number (short)
Definition RtypesCore.h:100
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
@ kPink
Definition Rtypes.h:67
@ kBlack
Definition Rtypes.h:65
@ kCyan
Definition Rtypes.h:66
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:142
R__EXTERN TRandom * gRandom
Definition TRandom.h:73
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
Base class for REveUtil visualization elements, providing hierarchy management, rendering control and...
Wrapper for TGeoShape with absolute positioning and color attributes allowing display of extracted TG...
Draws a jet cone with leading particle is specified in (eta,phi) and cone radius is given.
A screen-space image for an overlay scene, such as an experiment logo or a watermark.
Central application manager for web-based REve.
Eve representation of TGLScene.
Eve representation of a GL view.
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:1939
Cylindrical tube class.
Definition TGeoTube.h:17
static const TString & GetIconPath()
Get the icon path in the installation. Static utility function.
Definition TROOT.cxx:3501
static const TString & GetDataDir()
Get the data directory in the installation. Static utility function.
Definition TROOT.cxx:3406
This is the base class for the ROOT Random number generators.
Definition TRandom.h:28
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Namespace for ROOT features in testing.
Definition TROOT.h:100
constexpr Double_t TwoPi()
Definition TMath.h:47