File indexing completed on 2023-03-17 11:01:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <cassert>
0015 #include <climits>
0016 #include <iostream>
0017 #include "TGResourcePool.h"
0018
0019
0020 #include "Fireworks/TableWidget/interface/FWTabularWidget.h"
0021 #include "Fireworks/TableWidget/interface/FWTableManagerBase.h"
0022 #include "Fireworks/TableWidget/interface/FWTableCellRendererBase.h"
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 const int FWTabularWidget::kTextBuffer = 2;
0033 const int FWTabularWidget::kSeperatorWidth = 1;
0034
0035
0036
0037
0038 FWTabularWidget::FWTabularWidget(FWTableManagerBase* iTable, const TGWindow* p, GContext_t context)
0039 : TGFrame(p),
0040 m_table(iTable),
0041 m_widthOfTextInColumns(m_table->numberOfColumns(), static_cast<unsigned int>(0)),
0042 m_vOffset(0),
0043 m_hOffset(0),
0044 m_normGC(context),
0045 m_backgroundGC(ULONG_MAX),
0046 m_growInWidth(true) {
0047 m_textHeight = iTable->cellHeight();
0048 m_widthOfTextInColumns = m_table->maxWidthForColumns();
0049
0050 m_tableWidth = (kTextBuffer + kTextBuffer + kSeperatorWidth) * (m_widthOfTextInColumns.size()) + kSeperatorWidth;
0051 for (std::vector<unsigned int>::const_iterator it = m_widthOfTextInColumns.begin(),
0052 itEnd = m_widthOfTextInColumns.end();
0053 it != itEnd;
0054 ++it) {
0055 m_tableWidth += *it;
0056 }
0057 Resize();
0058
0059 gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier, kButtonPressMask | kButtonReleaseMask, kNone, kNone);
0060 m_table->Connect("visualPropertiesChanged()", "FWTabularWidget", this, "needToRedraw()");
0061 }
0062
0063
0064
0065
0066
0067
0068 FWTabularWidget::~FWTabularWidget() { m_table->Disconnect("visualPropertiesChanged()", this, "needToRedraw()"); }
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 void FWTabularWidget::dataChanged() {
0086 m_textHeight = m_table->cellHeight();
0087 setWidthOfTextInColumns(m_table->maxWidthForColumns());
0088 }
0089
0090 void FWTabularWidget::needToRedraw() { fClient->NeedRedraw(this); }
0091
0092 void FWTabularWidget::setWidthOfTextInColumns(const std::vector<unsigned int>& iNew) {
0093 assert(iNew.size() == static_cast<unsigned int>(m_table->numberOfColumns()));
0094
0095 m_widthOfTextInColumns = iNew;
0096 if (m_growInWidth) {
0097
0098 m_widthOfTextInColumnsMax.resize(iNew.size());
0099 std::vector<unsigned int>::iterator k = m_widthOfTextInColumnsMax.begin();
0100 for (std::vector<unsigned int>::iterator it = m_widthOfTextInColumns.begin(); it != m_widthOfTextInColumns.end();
0101 ++it, ++k) {
0102 if (*it < *k)
0103 *it = *k;
0104 else
0105 *k = *it;
0106 }
0107 }
0108
0109 m_tableWidth = 0;
0110 for (std::vector<unsigned int>::const_iterator it = m_widthOfTextInColumns.begin(),
0111 itEnd = m_widthOfTextInColumns.end();
0112 it != itEnd;
0113 ++it) {
0114 m_tableWidth += *it + kTextBuffer + kTextBuffer + kSeperatorWidth;
0115 }
0116 m_tableWidth += kSeperatorWidth;
0117 }
0118
0119 void FWTabularWidget::setVerticalOffset(UInt_t iV) {
0120 if (iV != m_vOffset) {
0121 m_vOffset = iV;
0122 fClient->NeedRedraw(this);
0123 }
0124 }
0125 void FWTabularWidget::setHorizontalOffset(UInt_t iH) {
0126 if (iH != m_hOffset) {
0127 m_hOffset = iH;
0128 fClient->NeedRedraw(this);
0129 }
0130 }
0131
0132 Bool_t FWTabularWidget::HandleButton(Event_t* event) {
0133 if (event->fType == kButtonPress) {
0134 Int_t row, col, relX, relY;
0135 translateToRowColumn(event->fX, event->fY, row, col, relX, relY);
0136
0137 if (row >= 0 && row < m_table->numberOfRows() && col >= 0 && col < m_table->numberOfColumns()) {
0138 FWTableCellRendererBase* renderer = m_table->cellRenderer(row, col);
0139 if (renderer) {
0140 renderer->buttonEvent(event, relX, relY);
0141 }
0142 buttonPressed(row, col, event, relX, relY);
0143 }
0144 return true;
0145 }
0146 if (event->fType == kButtonRelease) {
0147 Int_t row, col, relX, relY;
0148 translateToRowColumn(event->fX, event->fY, row, col, relX, relY);
0149
0150 if (row >= 0 && row < m_table->numberOfRows() && col >= 0 && col < m_table->numberOfColumns()) {
0151 FWTableCellRendererBase* renderer = m_table->cellRenderer(row, col);
0152 if (renderer) {
0153 renderer->buttonEvent(event, relX, relY);
0154 }
0155 buttonReleased(row, col, event, relX, relY);
0156 }
0157 return true;
0158 }
0159 return false;
0160 }
0161
0162 void FWTabularWidget::translateToRowColumn(
0163 Int_t iX, Int_t iY, Int_t& oRow, Int_t& oCol, Int_t& oRelX, Int_t& oRelY) const {
0164 if (iX < 0) {
0165 oCol = -1;
0166 oRelX = 0;
0167 } else {
0168 if (iX + static_cast<Int_t>(m_hOffset) > static_cast<Int_t>(m_tableWidth)) {
0169 oCol = m_widthOfTextInColumns.size();
0170 oRelX = 0;
0171 } else {
0172 iX += m_hOffset;
0173 oCol = 0;
0174 for (std::vector<unsigned int>::const_iterator it = m_widthOfTextInColumns.begin(),
0175 itEnd = m_widthOfTextInColumns.end();
0176 it != itEnd;
0177 ++it, ++oCol) {
0178 oRelX = iX - kTextBuffer;
0179 iX -= 2 * kTextBuffer + kSeperatorWidth + *it;
0180 if (iX <= 0) {
0181 break;
0182 }
0183 }
0184 }
0185 }
0186 if (iY < 0) {
0187 oRow = -1;
0188 oRelY = 0;
0189 } else {
0190 oRow = (int)(float(iY + m_vOffset) / (m_textHeight + 2 * kTextBuffer + kSeperatorWidth));
0191 oRelY = iY - oRow * (m_textHeight + 2 * kTextBuffer + kSeperatorWidth) + m_vOffset - kTextBuffer;
0192 Int_t numRows = m_table->numberOfRows();
0193 if (oRow > numRows) {
0194 oRow = numRows;
0195 oRelY = 0;
0196 }
0197 }
0198 }
0199
0200 void FWTabularWidget::buttonPressed(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY) {
0201
0202 Long_t args[5];
0203 args[0] = (Long_t)row;
0204 args[1] = (Long_t)column;
0205 args[2] = (Long_t)event;
0206 args[3] = (Long_t)relX;
0207 args[4] = (Long_t)relY;
0208 Emit("buttonPressed(Int_t,Int_t,Event_t*,Int_t,Int_t)", args);
0209 }
0210 void FWTabularWidget::buttonReleased(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY) {
0211
0212 Long_t args[6];
0213 args[0] = (Long_t)row;
0214 args[1] = (Long_t)column;
0215 args[2] = (Long_t)event;
0216 args[3] = (Long_t)relX;
0217 args[4] = (Long_t)relY;
0218 Emit("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)", args);
0219 }
0220
0221 void FWTabularWidget::DoRedraw() {
0222 TGFrame::DoRedraw();
0223
0224
0225
0226 const int yOrigin = -m_vOffset;
0227 const int xOrigin = -m_hOffset;
0228 const int visibleWidth = m_tableWidth + xOrigin - kSeperatorWidth;
0229 int y = yOrigin;
0230 if (m_backgroundGC != ULONG_MAX) {
0231 gVirtualX->FillRectangle(fId, m_backgroundGC, xOrigin, y, m_tableWidth, GetHeight());
0232 }
0233 gVirtualX->DrawLine(fId, m_normGC, xOrigin, y, visibleWidth, y);
0234
0235 const int numRows = m_table->numberOfRows();
0236
0237
0238 Int_t startRow, startColumn, relX, relY;
0239 translateToRowColumn(0, 0, startRow, startColumn, relX, relY);
0240 if (startRow < 0) {
0241 startRow = 0;
0242 }
0243 if (startColumn < 0) {
0244 startColumn = 0;
0245 }
0246 Int_t endRow, endColumn;
0247 translateToRowColumn(GetWidth(), GetHeight(), endRow, endColumn, relX, relY);
0248 if (endRow >= numRows) {
0249 endRow = numRows - 1;
0250 }
0251 if (endColumn >= static_cast<Int_t>(m_widthOfTextInColumns.size())) {
0252 endColumn = m_widthOfTextInColumns.size() - 1;
0253 }
0254
0255
0256
0257 Int_t rowOffset = (kSeperatorWidth + 2 * kTextBuffer + m_textHeight) * startRow;
0258 Int_t columnOffset = kSeperatorWidth + kTextBuffer + xOrigin;
0259 for (std::vector<unsigned int>::iterator itTextWidth = m_widthOfTextInColumns.begin(),
0260 itEnd = m_widthOfTextInColumns.begin() + startColumn;
0261 itTextWidth != itEnd;
0262 ++itTextWidth) {
0263 columnOffset += *itTextWidth + kTextBuffer + kSeperatorWidth + kTextBuffer;
0264 }
0265
0266 y += rowOffset;
0267 for (int row = startRow; row <= endRow; ++row) {
0268 std::vector<unsigned int>::iterator itTextWidth = m_widthOfTextInColumns.begin() + startColumn;
0269
0270 int x = columnOffset;
0271 y += kTextBuffer + kSeperatorWidth;
0272 for (int col = startColumn; col <= endColumn; ++col, ++itTextWidth) {
0273 m_table->cellRenderer(row, col)->draw(fId, x, y, *itTextWidth, m_textHeight);
0274
0275 x += *itTextWidth + kTextBuffer + kSeperatorWidth + kTextBuffer;
0276 }
0277 y += +m_textHeight + kTextBuffer;
0278 gVirtualX->DrawLine(fId, m_normGC, xOrigin, y, visibleWidth, y);
0279 }
0280
0281
0282 int x = xOrigin;
0283 gVirtualX->DrawLine(fId, m_normGC, x, 0, x, y);
0284 x += kSeperatorWidth;
0285 for (std::vector<unsigned int>::iterator itTextWidth = m_widthOfTextInColumns.begin();
0286 itTextWidth != m_widthOfTextInColumns.end();
0287 ++itTextWidth) {
0288 x += 2 * kTextBuffer + *itTextWidth;
0289 gVirtualX->DrawLine(fId, m_normGC, x, 0, x, y);
0290 x += kSeperatorWidth;
0291 }
0292 }
0293
0294 void FWTabularWidget::setLineContext(GContext_t iContext) { m_normGC = iContext; }
0295 void FWTabularWidget::setBackgroundAreaContext(GContext_t iContext) { m_backgroundGC = iContext; }
0296
0297
0298
0299
0300 TGDimension FWTabularWidget::GetDefaultSize() const {
0301
0302
0303 UInt_t w = fWidth;
0304 if (!(GetOptions() & kFixedWidth)) {
0305 w = m_tableWidth;
0306 }
0307 UInt_t h = fHeight;
0308 if (!(GetOptions() & kFixedHeight)) {
0309 unsigned int numRows = m_table->numberOfRows();
0310
0311 h = kSeperatorWidth + (m_textHeight + 2 * kTextBuffer + kSeperatorWidth) * (numRows);
0312 }
0313 return TGDimension(w, h);
0314 }
0315
0316
0317
0318
0319 const TGGC& FWTabularWidget::getDefaultGC() {
0320 static const TGGC* s_default = gClient->GetResourcePool()->GetFrameGC();
0321 return *s_default;
0322 }
0323
0324 ClassImp(FWTabularWidget);