Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TInspectCanvas.cxx
Go to the documentation of this file.
1// @(#)root/gpad:$Id$
2// Author: Rene Brun 08/01/2000
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, 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 "TROOT.h"
13#include "TDatime.h"
14#include "TGuiFactory.h"
15#include "TInspectCanvas.h"
16#include "TButton.h"
17#include "TClass.h"
18#include "TLine.h"
19#include "TLink.h"
20#include "TDataMember.h"
21#include "TDataType.h"
22#include "TRealData.h"
23#include "strlcpy.h"
24#include "snprintf.h"
25
27
28
29/** \class TInspectorObject
30\ingroup gpad
31
32This class is designed to wrap a Foreign object in order to
33inject it into the Browse sub-system.
34*/
35
37{
38public:
39
40 TInspectorObject(void *obj, TClass *cl) : fObj(obj),fClass(cl) {}
41 ~TInspectorObject() override {}
42
43 void *GetObject() const { return fObj; };
44 void Inspect() const override
45 {
46 gGuiFactory->CreateInspectorImp(this, 400, 200);
47 }
48 TClass *IsA() const override { return fClass; }
49
50private:
51 void *fObj{nullptr}; //! pointer to the foreign object
52 TClass *fClass{nullptr}; //! pointer to class of the foreign object
53
54};
55
56
57/** \class TInspectCanvas
58\ingroup gpad
59
60A TInspectCanvas is a canvas specialized to inspect Root objects.
61*/
62
63////////////////////////////////////////////////////////////////////////////////
64/// InspectCanvas default constructor.
65
67{
68 fLogx = 0;
69 fLogy = 0;
70 SetFillColor(0);
71}
72
73////////////////////////////////////////////////////////////////////////////////
74/// InspectCanvas constructor.
75
77 : TCanvas("inspect","ROOT Object Inspector",ww,wh)
78{
79 fObjects = new TList;
80 fLogx = 0;
81 fLogy = 0;
82 SetFillColor(0);
83}
84
85////////////////////////////////////////////////////////////////////////////////
86/// InspectCanvas default destructor.
87
89{
90 if (fObjects) {
91 fObjects->Clear("nodelete");
92 delete fObjects;
93 }
94}
95
96////////////////////////////////////////////////////////////////////////////////
97/// Dump contents of obj in a graphics canvas.
98/// Same action as TObject::Dump but in a graphical form.
99/// In addition pointers to other objects can be followed.
100///
101/// The following picture is the Inspect of a histogram object:
102/// \image html gpad_inspect.png
103
105{
106 Int_t cdate = 0;
107 Int_t ctime = 0;
108 UInt_t *cdatime = nullptr;
109 Bool_t isdate = kFALSE;
110 Bool_t isbits = kFALSE;
111 const Int_t kname = 1;
112 const Int_t kvalue = 25;
113 const Int_t ktitle = 37;
114 const Int_t kline = 1024;
115 char line[kline];
116 char *pname;
117
118 TClass *cl = obj->IsA();
119 if (!cl) return;
120 TInspectorObject *proxy = nullptr;
121 if (!cl->IsTObject()) {
122 // This is possible only if obj is actually a TInspectorObject
123 // wrapping a non-TObject.
124 proxy = (TInspectorObject*)obj;
125 obj = (TObject*)proxy->GetObject();
126 }
127
128 if (!cl->GetListOfRealData())
129 cl->BuildRealData(obj);
130
131 // Count number of data members in order to resize the canvas
132 TRealData *rd;
133 TIter next(cl->GetListOfRealData());
134 Int_t nreal = cl->GetListOfRealData()->GetSize();
135 if (nreal == 0) return;
136
137 Int_t nrows = 33;
138 if (nreal+7 > nrows) nrows = nreal+7;
139 Int_t nh = nrows*15;
140 Int_t nw = 700;
141 TVirtualPad *canvas = GetVirtCanvas();
143 if (canvas) {
144 canvas->Clear(); // remove primitives from canvas
145 canvas->SetCanvasSize(nw, nh); // set new size of drawing area
146 canvas->Range(0,-3,20,nreal+4);
147 }
148
149 Float_t xvalue = 5;
150 Float_t xtitle = 8;
151 Float_t dy = 1;
152 Float_t ytext = Float_t(nreal) - 1.5;
153 Float_t tsize = 0.99/ytext;
154 if (tsize < 0.02) tsize = 0.02;
155 if (tsize > 0.03) tsize = 0.03;
156
157 // Create text objects
158 TText tname, tvalue, ttitle;
159 TText *tval;
160 tname.SetTextFont(61);
161 tname.SetTextAngle(0);
162 tname.SetTextAlign(12);
163 tname.SetTextColor(1);
164 tname.SetTextSize(tsize);
165 tvalue.SetTextFont(61);
166 tvalue.SetTextAngle(0);
167 tvalue.SetTextAlign(12);
168 tvalue.SetTextColor(1);
169 tvalue.SetTextSize(tsize);
170 ttitle.SetTextFont(62);
171 ttitle.SetTextAngle(0);
172 ttitle.SetTextAlign(12);
173 ttitle.SetTextColor(1);
174 ttitle.SetTextSize(tsize);
175
176 Float_t x1 = 0.2;
177 Float_t x2 = 19.8;
178 Float_t y1 = -0.5;
179 Float_t y2 = Float_t(nreal) - 0.5;
180 Float_t y3 = y2 + 1;
181 Float_t y4 = y3 + 1.5;
182 Float_t db = 25./GetWh();
183 Float_t btop = 0.999;
184
185 // Draw buttons
186 fBackward = new TButton("backward","TInspectCanvas::GoBackward();",.01,btop-db,.15,btop);
187 fBackward->Draw();
188 fBackward->SetToolTipText("Inspect previous object");
189 fForward = new TButton("forward", "TInspectCanvas::GoForward();", .21,btop-db,.35,btop);
190 fForward->Draw();
191 fForward->SetToolTipText("Inspect next object");
192
193 // Draw surrounding box and title areas
194 TLine frame;
195 frame.SetLineColor(1);
196 frame.SetLineStyle(1);
197 frame.SetLineWidth(1);
198 frame.DrawLine(x1, y1, x2, y1);
199 frame.DrawLine(x2, y1, x2, y4);
200 frame.DrawLine(x2, y4, x1, y4);
201 frame.DrawLine(x1, y4, x1, y1);
202 frame.DrawLine(x1, y2, x2, y2);
203 frame.DrawLine(x1, y3, x2, y3);
204 frame.DrawLine(xvalue, y1, xvalue, y3);
205 frame.DrawLine(xtitle, y1, xtitle, y3);
206 ttitle.SetTextSize(0.8*tsize);
207 ttitle.SetTextAlign(21);
208 ttitle.DrawText(0.5*(x1+xvalue), y2+0.1, "Member Name");
209 ttitle.DrawText(0.5*(xvalue+xtitle), y2+0.1, "Value");
210 ttitle.DrawText(0.5*(xtitle+x2), y2+0.1, "Title");
211 ttitle.SetTextSize(1.2*tsize);
212 ttitle.SetTextColor(2);
213 ttitle.SetTextAlign(11);
214 ttitle.DrawText(x1+0.2, y3+0.1, cl->GetName());
215 if (!proxy) {
216 ttitle.SetTextColor(4);
217 strlcpy(line,obj->GetName(),kline);
218 ttitle.DrawText(xvalue+0.2, y3+0.1, line);
219 ttitle.SetTextColor(6);
220 ttitle.DrawText(xtitle+2, y3+0.1, obj->GetTitle());
221 } else {
222 ttitle.SetTextColor(4);
223 snprintf(line,1023,"%s:%d","Foreign object",0);
224 ttitle.DrawText(xvalue+0.2, y3+0.1, line);
225 ttitle.SetTextColor(6);
226 ttitle.DrawText(xtitle+2, y3+0.1, "no title given");
227 }
228 ttitle.SetTextSize(tsize);
229 ttitle.SetTextColor(1);
230 ttitle.SetTextFont(11);
231 ttitle.SetTextAlign(12);
232
233 //---Now loop on data members-----------------------
234 // We make 3 passes. Faster than one single pass because changing
235 // font parameters is time consuming
236 for (Int_t pass = 0; pass < 3; pass++) {
237 ytext = y2 - 0.5;
238 next.Reset();
239 while ((rd = (TRealData*) next())) {
240 TDataMember *member = rd->GetDataMember();
241 if (!member) continue;
242 TDataType *membertype = member->GetDataType();
243 isdate = kFALSE;
244 if (strcmp(member->GetName(),"fDatime") == 0 && membertype && membertype->GetType() == kUInt_t) {
245 isdate = kTRUE;
246 }
247 isbits = kFALSE;
248 if (strcmp(member->GetName(),"fBits") == 0 && membertype && membertype->GetType() == kUInt_t) {
249 isbits = kTRUE;
250 }
251
252 // Encode data member name
253 pname = &line[kname];
254 for (Int_t i=0;i<kline;i++) line[i] = ' ';
255 line[kline-1] = 0;
256 strlcpy(pname,rd->GetName(),kline-kname);
257 if (strstr(member->GetFullTypeName(),"**")) strlcat(pname,"**",kline-kname);
258
259 // Encode data value or pointer value
260 tval = &tvalue;
261 Int_t offset = rd->GetThisOffset();
262 char *pointer = (char*)obj + offset;
263 char **ppointer = (char**)(pointer);
264 TLink *tlink = nullptr;
265
266 TClass *clm = nullptr;
267 if (!membertype) {
268 clm = member->GetClass();
269 }
270
271 if (member->IsaPointer()) {
272 char **p3pointer = (char**)(*ppointer);
273 if (clm && !clm->IsStartingWithTObject() ) {
274 //NOTE: memory leak!
275 p3pointer = (char**)new TInspectorObject(p3pointer,clm);
276 }
277
278 if (!p3pointer) {
279 snprintf(&line[kvalue],kline-kvalue,"->0");
280 } else if (!member->IsBasic()) {
281 if (pass == 1) {
282 tlink = new TLink(xvalue+0.1, ytext, p3pointer);
283 }
284 } else if (membertype) {
285 if (!strcmp(membertype->GetTypeName(), "char"))
286 strlcpy(&line[kvalue], *ppointer,kline-kvalue);
287 else
288 strlcpy(&line[kvalue], membertype->AsString(p3pointer),kline-kvalue);
289 } else if (!strcmp(member->GetFullTypeName(), "char*") ||
290 !strcmp(member->GetFullTypeName(), "const char*")) {
291 strlcpy(&line[kvalue], *ppointer,kline-kvalue);
292 } else {
293 if (pass == 1) tlink = new TLink(xvalue+0.1, ytext, p3pointer);
294 }
295 } else if (membertype)
296 if (isdate) {
297 cdatime = (UInt_t*)pointer;
298 TDatime::GetDateTime(cdatime[0],cdate,ctime);
299 snprintf(&line[kvalue],kline-kvalue,"%d/%d",cdate,ctime);
300 } else if (isbits) {
301 snprintf(&line[kvalue],kline-kvalue,"0x%08x", *(UInt_t*)pointer);
302 } else {
303 strlcpy(&line[kvalue], membertype->AsString(pointer),kline-kvalue);
304 }
305 else
306 snprintf(&line[kvalue],kline-kvalue,"->%zx ", (size_t)pointer);
307
308 // Encode data member title
309 Int_t ltit = 0;
310 if (isdate == kFALSE && strcmp(member->GetFullTypeName(), "char*") &&
311 strcmp(member->GetFullTypeName(), "const char*")) {
312 Int_t lentit = strlen(member->GetTitle());
313 if (lentit >= kline-ktitle) lentit = kline-ktitle-1;
314 strlcpy(&line[ktitle],member->GetTitle(),kline-ktitle);
315 line[ktitle+lentit] = 0;
316 ltit = ktitle;
317 }
318
319 // Ready to draw the name, value and title columns
320 if (pass == 0)tname.DrawText( x1+0.1, ytext, &line[kname]);
321 if (pass == 1) {
322 if (tlink) {
323 tlink->SetTextFont(61);
324 tlink->SetTextAngle(0);
325 tlink->SetTextAlign(12);
326 tlink->SetTextColor(2);
327 tlink->SetTextSize(tsize);
328 tlink->SetBit(kCanDelete);
329 tlink->Draw();
330 if (strstr(member->GetFullTypeName(),"**")) tlink->SetBit(TLink::kIsStarStar);
331 tlink->SetName(member->GetTypeName());
332 } else {
333 tval->DrawText(xvalue+0.1, ytext, &line[kvalue]);
334 }
335 }
336 if (pass == 2 && ltit) ttitle.DrawText(xtitle+0.3, ytext, &line[ltit]);
337 ytext -= dy;
338 }
339 }
341 Update();
342 fCurObject = obj;
343}
344
345////////////////////////////////////////////////////////////////////////////////
346/// static function , inspect previous object
347
349{
350 TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
351 if (!inspect) return;
352 TObject *cur = inspect->GetCurObject();
353 TObject *obj = inspect->GetObjects()->Before(cur);
354 if (obj) inspect->InspectObject(obj);
355}
356
357////////////////////////////////////////////////////////////////////////////////
358/// static function , inspect next object
359
361{
362 TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
363 if (!inspect) return;
364 TObject *cur = inspect->GetCurObject();
365 TObject *obj = inspect->GetObjects()->After(cur);
366 if (obj) inspect->InspectObject(obj);
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// static function , interface to InspectObject.
371/// Create the InspectCanvas if it does not exist yet.
372
374{
376 TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
377 if (!inspect) inspect = new TInspectCanvas(700,600);
378 else inspect->cd();
379
380 inspect->InspectObject(obj);
381 inspect->GetObjects()->Add(obj);
382 //obj->SetBit(kMustCleanup);
383}
384
385////////////////////////////////////////////////////////////////////////////////
386/// Recursively remove object from the list of objects.
387
389{
390 fObjects->Remove(obj);
392}
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
#define ClassImp(name)
Definition Rtypes.h:382
@ kUInt_t
Definition TDataType.h:30
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
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 SetFillColor
Option_t Option_t TPoint TPoint const char y1
R__EXTERN TGuiFactory * gGuiFactory
Definition TGuiFactory.h:66
#define gROOT
Definition TROOT.h:406
#define snprintf
Definition civetweb.c:1540
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:42
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:40
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Definition TAttText.h:42
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
Definition TAttText.h:43
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
Definition TAttText.h:44
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Definition TAttText.h:46
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition TAttText.h:47
A TButton object is a user interface object.
Definition TButton.h:18
void Draw(Option_t *option="") override
Draw this button with its current attributes.
Definition TButton.cxx:146
The Canvas class.
Definition TCanvas.h:23
TVirtualPad * cd(Int_t subpadnumber=0) override
Set current canvas & pad.
Definition TCanvas.cxx:719
void Update() override
Update canvas pad buffers.
Definition TCanvas.cxx:2489
UInt_t GetWh() const override
Definition TCanvas.h:164
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
Bool_t IsStartingWithTObject() const
Returns true if this class inherits from TObject and if the start of the TObject parts is at the very...
Definition TClass.cxx:6010
void BuildRealData(void *pointer=nullptr, Bool_t isTransient=kFALSE)
Build a full list of persistent data members.
Definition TClass.cxx:2100
TList * GetListOfRealData() const
Definition TClass.h:454
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition TClass.cxx:6019
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
All ROOT classes may have RTTI (run time type identification) support added.
Definition TDataMember.h:31
Bool_t IsBasic() const
Return true if data member is a basic type, e.g. char, int, long...
Bool_t IsaPointer() const
Return true if data member is a pointer.
TDataType * GetDataType() const
Definition TDataMember.h:76
const char * GetTypeName() const
Get the decayed type name of this data member, removing const and volatile qualifiers,...
const char * GetFullTypeName() const
Get the concrete type name of this data member, including const and volatile qualifiers.
TClass * GetClass() const
Definition TDataMember.h:75
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:68
const char * AsString(void *buf) const
Return string containing value in buffer formatted according to the basic data type.
TString GetTypeName()
Get basic type of typedef, e,g.: "class TDirectory*" -> "TDirectory".
static void GetDateTime(UInt_t datetime, Int_t &date, Int_t &time)
Static function that returns the date and time.
Definition TDatime.cxx:431
virtual TInspectorImp * CreateInspectorImp(const TObject *obj, UInt_t width, UInt_t height)
Create a batch version of TInspectorImp.
A TInspectCanvas is a canvas specialized to inspect Root objects.
TButton * fBackward
Pointer to the Backward button.
~TInspectCanvas() override
InspectCanvas default destructor.
TInspectCanvas()
InspectCanvas default constructor.
static void Inspector(TObject *obj)
static function , interface to InspectObject.
TList * fObjects
List of objects inspected.
TObject * fCurObject
Pointer to object being inspected.
TList * GetObjects() const
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of objects.
TObject * GetCurObject() const
static void GoBackward()
static function , inspect previous object
TButton * fForward
Pointer to the Forward button.
static void GoForward()
static function , inspect next object
virtual void InspectObject(TObject *obj)
Dump contents of obj in a graphics canvas.
This class is designed to wrap a Foreign object in order to inject it into the Browse sub-system.
TClass * IsA() const override
void * GetObject() const
~TInspectorObject() override
TInspectorObject(void *obj, TClass *cl)
void Inspect() const override
Dump contents of this object in a graphics canvas.
TClass * fClass
pointer to the foreign object
void Reset()
Use the TLine constructor to create a simple line.
Definition TLine.h:22
virtual TLine * DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw this line with new coordinates.
Definition TLine.cxx:103
A doubly linked list.
Definition TList.h:38
TObject * After(const TObject *obj) const override
Returns the object after object obj.
Definition TList.cxx:328
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:400
TObject * Before(const TObject *obj) const override
Returns the object before object obj.
Definition TList.cxx:369
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:820
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:456
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:798
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:500
virtual TClass * IsA() const
Definition TObject.h:243
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:292
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
void SetEditable(Bool_t mode=kTRUE) override
Set pad editable yes/no If a pad is not editable:
Definition TPad.cxx:6055
void RecursiveRemove(TObject *obj) override
Recursively remove object from a pad and its sub-pads.
Definition TPad.cxx:5389
void SetToolTipText(const char *text, Long_t delayms=1000) override
Set tool tip text associated with this pad.
Definition TPad.cxx:6690
TVirtualPad * GetVirtCanvas() const override
Get virtual canvas.
Definition TPad.cxx:2778
Int_t fLogx
(=0 if X linear scale, =1 if log scale)
Definition TPad.h:91
TObject * FindObject(const char *name) const override
Search if object named name is inside this pad or in pads inside this pad.
Definition TPad.cxx:2700
Int_t fLogy
(=0 if Y linear scale, =1 if log scale)
Definition TPad.h:92
The TRealData class manages the effective list of all data members for a given class.
Definition TRealData.h:30
const char * GetName() const override
Returns name of object.
Definition TRealData.h:52
TDataMember * GetDataMember() const
Definition TRealData.h:53
Long_t GetThisOffset() const
Definition TRealData.h:55
Base class for several text objects.
Definition TText.h:22
virtual TText * DrawText(Double_t x, Double_t y, const char *text)
Draw this text with new coordinates.
Definition TText.cxx:176
small helper class to store/restore gPad context in TPad methods
Definition TVirtualPad.h:61
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition TVirtualPad.h:51
virtual void SetCanvasSize(UInt_t ww, UInt_t wh)=0
virtual void Range(Double_t x1, Double_t y1, Double_t x2, Double_t y2)=0
void Clear(Option_t *option="") override=0
TLine * line