Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:01:45

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