CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/Fireworks/TableWidget/src/FWTabularWidget.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     TableWidget
00004 // Class  :     FWTabularWidget
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Mon Feb  2 16:45:21 EST 2009
00011 // $Id: FWTabularWidget.cc,v 1.16 2011/03/07 13:13:51 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 #include <cassert>
00016 #include <limits.h>
00017 #include <iostream>
00018 #include "TGResourcePool.h"
00019 
00020 // user include files
00021 #include "Fireworks/TableWidget/src/FWTabularWidget.h"
00022 #include "Fireworks/TableWidget/interface/FWTableManagerBase.h"
00023 #include "Fireworks/TableWidget/interface/FWTableCellRendererBase.h"
00024 
00025 
00026 //
00027 // constants, enums and typedefs
00028 //
00029 
00030 //
00031 // static data member definitions
00032 //
00033 
00034 const int FWTabularWidget::kTextBuffer = 2;
00035 const int FWTabularWidget::kSeperatorWidth = 1;
00036 
00037 //
00038 // constructors and destructor
00039 //
00040 FWTabularWidget::FWTabularWidget(FWTableManagerBase* iTable, const TGWindow* p, GContext_t context):
00041 TGFrame(p),
00042 m_table(iTable),
00043 m_widthOfTextInColumns(m_table->numberOfColumns(),static_cast<unsigned int>(0)),
00044 m_vOffset(0),
00045 m_hOffset(0),
00046 m_normGC(context),
00047 m_backgroundGC(ULONG_MAX),
00048 m_growInWidth(true)
00049 {
00050 
00051    m_textHeight = iTable->cellHeight();
00052    m_widthOfTextInColumns = m_table->maxWidthForColumns();
00053       
00054    m_tableWidth=(kTextBuffer+kTextBuffer+kSeperatorWidth)*(m_widthOfTextInColumns.size())+kSeperatorWidth;
00055    for(std::vector<unsigned int>::const_iterator it = m_widthOfTextInColumns.begin(), itEnd = m_widthOfTextInColumns.end();
00056    it!=itEnd;
00057    ++it){
00058       m_tableWidth +=*it;
00059    }
00060    Resize();
00061    
00062    gVirtualX->GrabButton(fId,kAnyButton, kAnyModifier, kButtonPressMask|kButtonReleaseMask,kNone,kNone);
00063    m_table->Connect("visualPropertiesChanged()","FWTabularWidget",this,"needToRedraw()");
00064 }
00065 
00066 // FWTabularWidget::FWTabularWidget(const FWTabularWidget& rhs)
00067 // {
00068 //    // do actual copying here;
00069 // }
00070 
00071 FWTabularWidget::~FWTabularWidget()
00072 {
00073    m_table->Disconnect("visualPropertiesChanged()", this, "needToRedraw()");
00074 }
00075 
00076 //
00077 // assignment operators
00078 //
00079 // const FWTabularWidget& FWTabularWidget::operator=(const FWTabularWidget& rhs)
00080 // {
00081 //   //An exception safe implementation is
00082 //   FWTabularWidget temp(rhs);
00083 //   swap(rhs);
00084 //
00085 //   return *this;
00086 // }
00087 
00088 //
00089 // member functions
00090 //
00091 void
00092 FWTabularWidget::dataChanged()
00093 {
00094    m_textHeight = m_table->cellHeight();
00095    setWidthOfTextInColumns(m_table->maxWidthForColumns());
00096 }
00097 
00098 void 
00099 FWTabularWidget::needToRedraw()
00100 {
00101    fClient->NeedRedraw(this);
00102 }
00103 
00104 
00105 void 
00106 FWTabularWidget::setWidthOfTextInColumns(const std::vector<unsigned int>& iNew)
00107 {
00108    assert(iNew.size() == static_cast<unsigned int>(m_table->numberOfColumns()));
00109 
00110    m_widthOfTextInColumns=iNew;
00111    if (m_growInWidth)
00112    {
00113       // with of columns grow to prevent resizing/flickering on next event
00114       m_widthOfTextInColumnsMax.resize(iNew.size());
00115       std::vector<unsigned int>::iterator k =  m_widthOfTextInColumnsMax.begin();
00116       for(std::vector<unsigned int>::iterator it = m_widthOfTextInColumns.begin(); it != m_widthOfTextInColumns.end(); ++it, ++k)
00117       {
00118          if ( *it < *k ) 
00119             *it = *k;
00120          else
00121             *k = *it;
00122       }
00123    }
00124 
00125    m_tableWidth=0;
00126    for(std::vector<unsigned int>::const_iterator it = m_widthOfTextInColumns.begin(), itEnd = m_widthOfTextInColumns.end();
00127        it!=itEnd;
00128        ++it){
00129       m_tableWidth +=*it+kTextBuffer+kTextBuffer+kSeperatorWidth;
00130    }
00131    m_tableWidth +=kSeperatorWidth;
00132 }
00133 
00134 void 
00135 FWTabularWidget::setVerticalOffset(UInt_t iV)
00136 {
00137    if(iV != m_vOffset) {
00138       m_vOffset = iV;
00139       fClient->NeedRedraw(this);
00140    }
00141 }
00142 void 
00143 FWTabularWidget::setHorizontalOffset(UInt_t iH)
00144 {
00145    if(iH != m_hOffset){
00146       m_hOffset = iH;
00147       fClient->NeedRedraw(this);
00148    }
00149 }
00150 
00151 Bool_t 
00152 FWTabularWidget::HandleButton(Event_t *event)
00153 {
00154    if (event->fType==kButtonPress) {
00155       Int_t row,col,relX,relY;
00156       translateToRowColumn(event->fX, event->fY, row, col,relX,relY);
00157       //std::cout <<"Press: "<<relX<<" "<<relY<<" "<<row<<" "<<col<<" "<<m_table->numberOfRows()<<" "<<m_table->numberOfColumns()<<std::endl;
00158       if (row >= 0 && row < m_table->numberOfRows() && col >= 0 && col < m_table->numberOfColumns()) {
00159          FWTableCellRendererBase* renderer = m_table->cellRenderer(row,col);
00160          if (renderer) { 
00161             renderer->buttonEvent(event,relX,relY);
00162          }
00163          buttonPressed(row,col,event,relX,relY);
00164       }
00165       return true;
00166    }
00167    if (event->fType==kButtonRelease) {
00168       Int_t row,col,relX,relY;
00169       translateToRowColumn(event->fX, event->fY, row, col,relX, relY);
00170       //std::cout <<"Release: "<<relX<<" "<<relY<<" "<<row<<" "<<col<<" "<<m_table->numberOfRows()<<" "<<m_table->numberOfColumns()<<std::endl;
00171       if (row >= 0 && row < m_table->numberOfRows() && col >= 0 && col < m_table->numberOfColumns()) {
00172          FWTableCellRendererBase* renderer = m_table->cellRenderer(row,col);
00173          if (renderer) {
00174             renderer->buttonEvent(event,relX,relY);
00175          }
00176          buttonReleased(row,col,event,relX,relY);
00177       }
00178       return true;
00179    }
00180    return false;
00181 }
00182 
00183 void 
00184 FWTabularWidget::translateToRowColumn(Int_t iX, Int_t iY, Int_t& oRow, Int_t& oCol, Int_t& oRelX, Int_t& oRelY) const
00185 {
00186    if( iX < 0 ) {
00187       oCol = -1;
00188       oRelX = 0;
00189    } else {
00190       if(iX+static_cast<Int_t>(m_hOffset) > static_cast<Int_t>(m_tableWidth) ) {
00191          oCol = m_widthOfTextInColumns.size();
00192          oRelX = 0;
00193       } else {
00194          iX +=m_hOffset;
00195          oCol = 0;
00196          for(std::vector<unsigned int>::const_iterator it = m_widthOfTextInColumns.begin(), itEnd = m_widthOfTextInColumns.end();
00197          it!=itEnd;
00198          ++it,++oCol){
00199             oRelX=iX-kTextBuffer;
00200             iX-=2*kTextBuffer+kSeperatorWidth+*it;
00201             if(iX <= 0) {
00202                break;
00203             }
00204          }
00205       }
00206    }
00207    if( iY < 0) {
00208       oRow = -1;
00209       oRelY=0;
00210    } else {
00211       oRow = (int)(float(iY+m_vOffset)/(m_textHeight+2*kTextBuffer+kSeperatorWidth));
00212       oRelY = iY-oRow*(m_textHeight+2*kTextBuffer+kSeperatorWidth)+m_vOffset-kTextBuffer;
00213       Int_t numRows = m_table->numberOfRows();
00214       if(oRow > numRows) {
00215          oRow = numRows;
00216          oRelY=0;
00217       }
00218    }
00219 }
00220 
00221 void 
00222 FWTabularWidget::buttonPressed(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
00223 {
00224    //std::cout <<"buttonPressed "<<row<<" "<<column<<std::endl;
00225    Long_t args[5];
00226    args[0]=(Long_t)row;
00227    args[1]=(Long_t)column;
00228    args[2]=(Long_t)event;
00229    args[3]=(Long_t)relX;
00230    args[4]=(Long_t)relY;
00231    Emit("buttonPressed(Int_t,Int_t,Event_t*,Int_t,Int_t)",args);
00232 }
00233 void 
00234 FWTabularWidget::buttonReleased(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
00235 {
00236    //std::cout <<"buttonReleased "<<row<<" "<<column<<std::endl;
00237    Long_t args[6];
00238    args[0]=(Long_t)row;
00239    args[1]=(Long_t)column;
00240    args[2]=(Long_t)event;
00241    args[3]=(Long_t)relX;
00242    args[4]=(Long_t)relY;
00243    Emit("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",args);   
00244 }
00245 
00246 void
00247 FWTabularWidget::DoRedraw()
00248 {
00249    TGFrame::DoRedraw();
00250    
00251    //std::cout <<"DoRedraw "<<m_tableWidth<<std::endl;
00252    
00253    const int yOrigin = -m_vOffset;
00254    const int xOrigin = -m_hOffset;
00255    const int visibleWidth = m_tableWidth+xOrigin-kSeperatorWidth;
00256    int y=yOrigin;
00257    if(m_backgroundGC != ULONG_MAX) {
00258       gVirtualX->FillRectangle(fId,m_backgroundGC,xOrigin,y,m_tableWidth,
00259                                GetHeight());
00260    }
00261    gVirtualX->DrawLine(fId, m_normGC, xOrigin, y, visibleWidth, y);
00262    //Draw data
00263    const  int numRows=m_table->numberOfRows();
00264    
00265    //figure out which rows and columns are visible
00266    Int_t startRow, startColumn,relX,relY;
00267    translateToRowColumn(0,0,startRow,startColumn,relX,relY);
00268    if(startRow<0) { startRow = 0;}
00269    if(startColumn<0) { startColumn=0;}
00270    Int_t endRow, endColumn;
00271    translateToRowColumn(GetWidth(),GetHeight(),endRow,endColumn,relX,relY);
00272    if(endRow >= numRows) {
00273       endRow = numRows-1;
00274    }
00275    if(endColumn >= static_cast<Int_t>(m_widthOfTextInColumns.size())) {
00276       endColumn = m_widthOfTextInColumns.size()-1;
00277    }
00278    //std::cout <<"start "<<startRow<<" "<<startColumn<<" end "<<endRow<<" "<<endColumn<<std::endl;
00279    
00280    //calculate offset for rows and columns
00281    Int_t rowOffset = (kSeperatorWidth+2*kTextBuffer+m_textHeight)*startRow;
00282    Int_t columnOffset=kSeperatorWidth+kTextBuffer+xOrigin;
00283    for(std::vector<unsigned int>::iterator itTextWidth = m_widthOfTextInColumns.begin(), itEnd = m_widthOfTextInColumns.begin()+startColumn;
00284    itTextWidth != itEnd; ++itTextWidth) {
00285       columnOffset+=*itTextWidth+kTextBuffer+kSeperatorWidth+kTextBuffer;
00286    }
00287    
00288    
00289    y+=rowOffset;
00290    for(int row = startRow; row <= endRow; ++row) {
00291       std::vector<unsigned int>::iterator itTextWidth = m_widthOfTextInColumns.begin()+startColumn;
00292       //int x=kSeperatorWidth+kTextBuffer+xOrigin;
00293       int x = columnOffset;
00294       y+=kTextBuffer+kSeperatorWidth;
00295       for(int col = startColumn;
00296       col <= endColumn;
00297       ++col,++itTextWidth) {
00298          m_table->cellRenderer(row,col)->draw(fId,x,y,*itTextWidth,m_textHeight);
00299          //UInt_t textWidth = font->TextWidth(itData->c_str(),-1);
00300          x+=*itTextWidth+kTextBuffer+kSeperatorWidth+kTextBuffer;
00301       }
00302       y+=+m_textHeight+kTextBuffer;
00303       gVirtualX->DrawLine(fId, m_normGC, xOrigin, y, visibleWidth, y);
00304    }
00305 
00306    //draw column separators
00307    int x=xOrigin;
00308    gVirtualX->DrawLine(fId,m_normGC,x,0,x,y);
00309    x+=kSeperatorWidth;
00310    for(std::vector<unsigned int>::iterator itTextWidth = m_widthOfTextInColumns.begin();
00311    itTextWidth != m_widthOfTextInColumns.end();
00312    ++itTextWidth) {
00313       x+=2*kTextBuffer+*itTextWidth;
00314       gVirtualX->DrawLine(fId,m_normGC,x,0,x,y);
00315       x+=kSeperatorWidth;
00316    }
00317 }
00318 
00319 void 
00320 FWTabularWidget::setLineContext(GContext_t iContext)
00321 {
00322    m_normGC = iContext;
00323 }
00324 void 
00325 FWTabularWidget::setBackgroundAreaContext(GContext_t iContext)
00326 {
00327    m_backgroundGC = iContext;
00328 }
00329 
00330 //
00331 // const member functions
00332 //
00333 TGDimension 
00334 FWTabularWidget::GetDefaultSize() const
00335 {
00336    // returns default size
00337 
00338    UInt_t w = fWidth;
00339    if(! (GetOptions() & kFixedWidth) ) {
00340       w=m_tableWidth;
00341    }
00342    UInt_t h = fHeight;
00343    if(! (GetOptions() & kFixedHeight) ) {
00344       unsigned int numRows = m_table->numberOfRows();
00345       
00346       h = kSeperatorWidth+(m_textHeight+2*kTextBuffer+kSeperatorWidth)*(numRows);
00347    }
00348    return TGDimension(w, h);
00349 }
00350 
00351 //
00352 // static member functions
00353 //
00354 const TGGC&  
00355 FWTabularWidget::getDefaultGC()
00356 {
00357    static const TGGC* s_default = gClient->GetResourcePool()->GetFrameGC();
00358    return *s_default;
00359 }
00360 
00361 ClassImp(FWTabularWidget)