Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TObjectDrawable.cxx
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
3 * All rights reserved. *
4 * *
5 * For the licensing terms see $ROOTSYS/LICENSE. *
6 * For the list of contributors see $ROOTSYS/README/CREDITS. *
7 *************************************************************************/
8
10
12#include <ROOT/RColor.hxx>
13#include <ROOT/RLogger.hxx>
14#include <ROOT/RMenuItems.hxx>
15
16#include "TArrayI.h"
17#include "TColor.h"
18#include "TObjArray.h"
19#include "TObjString.h"
20#include "TROOT.h"
21#include "TList.h"
22#include "TStyle.h"
23#include "TMethodCall.h"
24
25#include <exception>
26#include <sstream>
27#include <iostream>
28#include <cstring>
29
30using namespace ROOT::Experimental;
31
32////////////////////////////////////////////////////////////////////
33/// Checks object ownership - used for TH1 directory handling and TF1 globals lists
34
36{
37 if (obj && obj->InheritsFrom("TH1")) {
38 TMethodCall call;
39 call.InitWithPrototype(obj->IsA(), "SetDirectory", "TDirectory*");
40 if (call.IsValid()) {
41 void *arg0 = nullptr;
42 const void *method_args[1] = { &arg0 };
43 call.Execute((void *) obj, method_args, 1);
44 }
45 } else if (obj && obj->InheritsFrom("TF1")) {
46 TMethodCall call;
47 call.InitWithPrototype(obj->IsA(), "AddToGlobalList", "Bool_t");
48 if (call.IsValid()) {
50 const void *method_args[1] = { &arg0 };
51 call.Execute((void *) obj, method_args, 1);
52 }
53 }
54}
55
56////////////////////////////////////////////////////////////////////
57/// Provide css type
58
60{
61 if (!obj) return "tobject";
62
63 const char *clname = obj->ClassName();
64 if (strncmp(clname, "TH3", 3) == 0) return "th3";
65 if (strncmp(clname, "TH2", 3) == 0) return "th2";
66 if ((strncmp(clname, "TH1", 3) == 0) || obj->InheritsFrom("TH1")) return "th1";
67 if (strncmp(clname, "TGraph", 6) == 0) return "tgraph";
68 if (strcmp(clname, "TLine") == 0) return "tline";
69 if (strcmp(clname, "TBox") == 0) return "tbox";
70 return "tobject";
71}
72
73////////////////////////////////////////////////////////////////////
74/// Default constructor
75
79
80////////////////////////////////////////////////////////////////////
81/// Constructor, can take ownership over the object is isowner specified
82
84{
85 fKind = kObject;
86 if (isowner) {
87 CheckOwnership(obj);
88 fObj = std::shared_ptr<TObject>(obj);
89 } else {
90 fExtObj = obj;
91 }
92}
93
94////////////////////////////////////////////////////////////////////
95/// Constructor, can take ownership over the object is isowner specified
96
97TObjectDrawable::TObjectDrawable(TObject *obj, const std::string &opt, bool isowner) : TObjectDrawable(obj, isowner)
98{
99 options = opt;
100}
101
102////////////////////////////////////////////////////////////////////
103/// Constructor
104
105TObjectDrawable::TObjectDrawable(const std::shared_ptr<TObject> &obj) : RDrawable(DetectCssType(obj.get()))
106{
107 fKind = kObject;
108 CheckOwnership(obj.get());
109 fObj = obj;
110}
111
112
113////////////////////////////////////////////////////////////////////
114/// Constructor
115
116TObjectDrawable::TObjectDrawable(const std::shared_ptr<TObject> &obj, const std::string &opt) : TObjectDrawable(obj)
117{
118 options = opt;
119}
120
121////////////////////////////////////////////////////////////////////
122/// Creates special kind for for palette or list of colors
123/// One can create persistent, which does not updated to actual values
124
125TObjectDrawable::TObjectDrawable(EKind kind, bool persistent) : RDrawable("tobject")
126{
127 fKind = kind;
128
129 if (persistent)
130 fObj = CreateSpecials(kind);
131}
132
133////////////////////////////////////////////////////////////////////
134/// Destructor
135
137
138
139////////////////////////////////////////////////////////////////////
140/// Reset object
141
143{
144 fKind = kNone;
145 fObj = nullptr;
146 fExtObj = nullptr;
147}
148
149
150////////////////////////////////////////////////////////////////////
151/// Return assigned object
152
154{
155 // weak pointer - when object deleted outside only indirect way to handle it :(
156 if (fExtObj) {
157 if (!fExtObj->TestBit(TObject::kNotDeleted)) fExtObj = nullptr;
158 return fExtObj;
159 }
160
161 return fObj.get();
162}
163
164
165////////////////////////////////////////////////////////////////////
166/// Set object
167
169{
170 Reset();
171
173 fKind = kObject;
174
175 if (isowner) {
176 CheckOwnership(obj);
177 fObj = std::shared_ptr<TObject>(obj);
178 } else {
179 fExtObj = obj;
180 }
181}
182
183////////////////////////////////////////////////////////////////////
184/// Set object
185
186void TObjectDrawable::Set(TObject *obj, const std::string &opt, bool isowner)
187{
188 Set(obj, isowner);
189 options = opt;
190}
191
192////////////////////////////////////////////////////////////////////
193/// Convert TColor to RGB string for using with SVG
194
196{
197 RColor rcol((uint8_t) (255*col->GetRed()), (uint8_t) (255*col->GetGreen()), (uint8_t) (255*col->GetBlue()));
198 if (col->GetAlpha() != 1)
199 rcol.SetAlphaFloat(col->GetAlpha());
200
201 return rcol.AsSVG();
202}
203
204////////////////////////////////////////////////////////////////////
205/// Create instance of requested special object
206
207std::unique_ptr<TObject> TObjectDrawable::CreateSpecials(int kind)
208{
209 switch (kind) {
210 case kColors: {
211 // convert list of colors into strings
212 auto arr = std::make_unique<TObjArray>();
213 arr->SetOwner(kTRUE);
214
215 auto cols = gROOT->GetListOfColors();
216 for (int n = 0; n <= cols->GetLast(); ++n) {
217 auto col = dynamic_cast<TColor *>(cols->At(n));
218 if (!col) continue;
219 auto code = TString::Format("%d=%s", n, GetColorCode(col).c_str());
220 arr->Add(new TObjString(code));
221 }
222
223 return arr;
224 }
225 case kStyle: { // create copy of gStyle
226 return std::make_unique<TStyle>(*gStyle);
227 }
228 case kPalette: { // copy color palette
229
230 auto arr = std::make_unique<TObjArray>();
231 arr->SetOwner(kTRUE);
232
234 for (int n = 0; n < palette.GetSize(); ++n) {
235 auto col = gROOT->GetColor(palette[n]);
236 arr->Add(new TObjString(GetColorCode(col).c_str()));
237 }
238
239 return arr;
240 }
241 }
242 return nullptr;
243}
244
245////////////////////////////////////////////////////////////////////
246/// Check if object has specified color value and store it in display item
247/// Ensure that color matches on client side too
248
249void TObjectDrawable::ExtractObjectColors(std::unique_ptr<TObjectDisplayItem> &item, const TObject *obj)
250{
251 if (!obj) return;
252
253 TClass *cl = obj->IsA();
254
255 auto ExtractColor = [&item, cl, obj](const char *class_name, const char *class_member) {
256 if (!cl->GetBaseClass(class_name)) return;
257
259 if (offset <= 0) return;
260
261 Color_t *icol = (Color_t *)((char *) obj + offset);
262 if (*icol < 10) return;
263
264 TColor *col = gROOT->GetColor(*icol);
265 if (col) item->UpdateColor(*icol, GetColorCode(col));
266 };
267
268 ExtractColor("TAttLine", "fLineColor");
269 ExtractColor("TAttFill", "fFillColor");
270 ExtractColor("TAttMarker", "fMarkerColor");
271 ExtractColor("TAttText", "fTextColor");
272 ExtractColor("TAttPad", "fFrameFillColor");
273 ExtractColor("TAttPad", "fFrameLineColor");
274 ExtractColor("TAttAxis", "fAxisColor");
275 ExtractColor("TAttAxis", "fLabelColor");
276 ExtractColor("TAttAxis", "fTitleColor");
277
278 if (cl->InheritsFrom("TH1")) {
279 auto offx = cl->GetDataMemberOffset("fXaxis");
280 if (offx > 0) ExtractObjectColors(item, (TObject *) ((char *) obj + offx));
281 auto offy = cl->GetDataMemberOffset("fYaxis");
282 if (offy > 0) ExtractObjectColors(item, (TObject *) ((char *) obj + offy));
283 auto offz = cl->GetDataMemberOffset("fZaxis");
284 if (offz > 0) ExtractObjectColors(item, (TObject *) ((char *) obj + offz));
285 }
286}
287
288
289////////////////////////////////////////////////////////////////////
290/// Create display item which will be delivered to the client
291
292std::unique_ptr<RDisplayItem> TObjectDrawable::Display(const RDisplayContext &ctxt)
293{
294 if (GetVersion() > ctxt.GetLastVersion()) {
295
296 auto obj = Get();
297
298 if ((fKind == kObject) || obj) {
299 auto item = std::make_unique<TObjectDisplayItem>(*this, fKind, obj);
300 if ((fKind == kObject) && obj) {
302
303 // special handling of THStack to support any custom colors inside
304 if (strcmp(obj->ClassName(), "THStack") == 0) {
305 TClass *cl = gROOT->GetClass("THStack");
306 // do not call stack->GetHistogram() to avoid it auto-creation
307 auto off1 = cl->GetDataMemberOffset("fHistogram");
308 if (off1 > 0) ExtractObjectColors(item, *((TObject **) ((char *) obj + off1)));
309 // here make identical to fHistogram, one also can use TMethodCall
310 auto off2 = cl->GetDataMemberOffset("fHists");
311 if (off2 > 0) {
312 TIter iter(*(TList **) (((char *) obj + off2)));
313 TObject *hist = nullptr;
314 while ((hist = iter()) != nullptr)
316 }
317
318 }
319 }
320
321 return item;
322 }
323
325 return std::make_unique<TObjectDisplayItem>(fKind, specials.release());
326 }
327
328 return nullptr;
329}
330
331////////////////////////////////////////////////////////////////////
332/// fill context menu items for the ROOT class
333
335{
336 auto obj = Get();
337
338 if ((fKind != kObject) || !obj)
339 return;
340
341 TClass *cl = obj->IsA();
342
343 if (!items.GetSpecifier().empty() && cl->InheritsFrom("TH1")) {
344 Longptr_t offset = 0;
345 if (items.GetSpecifier() == "x")
346 offset = cl->GetDataMemberOffset("fXaxis");
347 else if (items.GetSpecifier() == "y")
348 offset = cl->GetDataMemberOffset("fYaxis");
349 else if (items.GetSpecifier() == "z")
350 offset = cl->GetDataMemberOffset("fZaxis");
351 if (offset > 0) {
352 obj = (TObject *) ((char *) obj + offset);
353 cl = obj->IsA();
354 }
355 }
356
357 items.PopulateObjectMenu((void *)obj, cl);
358}
359
360////////////////////////////////////////////////////////////////////
361/// Execute object method
362
363void TObjectDrawable::Execute(const std::string &exec)
364{
365 auto obj = Get();
366
367 if ((fKind != kObject) || !obj) return;
368
369 std::string sub, ex = exec;
370 if (ex.compare(0, 6, "xaxis#") == 0) {
371 ex.erase(0,6);
372 ex.insert(0, "GetXaxis()->");
373 } else if (ex.compare(0, 6, "yaxis#") == 0) {
374 ex.erase(0,6);
375 ex.insert(0, "GetYaxis()->");
376 } else if (ex.compare(0, 6, "zaxis#") == 0) {
377 ex.erase(0,6);
378 ex.insert(0, "GetZaxis()->");
379 }
380
381 std::stringstream cmd;
382 cmd << "((" << obj->ClassName() << " *) " << std::hex << std::showbase << (size_t)obj << ")->" << ex << ";";
383 std::cout << "TObjectDrawable::Execute Obj " << obj->GetName() << " Cmd " << cmd.str() << std::endl;
384 gROOT->ProcessLine(cmd.str().c_str());
385}
short Color_t
Color number (short)
Definition RtypesCore.h:99
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
#define gROOT
Definition TROOT.h:417
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
The color class.
Definition RColor.hxx:33
Base class for drawable entities: objects that can be painted on a RPad.
Version_t GetVersion() const
void SetCssType(const char *csstype)
List of items for object context menu.
Provides v7 drawing facilities for TObject types (TGraph, TH1, TH2, etc).
RAttrValue< std::string > options
! object draw options
@ kPalette
list of colors from palette
@ kStyle
instance of TStyle object
static void ExtractObjectColors(std::unique_ptr< TObjectDisplayItem > &item, const TObject *obj)
Check if object has specified color value and store it in display item Ensure that color matches on c...
static void CheckOwnership(TObject *obj)
Checks object ownership - used for TH1 directory handling and TF1 globals lists.
Internal::RIOShared< TObject > fObj
The object to be painted, owned by the drawable.
std::unique_ptr< TObject > CreateSpecials(int kind)
Create instance of requested special object.
void PopulateMenu(RMenuItems &) final
fill context menu items for the ROOT class
static std::string GetColorCode(TColor *col)
Convert TColor to RGB string for using with SVG.
void Execute(const std::string &) final
Execute object method.
std::unique_ptr< RDisplayItem > Display(const RDisplayContext &) override
Create display item which will be delivered to the client.
const TObject * Get()
Return assigned object.
static const char * DetectCssType(const TObject *obj)
Provide css type.
const TObject * fExtObj
! external object, managed outside of the drawable, not persistent
void Set(TObject *obj, bool isowner=false)
Set object.
~TObjectDrawable() override
Destructor.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TClass * GetBaseClass(const char *classname)
Return pointer to the base class "classname".
Definition TClass.cxx:2662
Longptr_t GetDataMemberOffset(const char *membername) const
return offset for member name.
Definition TClass.cxx:3539
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4932
TClass * IsA() const override
Definition TClass.h:637
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2994
The color creation and management class.
Definition TColor.h:22
static const TArrayI & GetPalette()
Static function returning the current active palette.
Definition TColor.cxx:1521
Float_t GetRed() const
Definition TColor.h:61
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
Float_t GetAlpha() const
Definition TColor.h:67
Float_t GetBlue() const
Definition TColor.h:63
Float_t GetGreen() const
Definition TColor.h:62
A doubly linked list.
Definition TList.h:38
Method or function calling interface.
Definition TMethodCall.h:37
void Execute(const char *, const char *, int *=nullptr) override
Execute method on this object with the given parameter string, e.g.
Definition TMethodCall.h:64
Bool_t IsValid() const
Return true if the method call has been properly initialized and is usable.
void InitWithPrototype(TClass *cl, const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Initialize the method invocation environment.
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:42
@ kNotDeleted
object has not been deleted
Definition TObject.h:91
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:549
virtual TClass * IsA() const
Definition TObject.h:248
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2385
const Int_t n
Definition legend1.C:16
Double_t ex[n]
Definition legend1.C:17
Namespace for ROOT features in testing.
Definition TROOT.h:100