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