TGPicture.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGPicture.cxx 34286 2010-07-01 20:38:57Z rdm $
00002 // Author: Fons Rademakers   01/01/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     This source is based on Xclass95, a Win95-looking GUI toolkit.
00014     Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
00015 
00016     Xclass95 is free software; you can redistribute it and/or
00017     modify it under the terms of the GNU Library General Public
00018     License as published by the Free Software Foundation; either
00019     version 2 of the License, or (at your option) any later version.
00020 
00021 **************************************************************************/
00022 
00023 //////////////////////////////////////////////////////////////////////////
00024 //                                                                      //
00025 // TGPicture & TGPicturePool                                            //
00026 //                                                                      //
00027 // The TGPicture class implements pictures and icons used in the        //
00028 // different GUI elements and widgets. The TGPicturePool class          //
00029 // implements a TGPicture cache. TGPictures are created, managed and    //
00030 // destroyed by the TGPicturePool.                                      //
00031 //                                                                      //
00032 //////////////////////////////////////////////////////////////////////////
00033 
00034 #include "TGPicture.h"
00035 #include "TGResourcePool.h"
00036 #include "THashTable.h"
00037 #include "TSystem.h"
00038 #include "TGWindow.h"
00039 #include "TVirtualX.h"
00040 #include "TImage.h"
00041 #include <stdlib.h>
00042 
00043 TGGC *TGSelectedPicture::fgSelectedGC = 0;
00044 
00045 ClassImp(TGPicture)
00046 ClassImp(TGSelectedPicture)
00047 ClassImp(TGPicturePool)
00048 
00049 
00050 //______________________________________________________________________________
00051 TGPicturePool::TGPicturePool(const TGPicturePool& pp) :
00052   TObject(pp),
00053   fClient(pp.fClient),
00054   fPath(pp.fPath),
00055   fPicList(pp.fPicList)
00056 {
00057    //copy constructor
00058 }
00059 
00060 //______________________________________________________________________________
00061 TGPicturePool& TGPicturePool::operator=(const TGPicturePool& pp)
00062 {
00063    //assignment operator
00064    if(this!=&pp) {
00065       TObject::operator=(pp);
00066       fClient=pp.fClient;
00067       fPath=pp.fPath;
00068       fPicList=pp.fPicList;
00069    }
00070    return *this;
00071 }
00072 
00073 //______________________________________________________________________________
00074 const TGPicture *TGPicturePool::GetPicture(const char *name)
00075 {
00076    // Get a picture from the picture pool. Picture must be freed using
00077    // TGPicturePool::FreePicture(). If picture is not found 0 is returned.
00078 
00079    if (!fPicList)
00080       fPicList = new THashTable(50);
00081 
00082    TString pname = name;
00083    pname.Strip();
00084    TString ext = strrchr(pname, '.');
00085    ext.ToLower();
00086 
00087    if (ext.Length()) { // ".xpm", ".gif" etc
00088       char *pxname = gSystem->ExpandPathName(gSystem->UnixPathName(pname));
00089       pname = pxname;
00090       delete [] pxname;
00091    }
00092 
00093    TGPicture *pic = (TGPicture *)fPicList->FindObject(pname);
00094    if (pic && !pic->IsScaled()) {
00095       if (pic->fPic == kNone)
00096          return 0;
00097       pic->AddReference();
00098       return pic;
00099    }
00100 
00101    char *picnam = gSystem->Which(fPath, pname, kReadPermission);
00102    if (!picnam) {
00103       pic = new TGPicture(pname);
00104       pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
00105       pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
00106       pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
00107       fPicList->Add(pic);
00108       return 0;
00109    }
00110 
00111    TImage *img = TImage::Open(picnam);
00112    if (!img) {
00113       pic = new TGPicture(pname);
00114       pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
00115       pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
00116       pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
00117       fPicList->Add(pic);
00118       delete [] picnam;
00119       return 0;
00120    }
00121 
00122    pic = new TGPicture(pname, img->GetPixmap(), img->GetMask());
00123    delete [] picnam;
00124    delete img;
00125    fPicList->Add(pic);
00126    return pic;
00127 }
00128 
00129 //______________________________________________________________________________
00130 const TGPicture *TGPicturePool::GetPicture(const char *name,
00131                                            UInt_t new_width, UInt_t new_height)
00132 {
00133    // Get picture with specified size from pool (picture will be scaled if
00134    // necessary). Picture must be freed using TGPicturePool::FreePicture(). If
00135    // picture is not found 0 is returned.
00136 
00137    if (!fPicList)
00138       fPicList = new THashTable(50);
00139 
00140    TString pname = name;
00141    pname.Strip();
00142    TString ext = strrchr(pname, '.');
00143    ext.ToLower();
00144 
00145    if (ext.Length()) { // ".xpm", ".gif" etc
00146       char *pxname = gSystem->ExpandPathName(gSystem->UnixPathName(pname));
00147       pname = pxname;
00148       delete [] pxname;
00149    }
00150 
00151    const char *hname = TGPicture::HashName(pname, new_width, new_height);
00152    TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
00153    if (pic && pic->GetWidth() == new_width && pic->GetHeight() == new_height) {
00154       if (pic->fPic == kNone)
00155          return 0;
00156       pic->AddReference();
00157       return pic;
00158    }
00159 
00160    char *picnam = gSystem->Which(fPath, pname, kReadPermission);
00161    if (!picnam) {
00162       pic = new TGPicture(hname, kTRUE);
00163       pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
00164       pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
00165       pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
00166       pic->fAttributes.fWidth  = new_width;
00167       pic->fAttributes.fHeight = new_height;
00168       fPicList->Add(pic);
00169       return 0;
00170    }
00171 
00172    TImage *img = TImage::Open(picnam);
00173    if (!img) {
00174       pic = new TGPicture(hname, kTRUE);
00175       pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
00176       pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
00177       pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
00178       pic->fAttributes.fWidth  = new_width;
00179       pic->fAttributes.fHeight = new_height;
00180       fPicList->Add(pic);
00181       delete [] picnam;
00182       return 0;
00183    }
00184 
00185    img->Scale(new_width, new_height);
00186 
00187    pic = new TGPicture(hname, img->GetPixmap(), img->GetMask());
00188    delete [] picnam;
00189    delete img;
00190    fPicList->Add(pic);
00191    return pic;
00192 }
00193 
00194 //______________________________________________________________________________
00195 const TGPicture *TGPicturePool::GetPicture(const char *name, Pixmap_t pxmap,
00196                                            Pixmap_t mask)
00197 {
00198    // Get picture with specified pixmap and mask from pool.
00199    // Picture must be freed using TGPicturePool::FreePicture().
00200    // If picture is not found 0 is returned.
00201 
00202    if (!fPicList)
00203       fPicList = new THashTable(50);
00204 
00205    Int_t xy;
00206    UInt_t w, h;
00207 
00208    gVirtualX->GetWindowSize(pxmap, xy, xy, w, h);
00209 
00210    const char *hname = TGPicture::HashName(name, w, h);
00211    TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
00212 
00213    if (pic) {
00214       pic->AddReference();
00215       return pic;
00216    }
00217 
00218    pic = new TGPicture(hname, pxmap, mask);
00219    fPicList->Add(pic);
00220 
00221    return pic;
00222 }
00223 
00224 //______________________________________________________________________________
00225 const TGPicture *TGPicturePool::GetPicture(const char *name, char **xpm)
00226 {
00227    // Create picture from XPM data.
00228    // Picture must be freed using TGPicturePool::FreePicture().
00229    // If picture creation failed 0 is returned.
00230 
00231    UInt_t w, h;
00232 
00233    if (!xpm || !*xpm) {
00234       return 0;
00235    }
00236 
00237    if (!fPicList) {
00238       fPicList = new THashTable(50);
00239    }
00240    char *ptr = xpm[0];
00241    while (isspace((int)*ptr)) ++ptr;
00242    w = atoi(ptr);
00243 
00244    while (isspace((int)*ptr)) ++ptr;
00245    h = atoi(ptr);
00246 
00247    const char *hname = TGPicture::HashName(name, w, h);
00248    TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
00249    if (pic) {
00250       pic->AddReference();
00251       return pic;
00252    }
00253 
00254    TImage *img = TImage::Open(xpm);
00255    if (!img) {
00256       pic = new TGPicture(hname, kTRUE);
00257       pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
00258       pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
00259       pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
00260       pic->fAttributes.fWidth  = w;
00261       pic->fAttributes.fHeight = h;
00262       fPicList->Add(pic);
00263       return 0;
00264    }
00265 
00266    pic = new TGPicture(hname, img->GetPixmap(), img->GetMask());
00267    delete img;
00268    return pic;
00269 }
00270 
00271 //______________________________________________________________________________
00272 void TGPicturePool::FreePicture(const TGPicture *fpic)
00273 {
00274    // Remove picture from cache if nobody is using it anymore.
00275 
00276    if (!fPicList) return;
00277 
00278    TGPicture *pic = (TGPicture *)fPicList->FindObject(fpic);
00279    if (pic) {
00280       if (pic->RemoveReference() == 0) {
00281          fPicList->Remove(pic);
00282          delete pic;
00283       }
00284    }
00285 }
00286 
00287 //______________________________________________________________________________
00288 TGPicturePool::~TGPicturePool()
00289 {
00290    // Delete picture cache.
00291 
00292    if (fPicList) {
00293       fPicList->Delete();
00294       delete fPicList;
00295    }
00296 }
00297 
00298 //______________________________________________________________________________
00299 void TGPicturePool::Print(Option_t *) const
00300 {
00301    // List all pictures in the pool.
00302 
00303    if (fPicList)
00304       fPicList->Print();
00305    else
00306       Info("Print", "no pictures in picture pool");
00307 }
00308 
00309 //______________________________________________________________________________
00310 TGPicture::TGPicture(const char *name, Pixmap_t pxmap, Pixmap_t mask)
00311 {
00312    // ctor. Important: both pixmaps pxmap and mask must be unique (not shared)
00313 
00314    fName   = name;
00315    fScaled = kFALSE;
00316    fPic    = pxmap;
00317    fMask   = mask;
00318    Int_t xy;
00319 
00320    fAttributes.fColormap  = gClient->GetDefaultColormap();
00321    fAttributes.fCloseness = 40000; // Allow for "similar" colors
00322    fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
00323    fAttributes.fPixels    = 0;
00324    fAttributes.fDepth     = 0;
00325    fAttributes.fNpixels   = 0;
00326    fAttributes.fXHotspot  = 0;
00327    fAttributes.fYHotspot  = 0;
00328 
00329    gVirtualX->GetWindowSize(fPic, xy, xy, fAttributes.fWidth, fAttributes.fHeight);
00330    SetRefCount(1);
00331 }
00332 
00333 //______________________________________________________________________________
00334 void TGPicture::Draw(Handle_t id, GContext_t gc, Int_t x, Int_t y) const
00335 {
00336    // Draw a picture.
00337 
00338    GCValues_t gcv;
00339 
00340    gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
00341    gcv.fClipMask = fMask;
00342    gcv.fClipXOrigin = x;
00343    gcv.fClipYOrigin = y;
00344    gVirtualX->ChangeGC(gc, &gcv);
00345    gVirtualX->CopyArea(fPic, id, gc, 0, 0, fAttributes.fWidth, fAttributes.fHeight,
00346                   x, y);
00347    gcv.fMask = kGCClipMask;
00348    gcv.fClipMask = kNone;
00349    gVirtualX->ChangeGC(gc, &gcv);
00350 }
00351 
00352 //______________________________________________________________________________
00353 TGPicture::~TGPicture()
00354 {
00355    // Delete picture object.
00356 
00357    if (fPic != kNone)
00358       gVirtualX->DeletePixmap(fPic);
00359    if (fMask != kNone)
00360       gVirtualX->DeletePixmap(fMask);
00361    if (fAttributes.fPixels)
00362       delete [] fAttributes.fPixels;
00363 }
00364 
00365 //______________________________________________________________________________
00366 const char *TGPicture::HashName(const char *name, Int_t width, Int_t height)
00367 {
00368    // Static function returning a unique name used to look up a picture.
00369    // The unique name has the form "name__widthxheight".
00370 
00371    static TString hashName;
00372 
00373    hashName.Form("%s__%dx%d", name, width, height);
00374    return hashName.Data();
00375 }
00376 
00377 //______________________________________________________________________________
00378 void TGPicture::Print(Option_t *) const
00379 {
00380    // Print picture info.
00381 
00382    Printf("TGPicture: %s,%sref cnt = %u %lx", GetName(),
00383           fScaled ? " scaled, " : " ", References(), fPic);
00384 }
00385 
00386 
00387 //______________________________________________________________________________
00388 TGSelectedPicture::TGSelectedPicture(const TGClient *client, const TGPicture *p) :
00389    TGPicture("")
00390 {
00391    // Create a "selected" looking picture based on the original TGPicture.
00392 
00393    GCValues_t gcv;
00394    UInt_t     w, h;
00395 
00396    fClient = client;
00397    Window_t root  = fClient->GetDefaultRoot()->GetId();
00398 
00399    w = p->GetWidth();
00400    h = p->GetHeight();
00401 
00402    fPic  = gVirtualX->CreatePixmap(root, w, h);
00403    fMask = p->GetMask();
00404 
00405    fAttributes.fWidth  = w;
00406    fAttributes.fHeight = h;
00407 
00408    gVirtualX->CopyArea(p->GetPicture(), fPic, GetSelectedGC()(), 0, 0, w, h, 0, 0);
00409 
00410    gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
00411    gcv.fClipMask = p->GetMask();
00412    gcv.fClipXOrigin = 0;
00413    gcv.fClipYOrigin = 0;
00414    GetSelectedGC().SetAttributes(&gcv);
00415 
00416    gVirtualX->FillRectangle(fPic, GetSelectedGC()(), 0, 0, w, h);
00417 
00418    GetSelectedGC().SetClipMask(kNone);
00419 }
00420 
00421 //______________________________________________________________________________
00422 TGSelectedPicture::~TGSelectedPicture()
00423 {
00424    // Delete selected picture.
00425 
00426    // fMask was borrowed so should not be deleted by ~TGPicture.
00427    fMask = kNone;
00428 }
00429 
00430 //______________________________________________________________________________
00431 TGGC &TGSelectedPicture::GetSelectedGC()
00432 {
00433    // Return selection graphics context in use.
00434 
00435    if (!fgSelectedGC) {
00436       fgSelectedGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
00437       fgSelectedGC->SetForeground(gClient->GetResourcePool()->GetSelectedBgndColor());
00438       fgSelectedGC->SetBackground(gClient->GetResourcePool()->GetBlackColor());
00439       fgSelectedGC->SetFillStyle(kFillStippled);
00440       fgSelectedGC->SetStipple(gClient->GetResourcePool()->GetCheckeredBitmap());
00441    }
00442    return *fgSelectedGC;
00443 }

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