00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <iostream>
00016 #include "TGScrollBar.h"
00017 #include "TGTableLayout.h"
00018 #include "TGResourcePool.h"
00019
00020
00021
00022 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
00023 #include "Fireworks/TableWidget/interface/FWTableManagerBase.h"
00024 #include "Fireworks/TableWidget/src/FWTabularWidget.h"
00025 #include "Fireworks/TableWidget/src/FWAdapterHeaderTableManager.h"
00026 #include "Fireworks/TableWidget/src/FWAdapterRowHeaderTableManager.h"
00027
00028 static const unsigned long kWidgetColor = 0x2f2f2f;
00029
00030
00031
00032
00033 static const UInt_t kRowOptions = kLHintsExpandX|kLHintsFillX|kLHintsShrinkX;
00034 static const UInt_t kColOptions = kLHintsExpandY|kLHintsFillY|kLHintsShrinkY;
00035
00036
00037
00038
00039
00040
00041
00042
00043 FWTableWidget::FWTableWidget(FWTableManagerBase* iManager,const TGWindow* p):
00044 TGCompositeFrame(p),
00045 m_bodyTable(iManager),
00046 m_headerTable(iManager->hasLabelHeaders()?new FWAdapterHeaderTableManager(iManager): static_cast<FWTableManagerBase*>(0)),
00047 m_rowHeaderTable(iManager->hasRowHeaders()?new FWAdapterRowHeaderTableManager(iManager): static_cast<FWTableManagerBase*>(0)),
00048 m_header(0),
00049 m_rowHeader(0),
00050 m_showingVSlider(true),
00051 m_showingHSlider(true),
00052 m_sortedColumn(-1),
00053 m_descendingSort(true),
00054 m_forceLayout(false),
00055 m_headerBackground(0),
00056 m_headerForeground(0),
00057 m_lineSeparator(0)
00058 {
00059 SetLayoutManager( new TGTableLayout(this,3,3) );
00060
00061 if(0!=m_headerTable) {
00062 m_header = new FWTabularWidget(m_headerTable,this);
00063 AddFrame(m_header, new TGTableLayoutHints(1,2,0,1,kLHintsTop|kLHintsLeft|kRowOptions));
00064 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)");
00065 }
00066 m_body = new FWTabularWidget(iManager,this,GetWhiteGC()());
00067
00068 AddFrame(m_body, new TGTableLayoutHints(1,2,1,2,kLHintsTop|kLHintsLeft|kRowOptions|kColOptions));
00069 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)");
00070
00071
00072 std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
00073 if(0!=m_header) {
00074 std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
00075 for(std::vector<unsigned int>::iterator it = columnWidths.begin(), itEnd=columnWidths.end(), itHeader=headerWidths.begin();
00076 it != itEnd;
00077 ++it,++itHeader) {
00078 if(*itHeader > *it) {
00079 *it = *itHeader;
00080 }
00081 }
00082 }
00083 if(0!=m_header) {
00084 m_header->setWidthOfTextInColumns(columnWidths);
00085 }
00086 m_body->setWidthOfTextInColumns(columnWidths);
00087 if(m_rowHeaderTable) {
00088 m_rowHeader = new FWTabularWidget(m_rowHeaderTable,this, GetWhiteGC()());
00089
00090
00091 AddFrame(m_rowHeader, new TGTableLayoutHints(0,1,1,2,kLHintsTop|kLHintsLeft|kColOptions));
00092 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)");
00093 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)");
00094 m_rowHeader->setWidthOfTextInColumns(m_rowHeader->widthOfTextInColumns());
00095 }
00096
00097 m_hSlider = new TGHScrollBar(this);
00098 AddFrame(m_hSlider, new TGTableLayoutHints(1,2,2,3,kRowOptions));
00099 m_hSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
00100 m_vSlider = new TGVScrollBar(this);
00101 m_vSlider->SetSmallIncrement(12);
00102 AddFrame(m_vSlider, new TGTableLayoutHints(2,3,1,2,kColOptions));
00103 m_vSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
00104 MapSubwindows();
00105 Layout();
00106
00107
00108 m_hSlider->Associate(this);
00109 m_vSlider->Associate(this);
00110
00111 m_hSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
00112 m_vSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
00113 m_bodyTable->Connect("dataChanged()","FWTableWidget",this,"dataChanged()");
00114 }
00115
00116
00117
00118
00119
00120
00121 FWTableWidget::~FWTableWidget()
00122 {
00123 if(0!=m_headerBackground) {
00124 gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerBackground->GetGC());
00125 }
00126 if(0!= m_headerForeground) {
00127 gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerForeground->GetGC());
00128 }
00129
00130 if(0!= m_lineSeparator) {
00131 gClient->GetResourcePool()->GetGCPool()->FreeGC(m_lineSeparator->GetGC());
00132 }
00133
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 void
00152 FWTableWidget::sort(UInt_t iColumn, bool iDescendingSort)
00153 {
00154 if(0!=m_headerTable) {
00155 m_headerTable->sort(iColumn,iDescendingSort);
00156 }
00157 m_bodyTable->sort(iColumn,iDescendingSort);
00158 m_sortedColumn =iColumn;
00159 m_descendingSort=iDescendingSort;
00160
00161
00162
00163 }
00164
00165 void
00166 FWTableWidget::SetBackgroundColor(Pixel_t iColor)
00167 {
00168 TGFrame::SetBackgroundColor(iColor);
00169 if(m_rowHeaderTable) {
00170 m_rowHeader->SetBackgroundColor(iColor);
00171 fClient->NeedRedraw(m_rowHeader);
00172 }
00173 if(m_header) {
00174 m_header->SetBackgroundColor(iColor);
00175 fClient->NeedRedraw(m_header);
00176 }
00177 m_body->SetBackgroundColor(iColor);
00178 fClient->NeedRedraw(m_body);
00179 fClient->NeedRedraw(this);
00180 }
00181
00182 void
00183 FWTableWidget::SetHeaderBackgroundColor(Pixel_t iColor)
00184 {
00185 if(0==m_headerBackground) {
00186 GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
00187 m_headerBackground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
00188 }
00189 m_headerBackground->SetForeground(iColor);
00190 if(0!=m_header) {
00191 m_header->setBackgroundAreaContext((*m_headerBackground)());
00192 }
00193 }
00194 void
00195 FWTableWidget::SetHeaderForegroundColor(Pixel_t iColor)
00196 {
00197 if(0==m_headerForeground) {
00198 GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
00199 m_headerForeground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
00200 }
00201 m_headerForeground->SetForeground(iColor);
00202 if(0!=m_header) {
00203 m_header->setLineContext((*m_headerForeground)());
00204 }
00205 }
00206
00207 void
00208 FWTableWidget::SetLineSeparatorColor(Pixel_t iColor)
00209 {
00210 if(0==m_lineSeparator) {
00211 GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
00212 m_lineSeparator = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
00213 }
00214 m_lineSeparator->SetForeground(iColor);
00215 m_body->setLineContext( (*m_lineSeparator)());
00216 if(m_rowHeader) {
00217 m_rowHeader->setLineContext( (*m_lineSeparator)() );
00218 }
00219 }
00220
00221
00222 void
00223 FWTableWidget::Resize(UInt_t w, UInt_t h)
00224 {
00225 handleResize(w,h);
00226 TGCompositeFrame::Resize(w,h);
00227 }
00228
00229 bool
00230 FWTableWidget::handleResize(UInt_t w, UInt_t h)
00231 {
00232
00233 bool redoLayout=false;
00234
00235 TGDimension def = m_body->GetDefaultSize();
00236 UInt_t fullWidth = def.fWidth;
00237 if(m_rowHeader) {
00238 fullWidth += m_rowHeader->GetDefaultSize().fWidth;
00239 }
00240
00241 UInt_t headerHeight = 0;
00242 if(m_header) {
00243 headerHeight = m_header->GetHeight();
00244 }
00245 UInt_t fullHeight = def.fHeight + headerHeight;
00246
00247 UInt_t sBarWidth = (h < fullHeight) ? m_vSlider->GetWidth() : 0;
00248 UInt_t sBarHeight = (w < fullWidth) ? m_hSlider->GetHeight() : 0;
00249 if (sBarWidth == 0 && sBarHeight > 0 && h < fullHeight + sBarHeight)
00250 sBarWidth = m_vSlider->GetWidth();
00251 else if (sBarHeight == 0 && sBarWidth > 0 && h < fullWidth + sBarWidth)
00252 sBarHeight = m_hSlider->GetHeight();
00253 fullWidth += sBarWidth;
00254 fullHeight += sBarHeight;
00255
00256 if(w < fullWidth) {
00257 if(!m_showingHSlider) {
00258 ShowFrame(m_hSlider);
00259 redoLayout=true;
00260 m_showingHSlider=true;
00261 }
00262 m_hSlider->SetRange(fullWidth,w);
00263 } else {
00264 if(m_showingHSlider) {
00265 HideFrame(m_hSlider);
00266 m_hSlider->SetPosition(0);
00267 m_showingHSlider = false;
00268 redoLayout=true;
00269 }
00270 }
00271
00272 if(h < fullHeight) {
00273 if(!m_showingVSlider) {
00274 ShowFrame(m_vSlider);
00275 m_showingVSlider=true;
00276 redoLayout=true;
00277 }
00278 m_vSlider->SetRange(fullHeight,h);
00279 } else {
00280 if(m_showingVSlider) {
00281 HideFrame(m_vSlider);
00282 m_vSlider->SetPosition(0);
00283 m_showingVSlider = false;
00284 redoLayout=true;
00285 }
00286 }
00287 if(redoLayout) {
00288 Layout();
00289 }
00290
00291 return redoLayout;
00292 }
00293
00294 void
00295 FWTableWidget::MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h)
00296 {
00297
00298 if(w != GetWidth() || h != GetHeight()) {
00299 handleResize(w,h);
00300 }
00301 TGCompositeFrame::MoveResize(x,y,w,h);
00302 }
00303
00304 Bool_t
00305 FWTableWidget::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
00306 {
00307
00308
00309 switch (GET_MSG(msg)) {
00310 case kC_HSCROLL:
00311 switch (GET_SUBMSG(msg)) {
00312 case kSB_SLIDERTRACK:
00313 case kSB_SLIDERPOS:
00314 m_body->setHorizontalOffset(parm1);
00315 if(m_header) {
00316 m_header->setHorizontalOffset(parm1);
00317 }
00318 break;
00319 }
00320 break;
00321
00322 case kC_VSCROLL:
00323 switch (GET_SUBMSG(msg)) {
00324 case kSB_SLIDERTRACK:
00325 case kSB_SLIDERPOS:
00326 m_body->setVerticalOffset(parm1);
00327 if(m_rowHeader) {
00328 m_rowHeader->setVerticalOffset(parm1);
00329 }
00330 break;
00331 }
00332 break;
00333
00334 default:
00335 break;
00336 }
00337 return kTRUE;
00338 }
00339
00340 void
00341 FWTableWidget::buttonReleasedInHeader(Int_t row, Int_t column, Event_t* event,Int_t,Int_t)
00342 {
00343 Int_t btn = event->fCode;
00344 Int_t keyMod = event->fState;
00345
00346 if (btn == kButton1 || btn == kButton3) {
00347 if(m_sortedColumn==column) {
00348 sort(column, !m_descendingSort);
00349 } else {
00350 sort(column,true);
00351 }
00352 }
00353 columnClicked(column, btn, keyMod);
00354 }
00355
00356 void
00357 FWTableWidget::buttonReleasedInBody(Int_t row, Int_t column, Event_t* event,Int_t iRelX,Int_t iRelY)
00358 {
00359 Int_t btn = event->fCode;
00360 Int_t keyMod = event->fState;
00361 if(btn == kButton5){
00362
00363 if(m_vSlider) {
00364 Int_t p = m_vSlider->GetPosition();
00365 Int_t mx = m_vSlider->GetRange();
00366 p+=m_vSlider->GetSmallIncrement();
00367 if(p>mx){ p=mx;}
00368 m_vSlider->SetPosition(p);
00369 }
00370 return;
00371 }
00372 if(btn == kButton4){
00373
00374 if(m_vSlider) {
00375 Int_t p = m_vSlider->GetPosition();
00376 p -=m_vSlider->GetSmallIncrement();
00377 if(0>p) {p=0;}
00378 m_vSlider->SetPosition(p);
00379 }
00380 return;
00381 }
00382 if(btn != kButton1 && btn != kButton3) {return;}
00383 if(row>=-1 and row < m_bodyTable->numberOfRows()) {
00384 Int_t globalX,globalY;
00385 Window_t childdum;
00386 gVirtualX->TranslateCoordinates(m_body->GetId(),
00387 gClient->GetDefaultRoot()->GetId(),
00388 event->fX,event->fY,globalX,globalY,childdum);
00389 cellClicked(m_bodyTable->unsortedRowNumber(row), column, btn, keyMod, globalX, globalY);
00390 rowClicked(m_bodyTable->unsortedRowNumber(row), btn,keyMod,globalX,globalY);
00391 }
00392 }
00393
00394 void
00395 FWTableWidget::cellClicked(Int_t row, Int_t column, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY)
00396 {
00397 keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
00398
00399 Long_t args[6];
00400 args[0]=(Long_t)row;
00401 args[1]=(Long_t)column;
00402 args[2]=(Long_t)btn;
00403 args[3]=(Long_t)keyMod;
00404 args[4]=(Long_t)iGlobalX;
00405 args[5]=(Long_t)iGlobalY;
00406 Emit("cellClicked(Int_t,Int_t,Int_t,Int_t,Int_t,Int_t)",args);
00407 }
00408
00409 void
00410 FWTableWidget::childrenEvent(Event_t *)
00411 {
00412 Clicked();
00413 }
00414
00415 void
00416 FWTableWidget::Clicked()
00417 {
00418 Emit("Clicked()");
00419 }
00420
00421 void
00422 FWTableWidget::rowClicked(Int_t row, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY)
00423 {
00424 keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
00425
00426 Long_t args[5];
00427 args[0]=(Long_t)row;
00428 args[1]=(Long_t)btn;
00429 args[2]=(Long_t)keyMod;
00430 args[3]=(Long_t)iGlobalX;
00431 args[4]=(Long_t)iGlobalY;
00432 Emit("rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)",args);
00433 }
00434
00435 void
00436 FWTableWidget::columnClicked(Int_t column, Int_t btn, Int_t keyMod)
00437 {
00438 keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
00439
00440 Long_t args[3];
00441 args[0]=(Long_t)column;
00442 args[1]=(Long_t)btn;
00443 args[2]=(Long_t)keyMod;
00444 Emit("columnClicked(Int_t,Int_t,Int_t)",args);
00445 }
00446
00447 void
00448 FWTableWidget::dataChanged()
00449 {
00450 bool needs_layout = m_forceLayout; m_forceLayout = false;
00451
00452 m_body->dataChanged();
00453 if(m_rowHeader) {
00454 m_rowHeader->dataChanged();
00455 m_rowHeader->setWidthOfTextInColumns(m_rowHeader->widthOfTextInColumns());
00456 }
00457
00458 std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
00459 if(m_header) {
00460
00461 m_header->dataChanged();
00462 std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
00463 for(std::vector<unsigned int>::iterator it = columnWidths.begin(), itEnd=columnWidths.end(), itHeader=headerWidths.begin();
00464 it != itEnd;
00465 ++it,++itHeader) {
00466 if(*itHeader > *it) {
00467 *it = *itHeader;
00468 }
00469 }
00470 m_header->setWidthOfTextInColumns(columnWidths);
00471 }
00472 m_body->setWidthOfTextInColumns(columnWidths);
00473
00474
00475 bool layoutDoneByhandleResize = handleResize(GetWidth(), GetHeight());
00476 if (needs_layout && ! layoutDoneByhandleResize)
00477 {
00478 Layout();
00479 }
00480 gClient->NeedRedraw(m_body);
00481 if (m_header) gClient->NeedRedraw(m_header);
00482 if (m_rowHeader) gClient->NeedRedraw(m_rowHeader);
00483
00484 }
00485
00486 void
00487 FWTableWidget::buttonPressedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
00488 {
00489 Int_t btn = event->fCode;
00490 if(btn != kButton1 && btn != kButton3) {return;}
00491 m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
00492 }
00493 void
00494 FWTableWidget::buttonReleasedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
00495 {
00496 Int_t btn = event->fCode;
00497 if(btn != kButton1 && btn != kButton3) {return;}
00498 m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
00499 }
00500
00501
00502
00503
00504 TGDimension
00505 FWTableWidget::GetDefaultSize() const
00506 {
00507 TGDimension returnValue;
00508 if(m_header){
00509 returnValue.fHeight += m_header->GetDefaultHeight();
00510 }
00511 if(m_rowHeader) {
00512 returnValue.fWidth += m_rowHeader->GetDefaultWidth();
00513 }
00514 returnValue = returnValue + m_body->GetDefaultSize();
00515 returnValue.fHeight += m_hSlider->GetDefaultHeight();
00516 returnValue.fWidth += m_vSlider->GetDefaultWidth();
00517
00518 return returnValue;
00519 }
00520
00521 void
00522 FWTableWidget::disableGrowInWidth()
00523 {
00524 m_body->disableGrowInWidth();
00525 if (m_header) m_header->disableGrowInWidth();
00526 if (m_rowHeader) m_rowHeader->disableGrowInWidth();
00527 }
00528
00529 void
00530 FWTableWidget::DoRedraw()
00531 {
00532
00533 }
00534
00535
00536
00537
00538 ClassImp(FWTableWidget)