CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
20 // user include files
26 
27 static const unsigned long kWidgetColor = 0x2f2f2f;
28 
29 //
30 // constants, enums and typedefs
31 //
32 static const UInt_t kRowOptions = kLHintsExpandX|kLHintsFillX|kLHintsShrinkX;
33 static const UInt_t kColOptions = kLHintsExpandY|kLHintsFillY|kLHintsShrinkY;
34 
35 //
36 // static data member definitions
37 //
38 
39 //
40 // constructors and destructor
41 //
43 TGCompositeFrame(p),
44  m_bodyTable(iManager),
45  m_headerTable(iManager->hasLabelHeaders()?new FWAdapterHeaderTableManager(iManager): static_cast<FWTableManagerBase*>(0)),
46  m_rowHeaderTable(iManager->hasRowHeaders()?new FWAdapterRowHeaderTableManager(iManager): static_cast<FWTableManagerBase*>(0)),
47  m_header(0),
48  m_rowHeader(0),
49  m_showingVSlider(true),
50  m_showingHSlider(true),
51  m_sortedColumn(-1),
52  m_descendingSort(true),
53  m_forceLayout(false),
54  m_headerBackground(0),
55  m_headerForeground(0),
56  m_lineSeparator(0)
57 {
58  SetLayoutManager( new TGTableLayout(this,3,3) );
59 
60  if(0!=m_headerTable) {
62  AddFrame(m_header, new TGTableLayoutHints(1,2,0,1,kLHintsTop|kLHintsLeft|kRowOptions));
63  if (m_bodyTable->cellDataIsSortable()) m_header->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
64  }
65  m_body = new FWTabularWidget(iManager,this,GetWhiteGC()());
66  //m_body->SetBackgroundColor(kWidgetColor);
67  AddFrame(m_body, new TGTableLayoutHints(1,2,1,2,kLHintsTop|kLHintsLeft|kRowOptions|kColOptions));
68  m_body->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
69 
70  //set sizes
71  std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
72  if(0!=m_header) {
73  std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
74  for(std::vector<unsigned int>::iterator it = columnWidths.begin(), itEnd=columnWidths.end(), itHeader=headerWidths.begin();
75  it != itEnd;
76  ++it,++itHeader) {
77  if(*itHeader > *it) {
78  *it = *itHeader;
79  }
80  }
81  }
82  if(0!=m_header) {
83  m_header->setWidthOfTextInColumns(columnWidths);
84  }
85  m_body->setWidthOfTextInColumns(columnWidths);
86  if(m_rowHeaderTable) {
87  m_rowHeader = new FWTabularWidget(m_rowHeaderTable,this, GetWhiteGC()());
88  //m_rowHeader->SetBackgroundColor(kWidgetColor);
89 
90  AddFrame(m_rowHeader, new TGTableLayoutHints(0,1,1,2,kLHintsTop|kLHintsLeft|kColOptions));
91  m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
92  m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInRowHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
94  }
95 
96  m_hSlider = new TGHScrollBar(this);
97  AddFrame(m_hSlider, new TGTableLayoutHints(1,2,2,3,kRowOptions));
98  m_hSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
99  m_vSlider = new TGVScrollBar(this);
100  m_vSlider->SetSmallIncrement(12);
101  AddFrame(m_vSlider, new TGTableLayoutHints(2,3,1,2,kColOptions));
102  m_vSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
103  MapSubwindows();
104  Layout();
105  //HideFrame(m_hSlider);
106  //HideFrame(m_vSlider);
107  m_hSlider->Associate(this);
108  m_vSlider->Associate(this);
109 
110  m_hSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
111  m_vSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
112  m_bodyTable->Connect("dataChanged()","FWTableWidget",this,"dataChanged()");
113 }
114 
115 // FWTableWidget::FWTableWidget(const FWTableWidget& rhs)
116 // {
117 // // do actual copying here;
118 // }
119 
121 {
122  if(0!=m_headerBackground) {
123  gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerBackground->GetGC());
124  }
125  if(0!= m_headerForeground) {
126  gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerForeground->GetGC());
127  }
128 
129  if(0!= m_lineSeparator) {
130  gClient->GetResourcePool()->GetGCPool()->FreeGC(m_lineSeparator->GetGC());
131  }
132 
133 }
134 
135 //
136 // assignment operators
137 //
138 // const FWTableWidget& FWTableWidget::operator=(const FWTableWidget& rhs)
139 // {
140 // //An exception safe implementation is
141 // FWTableWidget temp(rhs);
142 // swap(rhs);
143 //
144 // return *this;
145 // }
146 
147 //
148 // member functions
149 //
150 void
151 FWTableWidget::sort(UInt_t iColumn, bool iDescendingSort)
152 {
153  if(0!=m_headerTable) {
154  m_headerTable->sort(iColumn,iDescendingSort);
155  }
156  m_bodyTable->sort(iColumn,iDescendingSort);
157  m_sortedColumn =iColumn;
158  m_descendingSort=iDescendingSort;
159 
160  //fClient->NeedRedraw(m_header);
161  //fClient->NeedRedraw(m_body);
162 }
163 
164 void
166 {
167  TGFrame::SetBackgroundColor(iColor);
168  if(m_rowHeaderTable) {
169  m_rowHeader->SetBackgroundColor(iColor);
170  fClient->NeedRedraw(m_rowHeader);
171  }
172  if(m_header) {
173  m_header->SetBackgroundColor(iColor);
174  fClient->NeedRedraw(m_header);
175  }
176  m_body->SetBackgroundColor(iColor);
177  fClient->NeedRedraw(m_body);
178  fClient->NeedRedraw(this);
179 }
180 
181 void
183 {
184  if(0==m_headerBackground) {
185  GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
186  m_headerBackground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
187  }
188  m_headerBackground->SetForeground(iColor);
189  if(0!=m_header) {
191  }
192 }
193 void
195 {
196  if(0==m_headerForeground) {
197  GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
198  m_headerForeground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
199  }
200  m_headerForeground->SetForeground(iColor);
201  if(0!=m_header) {
203  }
204 }
205 
206 void
208 {
209  if(0==m_lineSeparator) {
210  GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
211  m_lineSeparator = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
212  }
213  m_lineSeparator->SetForeground(iColor);
215  if(m_rowHeader) {
217  }
218 }
219 
220 
221 void
222 FWTableWidget::Resize(UInt_t w, UInt_t h)
223 {
224  handleResize(w,h);
225  TGCompositeFrame::Resize(w,h);
226 }
227 
228 bool
230 {
231  //std::cout <<"Resize"<<std::endl;
232  bool redoLayout=false;
233 
234  TGDimension def = m_body->GetDefaultSize();
235  UInt_t fullWidth = def.fWidth;
236  if(m_rowHeader) {
237  fullWidth += m_rowHeader->GetDefaultSize().fWidth;
238  }
239 
240  UInt_t headerHeight = 0;
241  if(m_header) {
242  headerHeight = m_header->GetHeight();
243  }
244  UInt_t fullHeight = def.fHeight + headerHeight;
245 
246  UInt_t sBarWidth = (h < fullHeight) ? m_vSlider->GetWidth() : 0;
247  UInt_t sBarHeight = (w < fullWidth) ? m_hSlider->GetHeight() : 0;
248  if (sBarWidth == 0 && sBarHeight > 0 && h < fullHeight + sBarHeight)
249  sBarWidth = m_vSlider->GetWidth();
250  else if (sBarHeight == 0 && sBarWidth > 0 && h < fullWidth + sBarWidth)
251  sBarHeight = m_hSlider->GetHeight();
252  fullWidth += sBarWidth;
253  fullHeight += sBarHeight;
254 
255  if(w < fullWidth) {
256  if(!m_showingHSlider) {
257  ShowFrame(m_hSlider);
258  redoLayout=true;
259  m_showingHSlider=true;
260  }
261  m_hSlider->SetRange(fullWidth,w);
262  } else {
263  if(m_showingHSlider) {
264  HideFrame(m_hSlider);
265  m_hSlider->SetPosition(0);
266  m_showingHSlider = false;
267  redoLayout=true;
268  }
269  }
270 
271  if(h < fullHeight) {
272  if(!m_showingVSlider) {
273  ShowFrame(m_vSlider);
274  m_showingVSlider=true;
275  redoLayout=true;
276  }
277  m_vSlider->SetRange(fullHeight,h);
278  } else {
279  if(m_showingVSlider) {
280  HideFrame(m_vSlider);
281  m_vSlider->SetPosition(0);
282  m_showingVSlider = false;
283  redoLayout=true;
284  }
285  }
286  if(redoLayout) {
287  Layout();
288  }
289 
290  return redoLayout;
291 }
292 
293 void
294 FWTableWidget::MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h)
295 {
296  //std::cout <<"MoveResize"<<std::endl;
297  if(w != GetWidth() || h != GetHeight()) {
298  handleResize(w,h);
299  }
300  TGCompositeFrame::MoveResize(x,y,w,h);
301 }
302 
303 Bool_t
304 FWTableWidget::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
305 {
306  // Handle message generated by the canvas scrollbars.
307 
308  switch (GET_MSG(msg)) {
309  case kC_HSCROLL:
310  switch (GET_SUBMSG(msg)) {
311  case kSB_SLIDERTRACK:
312  case kSB_SLIDERPOS:
313  m_body->setHorizontalOffset(parm1);
314  if(m_header) {
316  }
317  break;
318  }
319  break;
320 
321  case kC_VSCROLL:
322  switch (GET_SUBMSG(msg)) {
323  case kSB_SLIDERTRACK:
324  case kSB_SLIDERPOS:
325  m_body->setVerticalOffset(parm1);
326  if(m_rowHeader) {
328  }
329  break;
330  }
331  break;
332 
333  default:
334  break;
335  }
336  return kTRUE;
337 }
338 
339 void
340 FWTableWidget::buttonReleasedInHeader(Int_t row, Int_t column, Event_t* event,Int_t,Int_t)
341 {
342  Int_t btn = event->fCode;
343  Int_t keyMod = event->fState;
344  //Int_t keyMod = event->fState;
345  if (btn == kButton1 || btn == kButton3) {
346  if(m_sortedColumn==column) {
347  sort(column, !m_descendingSort);
348  } else {
349  sort(column,true);
350  }
351  }
352  columnClicked(column, btn, keyMod);
353 }
354 
355 void
356 FWTableWidget::buttonReleasedInBody(Int_t row, Int_t column, Event_t* event,Int_t iRelX,Int_t iRelY)
357 {
358  Int_t btn = event->fCode;
359  Int_t keyMod = event->fState;
360  if(btn == kButton5){
361  //should scroll down
362  if(m_vSlider) {
363  Int_t p = m_vSlider->GetPosition();
364  Int_t mx = m_vSlider->GetRange();
365  p+=m_vSlider->GetSmallIncrement();
366  if(p>mx){ p=mx;}
367  m_vSlider->SetPosition(p);
368  }
369  return;
370  }
371  if(btn == kButton4){
372  //should scroll up
373  if(m_vSlider) {
374  Int_t p = m_vSlider->GetPosition();
375  p -=m_vSlider->GetSmallIncrement();
376  if(0>p) {p=0;}
377  m_vSlider->SetPosition(p);
378  }
379  return;
380  }
381  if(btn != kButton1 && btn != kButton3) {return;}
382  if(row>=-1 and row < m_bodyTable->numberOfRows()) {
383  Int_t globalX,globalY;
384  Window_t childdum;
385  gVirtualX->TranslateCoordinates(m_body->GetId(),
386  gClient->GetDefaultRoot()->GetId(),
387  event->fX,event->fY,globalX,globalY,childdum);
388  cellClicked(m_bodyTable->unsortedRowNumber(row), column, btn, keyMod, globalX, globalY);
389  rowClicked(m_bodyTable->unsortedRowNumber(row), btn,keyMod,globalX,globalY);
390  }
391 }
392 
393 void
394 FWTableWidget::cellClicked(Int_t row, Int_t column, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY)
395 {
396  keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
397  //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
398  Long_t args[6];
399  args[0]=(Long_t)row;
400  args[1]=(Long_t)column;
401  args[2]=(Long_t)btn;
402  args[3]=(Long_t)keyMod;
403  args[4]=(Long_t)iGlobalX;
404  args[5]=(Long_t)iGlobalY;
405  Emit("cellClicked(Int_t,Int_t,Int_t,Int_t,Int_t,Int_t)",args);
406 }
407 
408 void
410 {
411  Clicked();
412 }
413 
414 void
416 {
417  Emit("Clicked()");
418 }
419 
420 void
421 FWTableWidget::rowClicked(Int_t row, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY)
422 {
423  keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
424  //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
425  Long_t args[5];
426  args[0]=(Long_t)row;
427  args[1]=(Long_t)btn;
428  args[2]=(Long_t)keyMod;
429  args[3]=(Long_t)iGlobalX;
430  args[4]=(Long_t)iGlobalY;
431  Emit("rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)",args);
432 }
433 
434 void
435 FWTableWidget::columnClicked(Int_t column, Int_t btn, Int_t keyMod)
436 {
437  keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
438  //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
439  Long_t args[3];
440  args[0]=(Long_t)column;
441  args[1]=(Long_t)btn;
442  args[2]=(Long_t)keyMod;
443  Emit("columnClicked(Int_t,Int_t,Int_t)",args);
444 }
445 
446 void
448 {
449  bool needs_layout = m_forceLayout; m_forceLayout = false;
450 
451  m_body->dataChanged();
452  if(m_rowHeader) {
455  }
456  //set sizes
457  std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
458  if(m_header) {
459  // reset header back to its internal max rather than the last width
460  m_header->dataChanged();
461  std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
462  for(std::vector<unsigned int>::iterator it = columnWidths.begin(), itEnd=columnWidths.end(), itHeader=headerWidths.begin();
463  it != itEnd;
464  ++it,++itHeader) {
465  if(*itHeader > *it) {
466  *it = *itHeader;
467  }
468  }
469  m_header->setWidthOfTextInColumns(columnWidths);
470  }
471  m_body->setWidthOfTextInColumns(columnWidths);
472 
473  //this updates sliders to match our new data
474  bool layoutDoneByhandleResize = handleResize(GetWidth(), GetHeight());
475  if (needs_layout && ! layoutDoneByhandleResize)
476  {
477  Layout();
478  }
479  gClient->NeedRedraw(m_body);
480  if (m_header) gClient->NeedRedraw(m_header);
481  if (m_rowHeader) gClient->NeedRedraw(m_rowHeader);
482 
483 }
484 
485 void
486 FWTableWidget::buttonPressedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
487 {
488  Int_t btn = event->fCode;
489  if(btn != kButton1 && btn != kButton3) {return;}
490  m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
491 }
492 void
493 FWTableWidget::buttonReleasedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
494 {
495  Int_t btn = event->fCode;
496  if(btn != kButton1 && btn != kButton3) {return;}
497  m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
498 }
499 
500 //
501 // const member functions
502 //
503 TGDimension
505 {
506  TGDimension returnValue;
507  if(m_header){
508  returnValue.fHeight += m_header->GetDefaultHeight();
509  }
510  if(m_rowHeader) {
511  returnValue.fWidth += m_rowHeader->GetDefaultWidth();
512  }
513  returnValue = returnValue + m_body->GetDefaultSize();
514  returnValue.fHeight += m_hSlider->GetDefaultHeight();
515  returnValue.fWidth += m_vSlider->GetDefaultWidth();
516 
517  return returnValue;
518 }
519 
520 void
522 {
526 }
527 
528 void
530 {
531  // override virtual TGFrame::DoRedraw() to prevent call of gVirtualX->ClearArea();
532 }
533 //
534 // static member functions
535 //
536 
537 ClassImp(FWTableWidget)
int def(FILE *, FILE *, int)
void SetBackgroundColor(Pixel_t)
virtual bool cellDataIsSortable() const
void buttonReleasedInRowHeader(Int_t row, Int_t column, Event_t *event, Int_t relX, Int_t relY)
virtual Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
FWTableManagerBase * m_bodyTable
TGVScrollBar * m_vSlider
TGGC * m_headerBackground
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)
bool handleResize(UInt_t w, UInt_t h)
TGDimension GetDefaultSize() const
void SetLineSeparatorColor(Pixel_t)
static const unsigned long kWidgetColor
void buttonReleasedInBody(Int_t row, Int_t column, Event_t *event, Int_t, Int_t)
virtual ~FWTableWidget()
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)
virtual void MoveResize(Int_t x, Int_t y, UInt_t w=0, UInt_t h=0)
TGDimension GetDefaultSize() const
TGGC * m_lineSeparator
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
virtual void buttonReleasedInRowHeader(Int_t row, Event_t *event, Int_t relX, Int_t relY)
virtual void DoRedraw()
void disableGrowInWidth()
void setHorizontalOffset(UInt_t)
const std::vector< unsigned int > & widthOfTextInColumns() const
static const UInt_t kRowOptions
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
#define column(...)
Definition: DbCore.h:74
FWTabularWidget * m_rowHeader
void columnClicked(Int_t iColumn, Int_t iButton, Int_t iKeyMod)
void setBackgroundAreaContext(GContext_t iContext)
void buttonPressedInRowHeader(Int_t row, Int_t column, Event_t *event, Int_t relX, Int_t relY)
dictionary args
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
virtual void Resize(UInt_t w, UInt_t h)
T w() const
volatile std::atomic< bool > shutdown_flag false
void buttonReleasedInHeader(Int_t row, Int_t column, Event_t *event, Int_t, Int_t)
Definition: DDAxes.h:10
FWTableManagerBase * m_headerTable
FWTabularWidget * m_header
FWTableManagerBase * m_rowHeaderTable
void setVerticalOffset(UInt_t)
TGHScrollBar * m_hSlider
FWTableWidget(FWTableManagerBase *iManager, const TGWindow *p=0)