// @(#)root/gui:$Name:  $:$Id: TGPicture.cxx,v 1.24 2005/06/26 23:37:27 rdm Exp $
// Author: Fons Rademakers   01/01/98
/*************************************************************************
 * 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.             *
 *************************************************************************/
/**************************************************************************
    This source is based on Xclass95, a Win95-looking GUI toolkit.
    Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
    Xclass95 is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
**************************************************************************/
//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGPicture & TGPicturePool                                            //
//                                                                      //
// The TGPicture class implements pictures and icons used in the        //
// different GUI elements and widgets. The TGPicturePool class          //
// implements a TGPicture cache. TGPictures are created, managed and    //
// destroyed by the TGPicturePool.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////
#include "TGPicture.h"
#include "TGResourcePool.h"
#include "THashTable.h"
#include "TSystem.h"
#include "TGWindow.h"
#include "TVirtualX.h"
#include "TImage.h"
TGGC *TGSelectedPicture::fgSelectedGC = 0;
ClassImp(TGPicture)
ClassImp(TGSelectedPicture)
ClassImp(TGPicturePool)
//______________________________________________________________________________
 const TGPicture *TGPicturePool::GetPicture(const char *name)
{
   // Get a picture from the picture pool. Picture must be freed using
   // TGPicturePool::FreePicture(). If picture is not found 0 is returned.
   if (!fPicList)
      fPicList = new THashTable(50);
   TString pname = name;
   pname.Strip();
   TString ext = strrchr(pname, '.');
   ext.ToLower();
   if (ext.Length()) { // ".xpm", ".gif" etc
      char *pxname = gSystem->ExpandPathName(gSystem->UnixPathName(pname));
      pname = pxname;
      delete [] pxname;
   }
   TGPicture *pic = (TGPicture *)fPicList->FindObject(pname);
   if (pic && !pic->IsScaled()) {
      if (pic->fPic == kNone)
         return 0;
      pic->AddReference();
      return pic;
   }
   char *picnam = gSystem->Which(fPath, pname, kReadPermission);
   if (!picnam) {
      pic = new TGPicture(pname);
      pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
      pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
      pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
      fPicList->Add(pic);
      return 0;
   }
   TImage *img = TImage::Open(picnam);
   if (!img) {
      pic = new TGPicture(pname);
      pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
      pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
      pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
      fPicList->Add(pic);
      delete [] picnam;
      return 0;
   }
   pic = new TGPicture(pname, img->GetPixmap(), img->GetMask());
   delete [] picnam;
   delete img;
   fPicList->Add(pic);
   return pic;
}
//______________________________________________________________________________
 const TGPicture *TGPicturePool::GetPicture(const char *name,
                                           UInt_t new_width, UInt_t new_height)
{
   // Get picture with specified size from pool (picture will be scaled if
   // necessary). Picture must be freed using TGPicturePool::FreePicture(). If
   // picture is not found 0 is returned.
   if (!fPicList)
      fPicList = new THashTable(50);
   TString pname = name;
   pname.Strip();
   TString ext = strrchr(pname, '.');
   ext.ToLower();
   if (ext.Length()) { // ".xpm", ".gif" etc
      char *pxname = gSystem->ExpandPathName(gSystem->UnixPathName(pname));
      pname = pxname;
      delete [] pxname;
   }
   const char *hname = TGPicture::HashName(pname, new_width, new_height);
   TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
   if (pic && pic->GetWidth() == new_width && pic->GetHeight() == new_height) {
      if (pic->fPic == kNone)
         return 0;
      pic->AddReference();
      return pic;
   }
   char *picnam = gSystem->Which(fPath, pname, kReadPermission);
   if (!picnam) {
      pic = new TGPicture(hname, kTRUE);
      pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
      pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
      pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
      pic->fAttributes.fWidth  = new_width;
      pic->fAttributes.fHeight = new_height;
      fPicList->Add(pic);
      return 0;
   }
   TImage *img = TImage::Open(picnam);
   if (!img) {
      pic = new TGPicture(hname, kTRUE);
      pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
      pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
      pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
      pic->fAttributes.fWidth  = new_width;
      pic->fAttributes.fHeight = new_height;
      fPicList->Add(pic);
      delete [] picnam;
      return 0;
   }
   img->Scale(new_width, new_height);
   pic = new TGPicture(hname, img->GetPixmap(), img->GetMask());
   delete [] picnam;
   delete img;
   fPicList->Add(pic);
   return pic;
}
//______________________________________________________________________________
 const TGPicture *TGPicturePool::GetPicture(const char *name, Pixmap_t pxmap,
                                           Pixmap_t mask)
{
   // Get picture with specified pixmap and mask from pool.
   // Picture must be freed using TGPicturePool::FreePicture().
   // If picture is not found 0 is returned.
   if (!fPicList)
      fPicList = new THashTable(50);
   Int_t xy;
   UInt_t w, h;
   gVirtualX->GetWindowSize(pxmap, xy, xy, w, h);
   const char *hname = TGPicture::HashName(name, w, h);
   TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
   if (pic) {
      pic->AddReference();
      return pic;
   }
   pic = new TGPicture(hname, pxmap, mask);
   fPicList->Add(pic);
   return pic;
}
//______________________________________________________________________________
 const TGPicture *TGPicturePool::GetPicture(const char *name, char **xpm)
{
   // Create picture from XPM data.
   // Picture must be freed using TGPicturePool::FreePicture().
   // If picture creation failed 0 is returned.
   UInt_t w, h;
   if (!xpm || !*xpm) {
      return 0;
   }
   if (!fPicList) {
      fPicList = new THashTable(50);
   }
   char *ptr = xpm[0];
   while (isspace((int)*ptr)) ++ptr;
   w = atoi(ptr);
   while (isspace((int)*ptr)) ++ptr;
   h = atoi(ptr);
   const char *hname = TGPicture::HashName(name, w, h);
   TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
   if (pic) {
      pic->AddReference();
      return pic;
   }
   TImage *img = TImage::Open(xpm);
   if (!img) {
      pic = new TGPicture(hname, kTRUE);
      pic->fAttributes.fColormap  = fClient->GetDefaultColormap();
      pic->fAttributes.fCloseness = 40000; // Allow for "similar" colors
      pic->fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
      pic->fAttributes.fWidth  = w;
      pic->fAttributes.fHeight = h;
      fPicList->Add(pic);
      return 0;
   }
   pic = new TGPicture(hname, img->GetPixmap(), img->GetMask());
   delete img;
   return pic;
}
//______________________________________________________________________________
 void TGPicturePool::FreePicture(const TGPicture *fpic)
{
   // Remove picture from cache if nobody is using it anymore.
   if (!fPicList) return;
   TGPicture *pic = (TGPicture *)fPicList->FindObject(fpic);
   if (pic) {
      if (pic->RemoveReference() == 0) {
         fPicList->Remove(pic);
         delete pic;
      }
   }
}
//______________________________________________________________________________
 TGPicturePool::~TGPicturePool()
{
   // Delete picture cache.
   if (fPicList) {
      fPicList->Delete();
      delete fPicList;
   }
}
//______________________________________________________________________________
 void TGPicturePool::Print(Option_t *) const
{
   // List all pictures in the pool.
   if (fPicList)
      fPicList->Print();
   else
      Info("Print", "no pictures in picture pool");
}
//______________________________________________________________________________
TGPicture::TGPicture(const char *name, Pixmap_t pxmap, Pixmap_t mask)
{
   // ctor. Important: both pixmaps pxmap and mask must be unique (not shared)
   fName   = name;
   fScaled = kFALSE;
   fPic    = pxmap;
   fMask   = mask;
   Int_t xy;
   fAttributes.fColormap  = gClient->GetDefaultColormap();
   fAttributes.fCloseness = 40000; // Allow for "similar" colors
   fAttributes.fMask      = kPASize | kPAColormap | kPACloseness;
   fAttributes.fPixels    = 0;
   gVirtualX->GetWindowSize(fPic, xy, xy, fAttributes.fWidth, fAttributes.fHeight);
   SetRefCount(1);
}
//______________________________________________________________________________
void TGPicture::Draw(Handle_t id, GContext_t gc, Int_t x, Int_t y) const
{
   // Draw a picture.
   GCValues_t gcv;
   gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
   gcv.fClipMask = fMask;
   gcv.fClipXOrigin = x;
   gcv.fClipYOrigin = y;
   gVirtualX->ChangeGC(gc, &gcv);
   gVirtualX->CopyArea(fPic, id, gc, 0, 0, fAttributes.fWidth, fAttributes.fHeight,
                  x, y);
   gcv.fMask = kGCClipMask;
   gcv.fClipMask = kNone;
   gVirtualX->ChangeGC(gc, &gcv);
}
//______________________________________________________________________________
TGPicture::~TGPicture()
{
   // Delete picture object.
   if (fPic != kNone)
      gVirtualX->DeletePixmap(fPic);
   if (fMask != kNone)
      gVirtualX->DeletePixmap(fMask);
   if (fAttributes.fPixels)
      delete [] fAttributes.fPixels;
}
//______________________________________________________________________________
const char *TGPicture::HashName(const char *name, Int_t width, Int_t height)
{
   // Static function returning a unique name used to look up a picture.
   // The unique name has the form "name__widthxheight".
   static TString hashName;
   hashName.Form("%s__%dx%d", name, width, height);
   return hashName.Data();
}
//______________________________________________________________________________
void TGPicture::Print(Option_t *) const
{
   // Print picture info.
   Printf("TGPicture: %s,%sref cnt = %u %d", GetName(),
          fScaled ? " scaled, " : " ", References(), fPic);
}
//______________________________________________________________________________
TGSelectedPicture::TGSelectedPicture(const TGClient *client, const TGPicture *p) :
   TGPicture("")
{
   // Create a "selected" looking picture based on the original TGPicture.
   GCValues_t gcv;
   UInt_t     w, h;
   fClient = client;
   Window_t root  = fClient->GetDefaultRoot()->GetId();
   w = p->GetWidth();
   h = p->GetHeight();
   fPic  = gVirtualX->CreatePixmap(root, w, h);
   fMask = p->GetMask();
   fAttributes.fWidth  = w;
   fAttributes.fHeight = h;
   gVirtualX->CopyArea(p->GetPicture(), fPic, GetSelectedGC()(), 0, 0, w, h, 0, 0);
   gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
   gcv.fClipMask = p->GetMask();
   gcv.fClipXOrigin = 0;
   gcv.fClipYOrigin = 0;
   GetSelectedGC().SetAttributes(&gcv);
   gVirtualX->FillRectangle(fPic, GetSelectedGC()(), 0, 0, w, h);
   GetSelectedGC().SetClipMask(kNone);
}
//______________________________________________________________________________
TGSelectedPicture::~TGSelectedPicture()
{
   // Delete selected picture.
   // fMask was borrowed so should not be deleted by ~TGPicture.
   fMask = kNone;
}
//______________________________________________________________________________
TGGC &TGSelectedPicture::GetSelectedGC()
{
   if (!fgSelectedGC) {
      fgSelectedGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
      fgSelectedGC->SetForeground(gClient->GetResourcePool()->GetSelectedBgndColor());
      fgSelectedGC->SetBackground(gClient->GetResourcePool()->GetBlackColor());
      fgSelectedGC->SetFillStyle(kFillStippled);
      fgSelectedGC->SetStipple(gClient->GetResourcePool()->GetCheckeredBitmap());
   }
   return *fgSelectedGC;
}
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.