00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
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 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 class TRootEmbeddedContainer : public TGCompositeFrame {
00047 private:
00048    TRootEmbeddedCanvas  *fCanvas;    
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    
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    
00099    
00100    
00101    
00102    
00103    
00104    
00105    
00106    
00107    
00108 
00109    fCanvas  = 0;
00110    fButton  = 0;
00111    fAutoFit = kTRUE;
00112    fEditDisabled = kEditDisableLayout;
00113 
00114    fCWinId = -1;
00115 
00116    if (gStyle->GetCanvasPreferGL()) {
00117       
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       
00136 
00137       if (!gGLManager || fCWinId == -1)
00138          gStyle->SetCanvasPreferGL(kFALSE);
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    
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    
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    
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    
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;  
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);
00224       if (button == kButton5)
00225          fCanvas->HandleInput(EEventType(6), x, y);
00226 
00227       fButton = 0;
00228    }
00229 
00230    return kTRUE;
00231 }
00232 
00233 
00234 Bool_t TRootEmbeddedCanvas::HandleContainerDoubleClick(Event_t *event)
00235 {
00236    
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    
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    
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)   
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    
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    
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    
00328 
00329    if (!fCanvas) return kTRUE;
00330 
00331    Int_t x = event->fX;
00332    Int_t y = event->fY;
00333 
00334    
00335    
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    
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 , Int_t , Atom_t action,
00403                                               Int_t xroot, Int_t yroot)
00404 {
00405    
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       
00419       pad->Update();
00420    }
00421    return action;
00422 }
00423 
00424 
00425 Atom_t TRootEmbeddedCanvas::HandleDNDEnter(Atom_t *typelist)
00426 {
00427    
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    
00445 
00446    return kTRUE;
00447 }
00448 
00449 
00450 void TRootEmbeddedCanvas::SavePrimitive(ostream &out, Option_t *option )
00451 {
00452    
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    
00492    
00493 }