TRootEmbeddedCanvas.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TRootEmbeddedCanvas.cxx 35582 2010-09-22 13:38:27Z bellenot $
00002 // Author: Fons Rademakers   15/07/98
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TRootEmbeddedCanvas                                                  //
00015 //                                                                      //
00016 // This class creates a TGCanvas in which a TCanvas is created. Use     //
00017 // GetCanvas() to get a pointer to the TCanvas.                         //
00018 //                                                                      //
00019 //////////////////////////////////////////////////////////////////////////
00020 
00021 #include "TRootEmbeddedCanvas.h"
00022 #include "TCanvas.h"
00023 #include "TROOT.h"
00024 #include "Riostream.h"
00025 #include "TStyle.h"
00026 #include "TPluginManager.h"
00027 #include "TVirtualGL.h"
00028 #include "TGDNDManager.h"
00029 #include "TBufferFile.h"
00030 #include "TImage.h"
00031 #include "TClass.h"
00032 #include "TUrl.h"
00033 
00034 //////////////////////////////////////////////////////////////////////////
00035 //                                                                      //
00036 // TRootEmbeddedContainer                                               //
00037 //                                                                      //
00038 // Utility class used by TRootEmbeddedCanvas. The TRootEmbeddedContainer//
00039 // is the frame embedded in the TGCanvas widget. The ROOT graphics goes //
00040 // into this frame. This class is used to enable input events on this   //
00041 // graphics frame and forward the events to the TRootEmbeddedCanvas     //
00042 // handlers.                                                            //
00043 //                                                                      //
00044 //////////////////////////////////////////////////////////////////////////
00045 
00046 class TRootEmbeddedContainer : public TGCompositeFrame {
00047 private:
00048    TRootEmbeddedCanvas  *fCanvas;    // pointer back to embedded canvas
00049 public:
00050    TRootEmbeddedContainer(TRootEmbeddedCanvas *c, Window_t id, const TGWindow *parent);
00051 
00052    Bool_t  HandleButton(Event_t *ev)
00053                { return fCanvas->HandleContainerButton(ev); }
00054    Bool_t  HandleDoubleClick(Event_t *ev)
00055                { return fCanvas->HandleContainerDoubleClick(ev); }
00056    Bool_t  HandleConfigureNotify(Event_t *ev)
00057                { TGFrame::HandleConfigureNotify(ev);
00058                   return fCanvas->HandleContainerConfigure(ev); }
00059    Bool_t  HandleKey(Event_t *ev)
00060                { return fCanvas->HandleContainerKey(ev); }
00061    Bool_t  HandleMotion(Event_t *ev)
00062                { return fCanvas->HandleContainerMotion(ev); }
00063    Bool_t  HandleExpose(Event_t *ev)
00064                { return fCanvas->HandleContainerExpose(ev); }
00065    Bool_t  HandleCrossing(Event_t *ev)
00066                { return fCanvas->HandleContainerCrossing(ev); }
00067    void    SetEditable(Bool_t) { }
00068 };
00069 
00070 //______________________________________________________________________________
00071 TRootEmbeddedContainer::TRootEmbeddedContainer(TRootEmbeddedCanvas *c, Window_t id,
00072    const TGWindow *p) : TGCompositeFrame(gClient, id, p)
00073 {
00074    // Create a canvas container.
00075 
00076    fCanvas = c;
00077 
00078    gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00079                          kButtonPressMask | kButtonReleaseMask |
00080                          kPointerMotionMask, kNone, kNone);
00081 
00082    AddInput(kKeyPressMask | kKeyReleaseMask | kPointerMotionMask |
00083             kExposureMask | kStructureNotifyMask | kLeaveWindowMask);
00084 
00085    fEditDisabled = kEditDisableGrab;
00086 }
00087 
00088 
00089 
00090 
00091 ClassImp(TRootEmbeddedCanvas)
00092 
00093 //______________________________________________________________________________
00094 TRootEmbeddedCanvas::TRootEmbeddedCanvas(const char *name, const TGWindow *p,
00095             UInt_t w, UInt_t h, UInt_t options, ULong_t back)
00096    : TGCanvas(p, w, h, options, back)
00097 {
00098    // Create an TCanvas embedded in a TGFrame. A pointer to the TCanvas can
00099    // be obtained via the GetCanvas() member function. To embed a canvas
00100    // derived from a TCanvas do the following:
00101    // TRootEmbeddedCanvas *embedded = new TRootEmbeddedCanvas(0, p, w, h);
00102    //      [note name must be 0, not null string ""]
00103    // Int_t wid = embedded->GetCanvasWindowId();
00104    // TMyCanvas *myc = new TMyCanvas("myname", 10, 10, wid);
00105    // embedded->AdoptCanvas(myc);
00106    //      [ the MyCanvas is adopted by the embedded canvas and will be
00107    //        destroyed by it ]
00108 
00109    fCanvas  = 0;
00110    fButton  = 0;
00111    fAutoFit = kTRUE;
00112    fEditDisabled = kEditDisableLayout;
00113 
00114    fCWinId = -1;
00115 
00116    if (gStyle->GetCanvasPreferGL()) {
00117       //first, initialize GL (if not yet)
00118       if (!gGLManager) {
00119          TString x = "win32";
00120          if (gVirtualX->InheritsFrom("TGX11"))
00121             x = "x11";
00122 
00123          TPluginHandler *ph = gROOT->GetPluginManager()->FindHandler("TGLManager", x);
00124 
00125          if (ph && ph->LoadPlugin() != -1) {
00126             if (!ph->ExecPlugin(0)) {
00127                Warning("CreateCanvas",
00128                        "Cannot load GL, will use default canvas imp instead\n");
00129             }
00130          }
00131       }
00132 
00133       if (gGLManager)
00134          fCWinId = gGLManager->InitGLWindow((ULong_t)GetViewPort()->GetId());
00135       //Context creation deferred till TCanvas creation (since there is no way to pass it to TCanvas).
00136 
00137       if (!gGLManager || fCWinId == -1)
00138          gStyle->SetCanvasPreferGL(kFALSE);//TCanvas should not use gl.
00139    }
00140    if (fCWinId == -1)
00141       fCWinId = gVirtualX->InitWindow((ULong_t)GetViewPort()->GetId());
00142 
00143    Window_t win = gVirtualX->GetWindowID(fCWinId);
00144    fCanvasContainer = new TRootEmbeddedContainer(this, win, GetViewPort());
00145    SetContainer(fCanvasContainer);
00146 
00147    TString cname;
00148    if (name) cname = name;
00149    else cname = TString::Format("%s_canvas", GetName());
00150    fCanvas = new TCanvas(cname.Data(), w, h, fCWinId);
00151 
00152    // define DND types
00153    fDNDTypeList = new Atom_t[3];
00154    fDNDTypeList[0] = gVirtualX->InternAtom("application/root", kFALSE);
00155    fDNDTypeList[1] = gVirtualX->InternAtom("text/uri-list", kFALSE);
00156    fDNDTypeList[2] = 0;
00157    gVirtualX->SetDNDAware(fId, fDNDTypeList);
00158    SetDNDTarget(kTRUE);
00159 
00160    if (!p) {
00161       fCanvas->SetBorderMode(0);
00162       MapSubwindows();
00163       Resize(100, 100);
00164    }
00165 }
00166 
00167 //______________________________________________________________________________
00168 TRootEmbeddedCanvas::~TRootEmbeddedCanvas()
00169 {
00170    // Delete embedded ROOT canvas.
00171 
00172    if (!MustCleanup()) {
00173       delete fCanvas;
00174       delete fCanvasContainer;
00175    }
00176    delete [] fDNDTypeList;
00177 }
00178 
00179 //______________________________________________________________________________
00180 void TRootEmbeddedCanvas::AdoptCanvas(TCanvas *c)
00181 {
00182    // Canvas c is adopted from this embedded canvas.
00183 
00184    if(c == 0) return;
00185    c->EmbedInto(fCWinId, fWidth, fHeight);
00186    fCanvas = c;
00187 }
00188 
00189 //______________________________________________________________________________
00190 Bool_t TRootEmbeddedCanvas::HandleContainerButton(Event_t *event)
00191 {
00192    // Handle mouse button events in the canvas container.
00193 
00194    if (!fCanvas) return kTRUE;
00195 
00196    Int_t button = event->fCode;
00197    Int_t x = event->fX;
00198    Int_t y = event->fY;
00199 
00200    if (event->fType == kButtonPress) {
00201       fButton = button;
00202       if (button == kButton1) {
00203          if (event->fState & kKeyShiftMask)
00204             fCanvas->HandleInput(EEventType(7), x, y);
00205          else
00206             fCanvas->HandleInput(kButton1Down, x, y);
00207       }
00208       if (button == kButton2)
00209          fCanvas->HandleInput(kButton2Down, x, y);
00210       if (button == kButton3) {
00211          fCanvas->HandleInput(kButton3Down, x, y);
00212          fButton = 0;  // button up is consumed by TContextMenu
00213       }
00214 
00215    } else if (event->fType == kButtonRelease) {
00216       if (button == kButton1)
00217          fCanvas->HandleInput(kButton1Up, x, y);
00218       if (button == kButton2)
00219          fCanvas->HandleInput(kButton2Up, x, y);
00220       if (button == kButton3)
00221          fCanvas->HandleInput(kButton3Up, x, y);
00222       if (button == kButton4)
00223          fCanvas->HandleInput(EEventType(5), x, y);//hack
00224       if (button == kButton5)
00225          fCanvas->HandleInput(EEventType(6), x, y);//hack
00226 
00227       fButton = 0;
00228    }
00229 
00230    return kTRUE;
00231 }
00232 
00233 //______________________________________________________________________________
00234 Bool_t TRootEmbeddedCanvas::HandleContainerDoubleClick(Event_t *event)
00235 {
00236    // Handle mouse button double click events in the canvas container.
00237 
00238    if (!fCanvas) return kTRUE;
00239 
00240    Int_t button = event->fCode;
00241    Int_t x = event->fX;
00242    Int_t y = event->fY;
00243 
00244    if (button == kButton1)
00245       fCanvas->HandleInput(kButton1Double, x, y);
00246    if (button == kButton2)
00247       fCanvas->HandleInput(kButton2Double, x, y);
00248    if (button == kButton3)
00249       fCanvas->HandleInput(kButton3Double, x, y);
00250 
00251    return kTRUE;
00252 }
00253 
00254 //______________________________________________________________________________
00255 Bool_t TRootEmbeddedCanvas::HandleContainerConfigure(Event_t *)
00256 {
00257    // Handle configure (i.e. resize) event.
00258 
00259    if (fAutoFit && fCanvas) {
00260       fCanvas->Resize();
00261       fCanvas->Update();
00262    }
00263    return kTRUE;
00264 }
00265 
00266 //______________________________________________________________________________
00267 Bool_t TRootEmbeddedCanvas::HandleContainerKey(Event_t *event)
00268 {
00269    // Handle keyboard events in the canvas container.
00270 
00271    if (!fCanvas) return kTRUE;
00272 
00273    if (event->fType == kGKeyPress) {
00274       fButton = event->fCode;
00275       UInt_t keysym;
00276       char str[2];
00277       gVirtualX->LookupString(event, str, sizeof(str), keysym);
00278       if (str[0] == 3)   // ctrl-c sets the interrupt flag
00279          gROOT->SetInterrupt();
00280       fCanvas->HandleInput(kKeyPress, str[0], keysym);
00281    } else if (event->fType == kKeyRelease)
00282       fButton = 0;
00283 
00284    return kTRUE;
00285 }
00286 
00287 //______________________________________________________________________________
00288 Bool_t TRootEmbeddedCanvas::HandleContainerMotion(Event_t *event)
00289 {
00290    // Handle mouse motion event in the canvas container.
00291 
00292    if (!fCanvas) return kTRUE;
00293 
00294    Int_t x = event->fX;
00295    Int_t y = event->fY;
00296 
00297    if (fButton == 0)
00298       fCanvas->HandleInput(kMouseMotion, x, y);
00299    if (fButton == kButton1) {
00300       if (event->fState & kKeyShiftMask)
00301          fCanvas->HandleInput(EEventType(8), x, y);
00302       else
00303          fCanvas->HandleInput(kButton1Motion, x, y);
00304    }
00305    if (fButton == kButton2)
00306       fCanvas->HandleInput(kButton2Motion, x, y);
00307 
00308    return kTRUE;
00309 }
00310 
00311 //______________________________________________________________________________
00312 Bool_t TRootEmbeddedCanvas::HandleContainerExpose(Event_t *event)
00313 {
00314    // Handle expose events.
00315 
00316    if (!fCanvas) return kTRUE;
00317 
00318    if (event->fCount == 0)
00319       fCanvas->Flush();
00320 
00321    return kTRUE;
00322 }
00323 
00324 //______________________________________________________________________________
00325 Bool_t TRootEmbeddedCanvas::HandleContainerCrossing(Event_t *event)
00326 {
00327    // Handle enter/leave events. Only leave is activated at the moment.
00328 
00329    if (!fCanvas) return kTRUE;
00330 
00331    Int_t x = event->fX;
00332    Int_t y = event->fY;
00333 
00334    // pointer grabs create also an enter and leave event but with fCode
00335    // either kNotifyGrab or kNotifyUngrab, don't propagate these events
00336    if (event->fType == kLeaveNotify && event->fCode == kNotifyNormal)
00337       fCanvas->HandleInput(kMouseLeave, x, y);
00338 
00339    return kTRUE;
00340 }
00341 
00342 //______________________________________________________________________________
00343 Bool_t TRootEmbeddedCanvas::HandleDNDDrop(TDNDData *data)
00344 {
00345    // Handle drop events.
00346 
00347    static Atom_t rootObj  = gVirtualX->InternAtom("application/root", kFALSE);
00348    static Atom_t uriObj  = gVirtualX->InternAtom("text/uri-list", kFALSE);
00349 
00350    if (data->fDataType == rootObj) {
00351       TBufferFile buf(TBuffer::kRead, data->fDataLength, (void *)data->fData);
00352       buf.SetReadMode();
00353       TObject *obj = (TObject *)buf.ReadObjectAny(TObject::Class());
00354       if (!obj) return kTRUE;
00355       gPad->Clear();
00356       if (obj->InheritsFrom("TKey")) {
00357          TObject *object = (TObject *)gROOT->ProcessLine(Form("((TKey *)0x%lx)->ReadObj();", (ULong_t)obj));
00358          if (!object) return kTRUE;
00359          if (object->InheritsFrom("TGraph"))
00360             object->Draw("ACP");
00361          else if (object->InheritsFrom("TImage"))
00362             object->Draw("x");
00363          else if (object->IsA()->GetMethodAllAny("Draw"))
00364             object->Draw();
00365       }
00366       else if (obj->InheritsFrom("TGraph"))
00367          obj->Draw("ACP");
00368       else if (obj->IsA()->GetMethodAllAny("Draw"))
00369          obj->Draw();
00370       gPad->Modified();
00371       gPad->Update();
00372       return kTRUE;
00373    }
00374    else if (data->fDataType == uriObj) {
00375       TString sfname((char *)data->fData);
00376       if (sfname.Length() > 7) {
00377          sfname.ReplaceAll("\r\n", "");
00378          TUrl uri(sfname.Data());
00379          if (sfname.EndsWith(".bmp") ||
00380             sfname.EndsWith(".gif") ||
00381             sfname.EndsWith(".jpg") ||
00382             sfname.EndsWith(".png") ||
00383             sfname.EndsWith(".ps")  ||
00384             sfname.EndsWith(".eps") ||
00385             sfname.EndsWith(".pdf") ||
00386             sfname.EndsWith(".tiff") ||
00387             sfname.EndsWith(".xpm")) {
00388             TImage *img = TImage::Open(uri.GetFile());
00389             if (img) {
00390                img->Draw("x");
00391                img->SetEditable(kTRUE);
00392             }
00393          }
00394          gPad->Modified();
00395          gPad->Update();
00396       }
00397    }
00398    return kFALSE;
00399 }
00400 
00401 //______________________________________________________________________________
00402 Atom_t TRootEmbeddedCanvas::HandleDNDPosition(Int_t /*x*/, Int_t /*y*/, Atom_t action,
00403                                               Int_t xroot, Int_t yroot)
00404 {
00405    // Handle dragging position events.
00406 
00407    Int_t    px = 0, py = 0;
00408    Window_t wtarget;
00409 
00410    gVirtualX->TranslateCoordinates(gClient->GetDefaultRoot()->GetId(),
00411                                    gVirtualX->GetWindowID(fCanvas->GetCanvasID()),
00412                                    xroot, yroot, px, py, wtarget);
00413 
00414    TPad *pad = fCanvas->Pick(px, py, 0);
00415    if (pad) {
00416       pad->cd();
00417       gROOT->SetSelectedPad(pad);
00418       // make sure the pad is highlighted (on Windows)
00419       pad->Update();
00420    }
00421    return action;
00422 }
00423 
00424 //______________________________________________________________________________
00425 Atom_t TRootEmbeddedCanvas::HandleDNDEnter(Atom_t *typelist)
00426 {
00427    // Handle drag enter events.
00428 
00429    static Atom_t rootObj  = gVirtualX->InternAtom("application/root", kFALSE);
00430    static Atom_t uriObj  = gVirtualX->InternAtom("text/uri-list", kFALSE);
00431    Atom_t ret = kNone;
00432    for (int i = 0; typelist[i] != kNone; ++i) {
00433       if (typelist[i] == rootObj)
00434          ret = rootObj;
00435       if (typelist[i] == uriObj)
00436          ret = uriObj;
00437    }
00438    return ret;
00439 }
00440 
00441 //______________________________________________________________________________
00442 Bool_t TRootEmbeddedCanvas::HandleDNDLeave()
00443 {
00444    // Handle drag leave events.
00445 
00446    return kTRUE;
00447 }
00448 
00449 //______________________________________________________________________________
00450 void TRootEmbeddedCanvas::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00451 {
00452    // Save an embedded canvas as a C++ statement(s) on output stream out.
00453 
00454    if (!GetCanvas()) return;
00455 
00456    if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
00457 
00458    char quote ='"';
00459 
00460    out << endl << "   // embedded canvas" << endl;
00461    out << "   TRootEmbeddedCanvas *";
00462    out << GetName() << " = new TRootEmbeddedCanvas(0" << "," << fParent->GetName()
00463        << "," << GetWidth() << "," << GetHeight();
00464 
00465    if (fBackground == GetDefaultFrameBackground()) {
00466       if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
00467          out <<");" << endl;
00468       } else {
00469          out << "," << GetOptionString() <<");" << endl;
00470       }
00471    } else {
00472       out << "," << GetOptionString() << ",ucolor);" << endl;
00473    }
00474    if (option && strstr(option, "keep_names"))
00475       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00476 
00477    out << "   Int_t w" << GetName() << " = " << GetName()
00478        << "->GetCanvasWindowId();" << endl;
00479 
00480    static int n = 123;
00481    TString cname = TString::Format("c%d", n);
00482 
00483    out << "   TCanvas *";
00484    out <<  cname << " = new TCanvas(";
00485    out << quote << cname.Data() << quote << ", 10, 10, w"
00486        << GetName() << ");" << endl;
00487    out << "   " << GetName() << "->AdoptCanvas(" << cname
00488        << ");" << endl;
00489 
00490    n++;
00491    //Next line is a connection to TCanvas::SavePrimitives()
00492    //GetCanvas()->SavePrimitive(out,option);
00493 }

Generated on Tue Jul 5 14:22:08 2011 for ROOT_528-00b_version by  doxygen 1.5.1