00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <cassert>
00016 #include <limits.h>
00017 #include <iostream>
00018 #include "TGResourcePool.h"
00019
00020
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
00028
00029
00030
00031
00032
00033
00034 const int FWTabularWidget::kTextBuffer = 2;
00035 const int FWTabularWidget::kSeperatorWidth = 1;
00036
00037
00038
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
00067
00068
00069
00070
00071 FWTabularWidget::~FWTabularWidget()
00072 {
00073 m_table->Disconnect("visualPropertiesChanged()", this, "needToRedraw()");
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
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
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
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
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
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
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
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
00263 const int numRows=m_table->numberOfRows();
00264
00265
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
00279
00280
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
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
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
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
00332
00333 TGDimension
00334 FWTabularWidget::GetDefaultSize() const
00335 {
00336
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
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)