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