File indexing completed on 2024-06-06 04:26:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <iostream>
0015 #include "TGScrollBar.h"
0016 #include "TGTableLayout.h"
0017 #include "TGResourcePool.h"
0018
0019
0020 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
0021 #include "Fireworks/TableWidget/interface/FWTableManagerBase.h"
0022 #include "Fireworks/TableWidget/interface/FWTabularWidget.h"
0023 #include "Fireworks/TableWidget/src/FWAdapterHeaderTableManager.h"
0024 #include "Fireworks/TableWidget/src/FWAdapterRowHeaderTableManager.h"
0025
0026
0027
0028
0029 static const UInt_t kRowOptions =
0030 static_cast<UInt_t>(kLHintsExpandX) | static_cast<UInt_t>(kLHintsFillX) | static_cast<UInt_t>(kLHintsShrinkX);
0031 static const UInt_t kColOptions =
0032 static_cast<UInt_t>(kLHintsExpandY) | static_cast<UInt_t>(kLHintsFillY) | static_cast<UInt_t>(kLHintsShrinkY);
0033
0034
0035
0036
0037
0038
0039
0040
0041 FWTableWidget::FWTableWidget(FWTableManagerBase* iManager, const TGWindow* p)
0042 : TGCompositeFrame(p),
0043 m_bodyTable(iManager),
0044 m_headerTable(iManager->hasLabelHeaders() ? new FWAdapterHeaderTableManager(iManager)
0045 : static_cast<FWTableManagerBase*>(nullptr)),
0046 m_rowHeaderTable(iManager->hasRowHeaders() ? new FWAdapterRowHeaderTableManager(iManager)
0047 : static_cast<FWTableManagerBase*>(nullptr)),
0048 m_header(nullptr),
0049 m_rowHeader(nullptr),
0050 m_showingVSlider(true),
0051 m_showingHSlider(true),
0052 m_sortedColumn(-1),
0053 m_descendingSort(true),
0054 m_forceLayout(false),
0055 m_headerBackground(nullptr),
0056 m_headerForeground(nullptr),
0057 m_lineSeparator(nullptr) {
0058 SetLayoutManager(new TGTableLayout(this, 3, 3));
0059
0060 if (nullptr != m_headerTable) {
0061 m_header = new FWTabularWidget(m_headerTable, this);
0062 AddFrame(m_header, new TGTableLayoutHints(1, 2, 0, 1, kLHintsTop | kLHintsLeft | kRowOptions));
0063 if (m_bodyTable->cellDataIsSortable())
0064 m_header->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
0065 "FWTableWidget",
0066 this,
0067 "buttonReleasedInHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
0068 }
0069 m_body = new FWTabularWidget(iManager, this, GetWhiteGC()());
0070
0071 AddFrame(m_body, new TGTableLayoutHints(1, 2, 1, 2, kLHintsTop | kLHintsLeft | kRowOptions | kColOptions));
0072 m_body->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
0073 "FWTableWidget",
0074 this,
0075 "buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
0076
0077
0078 std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
0079 if (nullptr != m_header) {
0080 std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
0081 for (std::vector<unsigned int>::iterator it = columnWidths.begin(),
0082 itEnd = columnWidths.end(),
0083 itHeader = headerWidths.begin();
0084 it != itEnd;
0085 ++it, ++itHeader) {
0086 if (*itHeader > *it) {
0087 *it = *itHeader;
0088 }
0089 }
0090 }
0091 if (nullptr != m_header) {
0092 m_header->setWidthOfTextInColumns(columnWidths);
0093 }
0094 m_body->setWidthOfTextInColumns(columnWidths);
0095 if (m_rowHeaderTable) {
0096 m_rowHeader = new FWTabularWidget(m_rowHeaderTable, this, GetWhiteGC()());
0097
0098
0099 AddFrame(m_rowHeader, new TGTableLayoutHints(0, 1, 1, 2, kLHintsTop | kLHintsLeft | kColOptions));
0100 m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
0101 "FWTableWidget",
0102 this,
0103 "buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
0104 m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
0105 "FWTableWidget",
0106 this,
0107 "buttonReleasedInRowHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
0108 m_rowHeader->setWidthOfTextInColumns(m_rowHeader->widthOfTextInColumns());
0109 }
0110
0111 m_hSlider = new TGHScrollBar(this);
0112 AddFrame(m_hSlider, new TGTableLayoutHints(1, 2, 2, 3, kRowOptions));
0113 m_hSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
0114 m_vSlider = new TGVScrollBar(this);
0115 m_vSlider->SetSmallIncrement(12);
0116 AddFrame(m_vSlider, new TGTableLayoutHints(2, 3, 1, 2, kColOptions));
0117 m_vSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
0118 MapSubwindows();
0119 Layout();
0120
0121
0122 m_hSlider->Associate(this);
0123 m_vSlider->Associate(this);
0124
0125 m_hSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
0126 m_vSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
0127 m_bodyTable->Connect("dataChanged()", "FWTableWidget", this, "dataChanged()");
0128 }
0129
0130
0131
0132
0133
0134
0135 FWTableWidget::~FWTableWidget() {
0136 if (nullptr != m_headerBackground) {
0137 gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerBackground->GetGC());
0138 }
0139 if (nullptr != m_headerForeground) {
0140 gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerForeground->GetGC());
0141 }
0142
0143 if (nullptr != m_lineSeparator) {
0144 gClient->GetResourcePool()->GetGCPool()->FreeGC(m_lineSeparator->GetGC());
0145 }
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 void FWTableWidget::sort(UInt_t iColumn, bool iDescendingSort) {
0164 if (nullptr != m_headerTable) {
0165 m_headerTable->sort(iColumn, iDescendingSort);
0166 }
0167 m_bodyTable->sort(iColumn, iDescendingSort);
0168 m_sortedColumn = iColumn;
0169 m_descendingSort = iDescendingSort;
0170
0171
0172
0173 }
0174
0175 void FWTableWidget::SetBackgroundColor(Pixel_t iColor) {
0176 TGFrame::SetBackgroundColor(iColor);
0177 if (m_rowHeaderTable) {
0178 m_rowHeader->SetBackgroundColor(iColor);
0179 fClient->NeedRedraw(m_rowHeader);
0180 }
0181 if (m_header) {
0182 m_header->SetBackgroundColor(iColor);
0183 fClient->NeedRedraw(m_header);
0184 }
0185 m_body->SetBackgroundColor(iColor);
0186 fClient->NeedRedraw(m_body);
0187 fClient->NeedRedraw(this);
0188 }
0189
0190 void FWTableWidget::SetHeaderBackgroundColor(Pixel_t iColor) {
0191 if (nullptr == m_headerBackground) {
0192 GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
0193 m_headerBackground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t, kTRUE);
0194 }
0195 m_headerBackground->SetForeground(iColor);
0196 if (nullptr != m_header) {
0197 m_header->setBackgroundAreaContext((*m_headerBackground)());
0198 }
0199 }
0200 void FWTableWidget::SetHeaderForegroundColor(Pixel_t iColor) {
0201 if (nullptr == m_headerForeground) {
0202 GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
0203 m_headerForeground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t, kTRUE);
0204 }
0205 m_headerForeground->SetForeground(iColor);
0206 if (nullptr != m_header) {
0207 m_header->setLineContext((*m_headerForeground)());
0208 }
0209 }
0210
0211 void FWTableWidget::SetLineSeparatorColor(Pixel_t iColor) {
0212 if (nullptr == m_lineSeparator) {
0213 GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
0214 m_lineSeparator = gClient->GetResourcePool()->GetGCPool()->GetGC(&t, kTRUE);
0215 }
0216 m_lineSeparator->SetForeground(iColor);
0217 m_body->setLineContext((*m_lineSeparator)());
0218 if (m_rowHeader) {
0219 m_rowHeader->setLineContext((*m_lineSeparator)());
0220 }
0221 }
0222
0223 void FWTableWidget::Resize(UInt_t w, UInt_t h) {
0224 handleResize(w, h);
0225 TGCompositeFrame::Resize(w, h);
0226 }
0227
0228 bool FWTableWidget::handleResize(UInt_t w, UInt_t h) {
0229
0230 bool redoLayout = false;
0231
0232 TGDimension def = m_body->GetDefaultSize();
0233 UInt_t fullWidth = def.fWidth;
0234 if (m_rowHeader) {
0235 fullWidth += m_rowHeader->GetDefaultSize().fWidth;
0236 }
0237
0238 UInt_t headerHeight = 0;
0239 if (m_header) {
0240 headerHeight = m_header->GetHeight();
0241 }
0242 UInt_t fullHeight = def.fHeight + headerHeight;
0243
0244 UInt_t sBarWidth = (h < fullHeight) ? m_vSlider->GetWidth() : 0;
0245 UInt_t sBarHeight = (w < fullWidth) ? m_hSlider->GetHeight() : 0;
0246 if (sBarWidth == 0 && sBarHeight > 0 && h < fullHeight + sBarHeight)
0247 sBarWidth = m_vSlider->GetWidth();
0248 else if (sBarHeight == 0 && sBarWidth > 0 && h < fullWidth + sBarWidth)
0249 sBarHeight = m_hSlider->GetHeight();
0250 fullWidth += sBarWidth;
0251 fullHeight += sBarHeight;
0252
0253 if (w < fullWidth) {
0254 if (!m_showingHSlider) {
0255 ShowFrame(m_hSlider);
0256 redoLayout = true;
0257 m_showingHSlider = true;
0258 }
0259 m_hSlider->SetRange(fullWidth, w);
0260 } else {
0261 if (m_showingHSlider) {
0262 HideFrame(m_hSlider);
0263 m_hSlider->SetPosition(0);
0264 m_showingHSlider = false;
0265 redoLayout = true;
0266 }
0267 }
0268
0269 if (h < fullHeight) {
0270 if (!m_showingVSlider) {
0271 ShowFrame(m_vSlider);
0272 m_showingVSlider = true;
0273 redoLayout = true;
0274 }
0275 m_vSlider->SetRange(fullHeight, h);
0276 } else {
0277 if (m_showingVSlider) {
0278 HideFrame(m_vSlider);
0279 m_vSlider->SetPosition(0);
0280 m_showingVSlider = false;
0281 redoLayout = true;
0282 }
0283 }
0284 if (redoLayout) {
0285 Layout();
0286 }
0287
0288 return redoLayout;
0289 }
0290
0291 void FWTableWidget::MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h) {
0292
0293 if (w != GetWidth() || h != GetHeight()) {
0294 handleResize(w, h);
0295 }
0296 TGCompositeFrame::MoveResize(x, y, w, h);
0297 }
0298
0299 Bool_t FWTableWidget::ProcessMessage(Long_t msg, Long_t parm1, Long_t) {
0300
0301
0302 switch (GET_MSG(msg)) {
0303 case kC_HSCROLL:
0304 switch (GET_SUBMSG(msg)) {
0305 case kSB_SLIDERTRACK:
0306 case kSB_SLIDERPOS:
0307 m_body->setHorizontalOffset(parm1);
0308 if (m_header) {
0309 m_header->setHorizontalOffset(parm1);
0310 }
0311 break;
0312 }
0313 break;
0314
0315 case kC_VSCROLL:
0316 switch (GET_SUBMSG(msg)) {
0317 case kSB_SLIDERTRACK:
0318 case kSB_SLIDERPOS:
0319 m_body->setVerticalOffset(parm1);
0320 if (m_rowHeader) {
0321 m_rowHeader->setVerticalOffset(parm1);
0322 }
0323 break;
0324 }
0325 break;
0326
0327 default:
0328 break;
0329 }
0330 return kTRUE;
0331 }
0332
0333 void FWTableWidget::buttonReleasedInHeader(Int_t row, Int_t column, Event_t* event, Int_t, Int_t) {
0334 Int_t btn = event->fCode;
0335 Int_t keyMod = event->fState;
0336
0337 if (btn == kButton1 || btn == kButton3) {
0338 if (m_sortedColumn == column) {
0339 sort(column, !m_descendingSort);
0340 } else {
0341 sort(column, true);
0342 }
0343 }
0344 columnClicked(column, btn, keyMod);
0345 }
0346
0347 void FWTableWidget::buttonReleasedInBody(Int_t row, Int_t column, Event_t* event, Int_t iRelX, Int_t iRelY) {
0348 Int_t btn = event->fCode;
0349 Int_t keyMod = event->fState;
0350 if (btn == kButton5) {
0351
0352 if (m_vSlider) {
0353 Int_t p = m_vSlider->GetPosition();
0354 Int_t mx = m_vSlider->GetRange();
0355 p += m_vSlider->GetSmallIncrement();
0356 if (p > mx) {
0357 p = mx;
0358 }
0359 m_vSlider->SetPosition(p);
0360 }
0361 return;
0362 }
0363 if (btn == kButton4) {
0364
0365 if (m_vSlider) {
0366 Int_t p = m_vSlider->GetPosition();
0367 p -= m_vSlider->GetSmallIncrement();
0368 if (0 > p) {
0369 p = 0;
0370 }
0371 m_vSlider->SetPosition(p);
0372 }
0373 return;
0374 }
0375 if (btn != kButton1 && btn != kButton3) {
0376 return;
0377 }
0378 if (row >= -1 and row < m_bodyTable->numberOfRows()) {
0379 Int_t globalX, globalY;
0380 Window_t childdum;
0381 gVirtualX->TranslateCoordinates(
0382 m_body->GetId(), gClient->GetDefaultRoot()->GetId(), event->fX, event->fY, globalX, globalY, childdum);
0383 cellClicked(m_bodyTable->unsortedRowNumber(row), column, btn, keyMod, globalX, globalY);
0384 rowClicked(m_bodyTable->unsortedRowNumber(row), btn, keyMod, globalX, globalY);
0385 }
0386 }
0387
0388 void FWTableWidget::cellClicked(Int_t row, Int_t column, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY) {
0389 keyMod = (keyMod & (kKeyShiftMask | kKeyControlMask));
0390
0391 Long_t args[6];
0392 args[0] = (Long_t)row;
0393 args[1] = (Long_t)column;
0394 args[2] = (Long_t)btn;
0395 args[3] = (Long_t)keyMod;
0396 args[4] = (Long_t)iGlobalX;
0397 args[5] = (Long_t)iGlobalY;
0398 Emit("cellClicked(Int_t,Int_t,Int_t,Int_t,Int_t,Int_t)", args);
0399 }
0400
0401 void FWTableWidget::childrenEvent(Event_t*) { Clicked(); }
0402
0403 void FWTableWidget::Clicked() { Emit("Clicked()"); }
0404
0405 void FWTableWidget::rowClicked(Int_t row, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY) {
0406 keyMod = (keyMod & (kKeyShiftMask | kKeyControlMask));
0407
0408 Long_t args[5];
0409 args[0] = (Long_t)row;
0410 args[1] = (Long_t)btn;
0411 args[2] = (Long_t)keyMod;
0412 args[3] = (Long_t)iGlobalX;
0413 args[4] = (Long_t)iGlobalY;
0414 Emit("rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)", args);
0415 }
0416
0417 void FWTableWidget::columnClicked(Int_t column, Int_t btn, Int_t keyMod) {
0418 keyMod = (keyMod & (kKeyShiftMask | kKeyControlMask));
0419
0420 Long_t args[3];
0421 args[0] = (Long_t)column;
0422 args[1] = (Long_t)btn;
0423 args[2] = (Long_t)keyMod;
0424 Emit("columnClicked(Int_t,Int_t,Int_t)", args);
0425 }
0426
0427 void FWTableWidget::dataChanged() {
0428 bool needs_layout = m_forceLayout;
0429 m_forceLayout = false;
0430
0431 m_body->dataChanged();
0432 if (m_rowHeader) {
0433 m_rowHeader->dataChanged();
0434 m_rowHeader->setWidthOfTextInColumns(m_rowHeader->widthOfTextInColumns());
0435 }
0436
0437 std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
0438 if (m_header) {
0439
0440 m_header->dataChanged();
0441 std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
0442 for (std::vector<unsigned int>::iterator it = columnWidths.begin(),
0443 itEnd = columnWidths.end(),
0444 itHeader = headerWidths.begin();
0445 it != itEnd;
0446 ++it, ++itHeader) {
0447 if (*itHeader > *it) {
0448 *it = *itHeader;
0449 }
0450 }
0451 m_header->setWidthOfTextInColumns(columnWidths);
0452 }
0453 m_body->setWidthOfTextInColumns(columnWidths);
0454
0455
0456 bool layoutDoneByhandleResize = handleResize(GetWidth(), GetHeight());
0457 if (needs_layout && !layoutDoneByhandleResize) {
0458 Layout();
0459 }
0460 gClient->NeedRedraw(m_body);
0461 if (m_header)
0462 gClient->NeedRedraw(m_header);
0463 if (m_rowHeader)
0464 gClient->NeedRedraw(m_rowHeader);
0465 }
0466
0467 void FWTableWidget::buttonPressedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY) {
0468 Int_t btn = event->fCode;
0469 if (btn != kButton1 && btn != kButton3) {
0470 return;
0471 }
0472 m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
0473 }
0474 void FWTableWidget::buttonReleasedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY) {
0475 Int_t btn = event->fCode;
0476 if (btn != kButton1 && btn != kButton3) {
0477 return;
0478 }
0479 m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
0480 }
0481
0482
0483
0484
0485 TGDimension FWTableWidget::GetDefaultSize() const {
0486 TGDimension returnValue;
0487 if (m_header) {
0488 returnValue.fHeight += m_header->GetDefaultHeight();
0489 }
0490 if (m_rowHeader) {
0491 returnValue.fWidth += m_rowHeader->GetDefaultWidth();
0492 }
0493 returnValue = returnValue + m_body->GetDefaultSize();
0494 returnValue.fHeight += m_hSlider->GetDefaultHeight();
0495 returnValue.fWidth += m_vSlider->GetDefaultWidth();
0496
0497 return returnValue;
0498 }
0499
0500 void FWTableWidget::disableGrowInWidth() {
0501 m_body->disableGrowInWidth();
0502 if (m_header)
0503 m_header->disableGrowInWidth();
0504 if (m_rowHeader)
0505 m_rowHeader->disableGrowInWidth();
0506 }
0507
0508 void FWTableWidget::DoRedraw() {
0509
0510 }
0511
0512
0513
0514
0515 ClassImp(FWTableWidget);