// @(#)root/gpad:$Name: $:$Id: TInspectCanvas.cxx,v 1.19 2005/08/23 17:00:40 brun Exp $
// Author: Rene Brun 08/01/2000
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TROOT.h"
#include "TGuiFactory.h"
#include "TInspectCanvas.h"
#include "TButton.h"
#include "TClass.h"
#include "TLine.h"
#include "TLink.h"
#include "TDataMember.h"
#include "TDataType.h"
#include "TRealData.h"
#include "TLatex.h"
ClassImp(TInspectCanvas)
//////////////////////////////////////////////////////////////////////////
// //
// TInspectorObject //
// //
//////////////////////////////////////////////////////////////////////////
class TInspectorObject : public TObject
{
// This class is designed to wrap a Foreign object in order to
// inject it into the Browse sub-system.
public:
TInspectorObject(void *obj, TClass *cl) : fObj(obj),fClass(cl) {};
~TInspectorObject(){;}
void *GetObject() const { return fObj; };
void Inspect() const {
gGuiFactory->CreateInspectorImp(this, 400, 200);
};
TClass *IsA() const { return fClass; }
private:
void *fObj; //! pointer to the foreign object
TClass *fClass; //! pointer to class of the foreign object
};
//______________________________________________________________________________//*-*
//*-* A InspectCanvas is a canvas specialized to inspect Root objects.
//
//
/*
*/
//
//
//______________________________________________________________________________
TInspectCanvas::TInspectCanvas() : TCanvas()
{
//*-*-*-*-*-*-*-*-*-*-*-*InspectCanvas default constructor*-*-*-*-*-*-*-*-*-*-*
//*-* ================================
fBackward = 0;
fForward = 0;
fCurObject = 0;
fObjects = 0;
}
//_____________________________________________________________________________
TInspectCanvas::TInspectCanvas(UInt_t ww, UInt_t wh)
: TCanvas("inspect","ROOT Object Inspector",ww,wh)
{
//*-*-*-*-*-*-*-*-*-*-*-*InspectCanvas constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ========================
fBackward = 0;
fForward = 0;
fCurObject = 0;
fObjects = new TList;
}
//______________________________________________________________________________
TInspectCanvas::~TInspectCanvas()
{
//*-*-*-*-*-*-*-*-*-*-*InspectCanvas default destructor*-*-*-*-*-*-*-*-*-*-*-*
//*-* ===============================
// delete fBackward;
// delete fForward;
if (fObjects) {
fObjects->Clear("nodelete");
delete fObjects;
}
}
//______________________________________________________________________________
void TInspectCanvas::InspectObject(TObject *obj)
{
// Dump contents of obj in a graphics canvas.
// Same action as TObject::Dump but in a graphical form.
// In addition pointers to other objects can be followed.
//
// The following picture is the Inspect of a histogram object:
//
/*
*/
//
Int_t cdate = 0;
Int_t ctime = 0;
UInt_t *cdatime = 0;
Bool_t isdate = kFALSE;
Bool_t isbits = kFALSE;
const Int_t kname = 1;
const Int_t kvalue = 25;
const Int_t ktitle = 37;
const Int_t kline = 1024;
char line[kline];
char *pname;
TClass *cl = obj->IsA();
if (cl == 0) return;
TInspectorObject *proxy=0;
if (!cl->InheritsFrom(TObject::Class())) {
// This is possible only if obj is actually a TInspectorObject
// wrapping a non-TObject.
proxy = (TInspectorObject*)obj;
obj = (TObject*)proxy->GetObject();
}
if (!cl->GetListOfRealData()) cl->BuildRealData(obj);
// Count number of data members in order to resize the canvas
TRealData *rd;
TIter next(cl->GetListOfRealData());
Int_t nreal = cl->GetListOfRealData()->GetSize();
if (nreal == 0) return;
Int_t nrows = 33;
if (nreal+7 > nrows) nrows = nreal+7;
Int_t nh = nrows*15;
Int_t nw = 700;
TVirtualPad *canvas = GetVirtCanvas();
canvas->Clear(); // remove primitives from canvas
canvas->SetCanvasSize(nw, nh); // set new size of drawing area
canvas->Range(0,-3,20,nreal+4);
Float_t xvalue = 5;
Float_t xtitle = 8;
Float_t dy = 1;
Float_t ytext = Float_t(nreal) - 1.5;
Float_t tsize = 0.99/ytext;
if (tsize < 0.02) tsize = 0.02;
if (tsize > 0.03) tsize = 0.03;
// Create text objects
TText tname, tvalue, ttitle;
TText *tval;
tname.SetTextFont(61);
tname.SetTextAngle(0);
tname.SetTextAlign(12);
tname.SetTextColor(1);
tname.SetTextSize(tsize);
tvalue.SetTextFont(61);
tvalue.SetTextAngle(0);
tvalue.SetTextAlign(12);
tvalue.SetTextColor(1);
tvalue.SetTextSize(tsize);
ttitle.SetTextFont(62);
ttitle.SetTextAngle(0);
ttitle.SetTextAlign(12);
ttitle.SetTextColor(1);
ttitle.SetTextSize(tsize);
Float_t x1 = 0.2;
Float_t x2 = 19.8;
Float_t y1 = -0.5;
Float_t y2 = Float_t(nreal) - 0.5;
Float_t y3 = y2 + 1;
Float_t y4 = y3 + 1.5;
Float_t db = 25./GetWh();
Float_t btop = 0.999;
// Draw buttons
fBackward = new TButton("backward","TInspectCanvas::GoBackward();",.01,btop-db,.15,btop);
fBackward->Draw();
fBackward->SetToolTipText("Inspect previous object");
fForward = new TButton("forward", "TInspectCanvas::GoForward();", .21,btop-db,.35,btop);
fForward->Draw();
fForward->SetToolTipText("Inspect next object");
// Draw surrounding box and title areas
TLine frame;
frame.SetLineColor(1);
frame.SetLineStyle(1);
frame.SetLineWidth(1);
frame.DrawLine(x1, y1, x2, y1);
frame.DrawLine(x2, y1, x2, y4);
frame.DrawLine(x2, y4, x1, y4);
frame.DrawLine(x1, y4, x1, y1);
frame.DrawLine(x1, y2, x2, y2);
frame.DrawLine(x1, y3, x2, y3);
frame.DrawLine(xvalue, y1, xvalue, y3);
frame.DrawLine(xtitle, y1, xtitle, y3);
ttitle.SetTextSize(0.8*tsize);
ttitle.SetTextAlign(21);
ttitle.DrawText(0.5*(x1+xvalue), y2+0.1, "Member Name");
ttitle.DrawText(0.5*(xvalue+xtitle), y2+0.1, "Value");
ttitle.DrawText(0.5*(xtitle+x2), y2+0.1, "Title");
ttitle.SetTextSize(1.2*tsize);
ttitle.SetTextColor(2);
ttitle.SetTextAlign(11);
ttitle.DrawText(x1+0.2, y3+0.1, cl->GetName());
if (proxy==0) {
ttitle.SetTextColor(4);
strncpy(line,obj->GetName(),kline);
ttitle.DrawText(xvalue+0.2, y3+0.1, line);
ttitle.SetTextColor(6);
ttitle.DrawText(xtitle+2, y3+0.1, obj->GetTitle());
} else {
ttitle.SetTextColor(4);
sprintf(line,"%s:%d","Foreign object",0);
ttitle.DrawText(xvalue+0.2, y3+0.1, line);
ttitle.SetTextColor(6);
ttitle.DrawText(xtitle+2, y3+0.1, "no title given");
}
ttitle.SetTextSize(tsize);
ttitle.SetTextColor(1);
ttitle.SetTextFont(11);
ttitle.SetTextAlign(12);
//---Now loop on data members-----------------------
// We make 3 passes. Faster than one single pass because changing
// font parameters is time consuming
for (Int_t pass = 0; pass < 3; pass++) {
ytext = y2 - 0.5;
next.Reset();
while ((rd = (TRealData*) next())) {
TDataMember *member = rd->GetDataMember();
if (!member) continue;
TDataType *membertype = member->GetDataType();
isdate = kFALSE;
if (strcmp(member->GetName(),"fDatime") == 0 && strcmp(member->GetTypeName(),"UInt_t") == 0) {
isdate = kTRUE;
}
isbits = kFALSE;
if (strcmp(member->GetName(),"fBits") == 0 && strcmp(member->GetTypeName(),"UInt_t") == 0) {
isbits = kTRUE;
}
// Encode data member name
pname = &line[kname];
for (Int_t i=0;i<kline;i++) line[i] = ' ';
line[kline-1] = 0;
strncpy(pname,rd->GetName(),128);
if (strstr(member->GetFullTypeName(),"**")) strcat(pname,"**");
// Encode data value or pointer value
tval = &tvalue;
Int_t offset = rd->GetThisOffset();
char *pointer = (char*)obj + offset;
char **ppointer = (char**)(pointer);
TLink *tlink = 0;
TClass *clm=0;
if (!membertype) {
clm = member->GetClass();
}
if (member->IsaPointer()) {
char **p3pointer = (char**)(*ppointer);
if (clm && !clm->IsStartingWithTObject() ) {
//NOTE: memory leak!
p3pointer = (char**)new TInspectorObject(p3pointer,clm);
}
if (!p3pointer) {
sprintf(&line[kvalue],"->0");
} else if (!member->IsBasic()) {
if (pass == 1) {
tlink = new TLink(xvalue+0.1, ytext, p3pointer);
}
} else if (membertype) {
if (!strcmp(membertype->GetTypeName(), "char"))
strncpy(&line[kvalue], *ppointer,128);
else
strncpy(&line[kvalue], membertype->AsString(p3pointer),128);
} else if (!strcmp(member->GetFullTypeName(), "char*") ||
!strcmp(member->GetFullTypeName(), "const char*")) {
strncpy(&line[kvalue], *ppointer,128);
} else {
if (pass == 1) tlink = new TLink(xvalue+0.1, ytext, p3pointer);
}
} else if (membertype)
if (isdate) {
cdatime = (UInt_t*)pointer;
TDatime::GetDateTime(cdatime[0],cdate,ctime);
sprintf(&line[kvalue],"%d/%d",cdate,ctime);
} else if (isbits) {
sprintf(&line[kvalue],"0x%08x", *(UInt_t*)pointer);
} else {
strncpy(&line[kvalue], membertype->AsString(pointer),128);
}
else
sprintf(&line[kvalue],"->%lx ", (Long_t)pointer);
// Encode data member title
Int_t ltit = 0;
if (isdate == kFALSE && strcmp(member->GetFullTypeName(), "char*") &&
strcmp(member->GetFullTypeName(), "const char*")) {
Int_t lentit = strlen(member->GetTitle());
if (lentit >= kline-ktitle) lentit = kline-ktitle-1;
strncpy(&line[ktitle],member->GetTitle(),128);
line[ktitle+lentit] = 0;
ltit = ktitle;
}
// Ready to draw the name, value and title columns
if (pass == 0)tname.DrawText( x1+0.1, ytext, &line[kname]);
if (pass == 1) {
if (tlink) {
tlink->SetTextFont(61);
tlink->SetTextAngle(0);
tlink->SetTextAlign(12);
tlink->SetTextColor(2);
tlink->SetTextSize(tsize);
tlink->SetBit(kCanDelete);
tlink->Draw();
if (strstr(member->GetFullTypeName(),"**")) tlink->SetBit(TLink::kIsStarStar);
tlink->SetName(member->GetTypeName());
} else {
tval->DrawText(xvalue+0.1, ytext, &line[kvalue]);
}
}
if (pass == 2 && ltit) ttitle.DrawText(xtitle+0.3, ytext, &line[ltit]);
ytext -= dy;
}
}
Update();
fCurObject = obj;
}
//______________________________________________________________________________
void TInspectCanvas::GoBackward()
{
// static function , inspect previous object
TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
TObject *cur = inspect->GetCurObject();
TObject *obj = inspect->GetObjects()->Before(cur);
if (obj) inspect->InspectObject(obj);
}
//______________________________________________________________________________
void TInspectCanvas::GoForward()
{
// static function , inspect next object
TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
TObject *cur = inspect->GetCurObject();
TObject *obj = inspect->GetObjects()->After(cur);
if (obj) inspect->InspectObject(obj);
}
//______________________________________________________________________________
void TInspectCanvas::Inspector(TObject *obj)
{
// static function , interface to InspectObject.
// Create the InspectCanvas if it does not exist yet.
//
TVirtualPad *padsav = gPad;
TInspectCanvas *inspect = (TInspectCanvas*)(gROOT->GetListOfCanvases())->FindObject("inspect");
if (!inspect) inspect = new TInspectCanvas(700,600);
else inspect->cd();
inspect->InspectObject(obj);
inspect->GetObjects()->Add(obj);
//obj->SetBit(kMustCleanup);
if (padsav) padsav->cd();
}
//______________________________________________________________________________
void TInspectCanvas::RecursiveRemove(TObject *obj)
{
//*-*-*-*-*-*-*-*Recursively remove object from the list of objects*-*-*-*-*
//*-* ==================================================
//printf("Revove obj=%x, name=%s\n",obj,obj->GetName());
fObjects->Remove(obj);
TPad::RecursiveRemove(obj);
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.