Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-06 04:26:50

0001 // -*- C++ -*-
0002 //
0003 // Package:     TableWidget
0004 // Class  :     FWTableWidget
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Mon Feb  2 16:45:42 EST 2009
0011 //
0012 
0013 // system include files
0014 #include <iostream>
0015 #include "TGScrollBar.h"
0016 #include "TGTableLayout.h"
0017 #include "TGResourcePool.h"
0018 
0019 // user include files
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 // constants, enums and typedefs
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 // static data member definitions
0036 //
0037 
0038 //
0039 // constructors and destructor
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   //m_body->SetBackgroundColor(kWidgetColor);
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   //set sizes
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     //m_rowHeader->SetBackgroundColor(kWidgetColor);
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   //HideFrame(m_hSlider);
0121   //HideFrame(m_vSlider);
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 // FWTableWidget::FWTableWidget(const FWTableWidget& rhs)
0131 // {
0132 //    // do actual copying here;
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 // assignment operators
0150 //
0151 // const FWTableWidget& FWTableWidget::operator=(const FWTableWidget& rhs)
0152 // {
0153 //   //An exception safe implementation is
0154 //   FWTableWidget temp(rhs);
0155 //   swap(rhs);
0156 //
0157 //   return *this;
0158 // }
0159 
0160 //
0161 // member functions
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   //fClient->NeedRedraw(m_header);
0172   //fClient->NeedRedraw(m_body);
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   //std::cout <<"Resize"<<std::endl;
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   //std::cout <<"MoveResize"<<std::endl;
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   // Handle message generated by the canvas scrollbars.
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   //Int_t keyMod = event->fState;
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     //should scroll down
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     //should scroll up
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   //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
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   //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
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   //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
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   //set sizes
0437   std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
0438   if (m_header) {
0439     // reset header back to its internal max rather than the last width
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   //this updates sliders to match our new data
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 // const member functions
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   // override virtual TGFrame::DoRedraw() to prevent call of gVirtualX->ClearArea();
0510 }
0511 //
0512 // static member functions
0513 //
0514 
0515 ClassImp(FWTableWidget);