Re: [ROOT] copy canvas (2)

From: Rene Brun (Rene.Brun@cern.ch)
Date: Thu Jul 13 2000 - 11:17:14 MEST


Hi Ingolf,

The macro that I send yesterday was only a partial implementation.
I have now implemented a new function TCanvas::DrawClonePad to do the job
correctly. It also appears in the canvas context menu.
As usual, you can get the latest source from the CVS repository.
I have updated the macro of yesterday to be a copy of the new
TCanvas::DrawClonePad
Here is the new code.

Rene Brun


void canclone(TCanvas *c1)
{
   //example showing how to copy a full canvas into a pad in another canvas
   
  
  //create second canvas, divide it and copy first canvas in first subpad
  TCanvas *c2 = new TCanvas("c2","c2",600,800);
  c2->Divide(1,2);
  c2->cd(1);
  TPad *pad = (TPad*)gPad;
  c1->cd();
  TObject *obj, *clone;
  //copy pad attributes
  pad->Range(c1->GetX1(),c1->GetY1(),c1->GetX2(),c1->GetY2());
  pad->SetTickx(c1->GetTickx());
  pad->SetTicky(c1->GetTicky());
  pad->SetGridx(c1->GetGridx());
  pad->SetGridy(c1->GetGridy());
  pad->SetLogx(c1->GetLogx());
  pad->SetLogy(c1->GetLogy());
  pad->SetLogz(c1->GetLogz());
  pad->SetBorderSize(c1->GetBorderSize());
  pad->SetBorderMode(c1->GetBorderMode());
  c1->TAttLine::Copy((TAttLine&)*pad);
  c1->TAttFill::Copy((TAttFill&)*pad);
  c1->TAttPad::Copy((TAttPad&)*pad);
  
  //copy primitives
  TIter next(c1->GetListOfPrimitives());
  while ((obj=next())) {
     gROOT->SetSelectedPad(pad);
     clone = obj->Clone();
     pad->GetListOfPrimitives()->Add(clone,obj->GetDrawOption());
  }
  pad->Modified();
  pad->Update();
  c2->cd();
}

Ingolf Martin wrote:
> 
> Hi Rene,
> 
> thanks for your quick reply on the canvas copy problem.
> Unfortunately, the "GetListOfPrimitives()" cloning procedure
> seems to have some problems with TGraphs.
> 
> For example, if we try this session:
> 
>   // it is interesting to select "p" as a drawing option for one graph
>   // after this command
>   .x $ROOTSYS/tutorials/gerrors2.C;
> 
>   // now the macro that you kindly supplied
>   .x canclone.C(c1);
> 
> we end up with a different drawing style and lost markers, which is quite
> surprising since everything works so well with histograms.
> Do you have any idea on where that information is lost and how it can be
> restored?
> 
> Ingolf
> 
> On Wed, 12 Jul 2000, Rene Brun wrote:
> > Hi Ingolf,
> >
> > The TObject::DrawClone function can be used to draw a clone of any object
> > into the current pad. In an interactive session, one can click with the middle
> > button to select the destination/current pad, then with the right button
> > click on the object to be copied (can be a primitive, histogram, pad, etc)
> > and select the item "DrawClone" in the context menu.
> >
> > However, I realize that this currently does not work for the canvas itself.
> > When selecting "DrawClone" on a canvas, a new canvas is created that is a clone
> > of the original canvas.
> > I will modify TCanvas::DrawClone (or may be add a new function) to copy
> > a full canvas inside a pad of another canvas. I agree that this would be
> > a very useful feature.
> >
> > Meanwhile, you can use the macro below as an example to do this.
> > This macro assumes that you have an already existing canvas c1 that may contain
> > subpads. You can for example test it with the session:
> >  root > .x $ROOTSYS/tutorials/h1draw.C
> >  root > .x canclone.C(c1)
> >
> > Rene Brun
> >
> >
> 
> void canclone(TCanvas *c1)
> {
>    //example showing how to copy a full canvas into a pad in another canvas
> 
> 
>   //create second canvas, divide it and copy first canvas in first subpad
>   TCanvas *c2 = new TCanvas("c2","c2",600,800);
>   c2->Divide(1,2);
>   c2->cd(1);
>   TPad *pad = (TPad*)gPad;
>   TObject *obj;
>   TIter next(c1->GetListOfPrimitives());
>   while ((obj=next())) {
>      gROOT->SetSelectedPad(pad);
>      pad->GetListOfPrimitives()->Add(obj->Clone());
>   }
>   gPad->Modified();
> }
> 
> >
> > Ingolf Martin wrote:
> > >
> > > Hi Rooters,
> > >
> > > I would like to copy a canvas into a little pad in another canvas,
> > > something like
> > >
> > >   // create two canvases (and one pad in second canvas)
> > >   .x $ROOTSYS/tutorials/graph.C;
> > >   TCanvas *canv1 = (TCanvas*)gROOT->GetListOfCanvases()->First();
> > >   TCanvas *canv2 = new TCanvas("canv2", "canv2", 1);
> > >   TPad *pad2 = new TPad("subpad","subpad", 0.3, 0.3, 0.7, 0.7);
> > >   canv2->cd();
> > >   pad2->Range(canv1->GetX1(), canv1->GetY1(), canv1->GetX2(), canv1->GetY2());
> > >   pad2->Draw();
> > >
> > > But if I do
> > >
> > >   //first try
> > >   TCanvas *clone1 = (TCanvas*)canv1->Clone();
> > >   pad2->cd();
> > >   clone1->Draw();
> > >
> > > all that appears on pad2 is a frame and the title of canv1's graph.
> > > If one decides to manually loop through all graphics objects
> > >
> > >   //second try
> > >   pad2->Clear();
> > >   TIter next(canv1->GetListOfPrimitives());
> > >   TObject *obj;
> > >   while (obj = next()) obj->Clone()->Draw();
> > >
> > > the copy is still incomplete (apart from the obvious fact that this doesn't
> > > duplicate pad attributes like color and grid).
> > > On the other hand, the second approach works fine on the output of
> > >
> > >   .x $ROOTSYS/tutorials/archi.C
> > >
> > > which contains mainly TBoxes.
> > >
> > > What is wrong with these examples?
> > > (ROOT 2.25/00 on Linux) - any comments would be greatly
> > > appreciated.
> > >
> > > Ingolf
> > >
> > > ------------------------------------------------
> > >
> > > Ingolf Martin
> > > Physikalisches Institut,  Universität Tübingen
> > > Auf der Morgenstelle 14, 72076 Tübingen, Germany
> > > Tel: 07071/2976311   Fax: /295373
> >



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:29 MET