CMS 3D CMS Logo

FWTableWidget.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: TableWidget
4 // Class : FWTableWidget
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Mon Feb 2 16:45:42 EST 2009
11 //
12 
13 // system include files
14 #include <iostream>
15 #include "TGScrollBar.h"
16 #include "TGTableLayout.h"
17 #include "TGResourcePool.h"
18 
19 // user include files
25 
26 //
27 // constants, enums and typedefs
28 //
29 static const UInt_t kRowOptions =
30  static_cast<UInt_t>(kLHintsExpandX) | static_cast<UInt_t>(kLHintsFillX) | static_cast<UInt_t>(kLHintsShrinkX);
31 static const UInt_t kColOptions =
32  static_cast<UInt_t>(kLHintsExpandY) | static_cast<UInt_t>(kLHintsFillY) | static_cast<UInt_t>(kLHintsShrinkY);
33 
34 //
35 // static data member definitions
36 //
37 
38 //
39 // constructors and destructor
40 //
42  : TGCompositeFrame(p),
43  m_bodyTable(iManager),
44  m_headerTable(iManager->hasLabelHeaders() ? new FWAdapterHeaderTableManager(iManager)
45  : static_cast<FWTableManagerBase*>(nullptr)),
46  m_rowHeaderTable(iManager->hasRowHeaders() ? new FWAdapterRowHeaderTableManager(iManager)
47  : static_cast<FWTableManagerBase*>(nullptr)),
48  m_header(nullptr),
49  m_rowHeader(nullptr),
50  m_showingVSlider(true),
51  m_showingHSlider(true),
52  m_sortedColumn(-1),
53  m_descendingSort(true),
54  m_forceLayout(false),
55  m_headerBackground(nullptr),
56  m_headerForeground(nullptr),
57  m_lineSeparator(nullptr) {
58  SetLayoutManager(new TGTableLayout(this, 3, 3));
59 
60  if (nullptr != m_headerTable) {
62  AddFrame(m_header, new TGTableLayoutHints(1, 2, 0, 1, kLHintsTop | kLHintsLeft | kRowOptions));
64  m_header->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
65  "FWTableWidget",
66  this,
67  "buttonReleasedInHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
68  }
69  m_body = new FWTabularWidget(iManager, this, GetWhiteGC()());
70  //m_body->SetBackgroundColor(kWidgetColor);
71  AddFrame(m_body, new TGTableLayoutHints(1, 2, 1, 2, kLHintsTop | kLHintsLeft | kRowOptions | kColOptions));
72  m_body->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
73  "FWTableWidget",
74  this,
75  "buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
76 
77  //set sizes
78  std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
79  if (nullptr != m_header) {
80  std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
81  for (std::vector<unsigned int>::iterator it = columnWidths.begin(),
82  itEnd = columnWidths.end(),
83  itHeader = headerWidths.begin();
84  it != itEnd;
85  ++it, ++itHeader) {
86  if (*itHeader > *it) {
87  *it = *itHeader;
88  }
89  }
90  }
91  if (nullptr != m_header) {
92  m_header->setWidthOfTextInColumns(columnWidths);
93  }
94  m_body->setWidthOfTextInColumns(columnWidths);
95  if (m_rowHeaderTable) {
96  m_rowHeader = new FWTabularWidget(m_rowHeaderTable, this, GetWhiteGC()());
97  //m_rowHeader->SetBackgroundColor(kWidgetColor);
98 
99  AddFrame(m_rowHeader, new TGTableLayoutHints(0, 1, 1, 2, kLHintsTop | kLHintsLeft | kColOptions));
100  m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
101  "FWTableWidget",
102  this,
103  "buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
104  m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)",
105  "FWTableWidget",
106  this,
107  "buttonReleasedInRowHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
109  }
110 
111  m_hSlider = new TGHScrollBar(this);
112  AddFrame(m_hSlider, new TGTableLayoutHints(1, 2, 2, 3, kRowOptions));
113  m_hSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
114  m_vSlider = new TGVScrollBar(this);
115  m_vSlider->SetSmallIncrement(12);
116  AddFrame(m_vSlider, new TGTableLayoutHints(2, 3, 1, 2, kColOptions));
117  m_vSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
118  MapSubwindows();
119  Layout();
120  //HideFrame(m_hSlider);
121  //HideFrame(m_vSlider);
122  m_hSlider->Associate(this);
123  m_vSlider->Associate(this);
124 
125  m_hSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
126  m_vSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
127  m_bodyTable->Connect("dataChanged()", "FWTableWidget", this, "dataChanged()");
128 }
129 
130 // FWTableWidget::FWTableWidget(const FWTableWidget& rhs)
131 // {
132 // // do actual copying here;
133 // }
134 
136  if (nullptr != m_headerBackground) {
137  gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerBackground->GetGC());
138  }
139  if (nullptr != m_headerForeground) {
140  gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerForeground->GetGC());
141  }
142 
143  if (nullptr != m_lineSeparator) {
144  gClient->GetResourcePool()->GetGCPool()->FreeGC(m_lineSeparator->GetGC());
145  }
146 }
147 
148 //
149 // assignment operators
150 //
151 // const FWTableWidget& FWTableWidget::operator=(const FWTableWidget& rhs)
152 // {
153 // //An exception safe implementation is
154 // FWTableWidget temp(rhs);
155 // swap(rhs);
156 //
157 // return *this;
158 // }
159 
160 //
161 // member functions
162 //
163 void FWTableWidget::sort(UInt_t iColumn, bool iDescendingSort) {
164  if (nullptr != m_headerTable) {
165  m_headerTable->sort(iColumn, iDescendingSort);
166  }
167  m_bodyTable->sort(iColumn, iDescendingSort);
168  m_sortedColumn = iColumn;
169  m_descendingSort = iDescendingSort;
170 
171  //fClient->NeedRedraw(m_header);
172  //fClient->NeedRedraw(m_body);
173 }
174 
175 void FWTableWidget::SetBackgroundColor(Pixel_t iColor) {
176  TGFrame::SetBackgroundColor(iColor);
177  if (m_rowHeaderTable) {
178  m_rowHeader->SetBackgroundColor(iColor);
179  fClient->NeedRedraw(m_rowHeader);
180  }
181  if (m_header) {
182  m_header->SetBackgroundColor(iColor);
183  fClient->NeedRedraw(m_header);
184  }
185  m_body->SetBackgroundColor(iColor);
186  fClient->NeedRedraw(m_body);
187  fClient->NeedRedraw(this);
188 }
189 
191  if (nullptr == m_headerBackground) {
192  GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
193  m_headerBackground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t, kTRUE);
194  }
195  m_headerBackground->SetForeground(iColor);
196  if (nullptr != m_header) {
198  }
199 }
201  if (nullptr == m_headerForeground) {
202  GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
203  m_headerForeground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t, kTRUE);
204  }
205  m_headerForeground->SetForeground(iColor);
206  if (nullptr != m_header) {
208  }
209 }
210 
212  if (nullptr == m_lineSeparator) {
213  GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
214  m_lineSeparator = gClient->GetResourcePool()->GetGCPool()->GetGC(&t, kTRUE);
215  }
216  m_lineSeparator->SetForeground(iColor);
218  if (m_rowHeader) {
220  }
221 }
222 
223 void FWTableWidget::Resize(UInt_t w, UInt_t h) {
224  handleResize(w, h);
225  TGCompositeFrame::Resize(w, h);
226 }
227 
228 bool FWTableWidget::handleResize(UInt_t w, UInt_t h) {
229  //std::cout <<"Resize"<<std::endl;
230  bool redoLayout = false;
231 
232  TGDimension def = m_body->GetDefaultSize();
233  UInt_t fullWidth = def.fWidth;
234  if (m_rowHeader) {
235  fullWidth += m_rowHeader->GetDefaultSize().fWidth;
236  }
237 
238  UInt_t headerHeight = 0;
239  if (m_header) {
240  headerHeight = m_header->GetHeight();
241  }
242  UInt_t fullHeight = def.fHeight + headerHeight;
243 
244  UInt_t sBarWidth = (h < fullHeight) ? m_vSlider->GetWidth() : 0;
245  UInt_t sBarHeight = (w < fullWidth) ? m_hSlider->GetHeight() : 0;
246  if (sBarWidth == 0 && sBarHeight > 0 && h < fullHeight + sBarHeight)
247  sBarWidth = m_vSlider->GetWidth();
248  else if (sBarHeight == 0 && sBarWidth > 0 && h < fullWidth + sBarWidth)
249  sBarHeight = m_hSlider->GetHeight();
250  fullWidth += sBarWidth;
251  fullHeight += sBarHeight;
252 
253  if (w < fullWidth) {
254  if (!m_showingHSlider) {
255  ShowFrame(m_hSlider);
256  redoLayout = true;
257  m_showingHSlider = true;
258  }
259  m_hSlider->SetRange(fullWidth, w);
260  } else {
261  if (m_showingHSlider) {
262  HideFrame(m_hSlider);
263  m_hSlider->SetPosition(0);
264  m_showingHSlider = false;
265  redoLayout = true;
266  }
267  }
268 
269  if (h < fullHeight) {
270  if (!m_showingVSlider) {
271  ShowFrame(m_vSlider);
272  m_showingVSlider = true;
273  redoLayout = true;
274  }
275  m_vSlider->SetRange(fullHeight, h);
276  } else {
277  if (m_showingVSlider) {
278  HideFrame(m_vSlider);
279  m_vSlider->SetPosition(0);
280  m_showingVSlider = false;
281  redoLayout = true;
282  }
283  }
284  if (redoLayout) {
285  Layout();
286  }
287 
288  return redoLayout;
289 }
290 
291 void FWTableWidget::MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h) {
292  //std::cout <<"MoveResize"<<std::endl;
293  if (w != GetWidth() || h != GetHeight()) {
294  handleResize(w, h);
295  }
296  TGCompositeFrame::MoveResize(x, y, w, h);
297 }
298 
299 Bool_t FWTableWidget::ProcessMessage(Long_t msg, Long_t parm1, Long_t) {
300  // Handle message generated by the canvas scrollbars.
301 
302  switch (GET_MSG(msg)) {
303  case kC_HSCROLL:
304  switch (GET_SUBMSG(msg)) {
305  case kSB_SLIDERTRACK:
306  case kSB_SLIDERPOS:
307  m_body->setHorizontalOffset(parm1);
308  if (m_header) {
310  }
311  break;
312  }
313  break;
314 
315  case kC_VSCROLL:
316  switch (GET_SUBMSG(msg)) {
317  case kSB_SLIDERTRACK:
318  case kSB_SLIDERPOS:
319  m_body->setVerticalOffset(parm1);
320  if (m_rowHeader) {
322  }
323  break;
324  }
325  break;
326 
327  default:
328  break;
329  }
330  return kTRUE;
331 }
332 
333 void FWTableWidget::buttonReleasedInHeader(Int_t row, Int_t column, Event_t* event, Int_t, Int_t) {
334  Int_t btn = event->fCode;
335  Int_t keyMod = event->fState;
336  //Int_t keyMod = event->fState;
337  if (btn == kButton1 || btn == kButton3) {
338  if (m_sortedColumn == column) {
339  sort(column, !m_descendingSort);
340  } else {
341  sort(column, true);
342  }
343  }
344  columnClicked(column, btn, keyMod);
345 }
346 
347 void FWTableWidget::buttonReleasedInBody(Int_t row, Int_t column, Event_t* event, Int_t iRelX, Int_t iRelY) {
348  Int_t btn = event->fCode;
349  Int_t keyMod = event->fState;
350  if (btn == kButton5) {
351  //should scroll down
352  if (m_vSlider) {
353  Int_t p = m_vSlider->GetPosition();
354  Int_t mx = m_vSlider->GetRange();
355  p += m_vSlider->GetSmallIncrement();
356  if (p > mx) {
357  p = mx;
358  }
359  m_vSlider->SetPosition(p);
360  }
361  return;
362  }
363  if (btn == kButton4) {
364  //should scroll up
365  if (m_vSlider) {
366  Int_t p = m_vSlider->GetPosition();
367  p -= m_vSlider->GetSmallIncrement();
368  if (0 > p) {
369  p = 0;
370  }
371  m_vSlider->SetPosition(p);
372  }
373  return;
374  }
375  if (btn != kButton1 && btn != kButton3) {
376  return;
377  }
378  if (row >= -1 and row < m_bodyTable->numberOfRows()) {
379  Int_t globalX, globalY;
380  Window_t childdum;
381  gVirtualX->TranslateCoordinates(
382  m_body->GetId(), gClient->GetDefaultRoot()->GetId(), event->fX, event->fY, globalX, globalY, childdum);
383  cellClicked(m_bodyTable->unsortedRowNumber(row), column, btn, keyMod, globalX, globalY);
384  rowClicked(m_bodyTable->unsortedRowNumber(row), btn, keyMod, globalX, globalY);
385  }
386 }
387 
388 void FWTableWidget::cellClicked(Int_t row, Int_t column, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY) {
389  keyMod = (keyMod & (kKeyShiftMask | kKeyControlMask));
390  //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
391  Long_t args[6];
392  args[0] = (Long_t)row;
393  args[1] = (Long_t)column;
394  args[2] = (Long_t)btn;
395  args[3] = (Long_t)keyMod;
396  args[4] = (Long_t)iGlobalX;
397  args[5] = (Long_t)iGlobalY;
398  Emit("cellClicked(Int_t,Int_t,Int_t,Int_t,Int_t,Int_t)", args);
399 }
400 
402 
403 void FWTableWidget::Clicked() { Emit("Clicked()"); }
404 
405 void FWTableWidget::rowClicked(Int_t row, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY) {
406  keyMod = (keyMod & (kKeyShiftMask | kKeyControlMask));
407  //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
408  Long_t args[5];
409  args[0] = (Long_t)row;
410  args[1] = (Long_t)btn;
411  args[2] = (Long_t)keyMod;
412  args[3] = (Long_t)iGlobalX;
413  args[4] = (Long_t)iGlobalY;
414  Emit("rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)", args);
415 }
416 
417 void FWTableWidget::columnClicked(Int_t column, Int_t btn, Int_t keyMod) {
418  keyMod = (keyMod & (kKeyShiftMask | kKeyControlMask));
419  //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
420  Long_t args[3];
421  args[0] = (Long_t)column;
422  args[1] = (Long_t)btn;
423  args[2] = (Long_t)keyMod;
424  Emit("columnClicked(Int_t,Int_t,Int_t)", args);
425 }
426 
428  bool needs_layout = m_forceLayout;
429  m_forceLayout = false;
430 
431  m_body->dataChanged();
432  if (m_rowHeader) {
435  }
436  //set sizes
437  std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
438  if (m_header) {
439  // reset header back to its internal max rather than the last width
441  std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
442  for (std::vector<unsigned int>::iterator it = columnWidths.begin(),
443  itEnd = columnWidths.end(),
444  itHeader = headerWidths.begin();
445  it != itEnd;
446  ++it, ++itHeader) {
447  if (*itHeader > *it) {
448  *it = *itHeader;
449  }
450  }
451  m_header->setWidthOfTextInColumns(columnWidths);
452  }
453  m_body->setWidthOfTextInColumns(columnWidths);
454 
455  //this updates sliders to match our new data
456  bool layoutDoneByhandleResize = handleResize(GetWidth(), GetHeight());
457  if (needs_layout && !layoutDoneByhandleResize) {
458  Layout();
459  }
460  gClient->NeedRedraw(m_body);
461  if (m_header)
462  gClient->NeedRedraw(m_header);
463  if (m_rowHeader)
464  gClient->NeedRedraw(m_rowHeader);
465 }
466 
467 void FWTableWidget::buttonPressedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY) {
468  Int_t btn = event->fCode;
469  if (btn != kButton1 && btn != kButton3) {
470  return;
471  }
472  m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
473 }
474 void FWTableWidget::buttonReleasedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY) {
475  Int_t btn = event->fCode;
476  if (btn != kButton1 && btn != kButton3) {
477  return;
478  }
479  m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
480 }
481 
482 //
483 // const member functions
484 //
485 TGDimension FWTableWidget::GetDefaultSize() const {
486  TGDimension returnValue;
487  if (m_header) {
488  returnValue.fHeight += m_header->GetDefaultHeight();
489  }
490  if (m_rowHeader) {
491  returnValue.fWidth += m_rowHeader->GetDefaultWidth();
492  }
493  returnValue = returnValue + m_body->GetDefaultSize();
494  returnValue.fHeight += m_hSlider->GetDefaultHeight();
495  returnValue.fWidth += m_vSlider->GetDefaultWidth();
496 
497  return returnValue;
498 }
499 
502  if (m_header)
504  if (m_rowHeader)
506 }
507 
509  // override virtual TGFrame::DoRedraw() to prevent call of gVirtualX->ClearArea();
510 }
511 //
512 // static member functions
513 //
514 
void Resize(UInt_t w, UInt_t h) override
int def(FILE *, FILE *, int)
void DoRedraw() override
void buttonReleasedInRowHeader(Int_t row, Int_t column, Event_t *event, Int_t relX, Int_t relY)
virtual bool cellDataIsSortable() const
FWTableManagerBase * m_bodyTable
TGVScrollBar * m_vSlider
T w() const
TGGC * m_headerBackground
void MoveResize(Int_t x, Int_t y, UInt_t w=0, UInt_t h=0) override
void sort(int iCol, bool iSortOrder)
Call to have table sorted on values in column iCol with the sort order being descending if iSortOrder...
void SetHeaderBackgroundColor(Pixel_t)
void setLineContext(GContext_t iContext)
TGDimension GetDefaultSize() const override
TGDimension GetDefaultSize() const override
ClassImp(FWTableWidget)
bool handleResize(UInt_t w, UInt_t h)
void SetLineSeparatorColor(Pixel_t)
FWTableWidget(FWTableManagerBase *iManager, const TGWindow *p=nullptr)
void buttonReleasedInBody(Int_t row, Int_t column, Event_t *event, Int_t, Int_t)
void sort(UInt_t iColumn, bool iDescendingSort)
void disableGrowInWidth()
void setWidthOfTextInColumns(const std::vector< unsigned int > &)
FWTabularWidget * m_body
virtual int unsortedRowNumber(int iSortedRowNumber) const =0
when passed the index to the sorted order of the rows it returns the original row number from the und...
TGGC * m_headerForeground
void cellClicked(Int_t iRow, Int_t iColumn, Int_t iButton, Int_t iKeyMod, Int_t iGlobalX, Int_t iGlobalY)
Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) override
TGGC * m_lineSeparator
virtual void buttonReleasedInRowHeader(Int_t row, Event_t *event, Int_t relX, Int_t relY)
void disableGrowInWidth()
void setHorizontalOffset(UInt_t)
void SetBackgroundColor(Pixel_t) override
static const UInt_t kRowOptions
FWTabularWidget * m_rowHeader
void columnClicked(Int_t iColumn, Int_t iButton, Int_t iKeyMod)
tuple msg
Definition: mps_check.py:286
void setBackgroundAreaContext(GContext_t iContext)
~FWTableWidget() override
void buttonPressedInRowHeader(Int_t row, Int_t column, Event_t *event, Int_t relX, Int_t relY)
void childrenEvent(Event_t *)
void rowClicked(Int_t iRow, Int_t iButton, Int_t iKeyMod, Int_t iGlobalX, Int_t iGlobalY)
void SetHeaderForegroundColor(Pixel_t)
static const UInt_t kColOptions
float x
const std::vector< unsigned int > & widthOfTextInColumns() const
void buttonReleasedInHeader(Int_t row, Int_t column, Event_t *event, Int_t, Int_t)
FWTableManagerBase * m_headerTable
FWTabularWidget * m_header
FWTableManagerBase * m_rowHeaderTable
void setVerticalOffset(UInt_t)
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
Definition: event.py:1
TGHScrollBar * m_hSlider