nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "Nux.h" 00024 #include "HScrollBar.h" 00025 #include "VScrollBar.h" 00026 #include "HLayout.h" 00027 #include "VLayout.h" 00028 #include "WindowCompositor.h" 00029 #include "TableCtrl.h" 00030 00031 namespace nux 00032 { 00033 00034 const int HANDLERSIZE = 6; 00035 extern const int ITEMDEFAULTWIDTH; 00036 extern const int ITEMDEFAULTHEIGHT; 00037 const Color HEADER_BACKGROUND_COLOR = Color (0xFF666666); 00038 00039 const int ROWHEADERWIDTH = 30; 00040 const int OPENCLOSE_BTN_WIDTH = 15; 00041 const int ITEM_DEPTH_MARGIN = 20; 00042 const int MIN_COLUMN_WIDTH = 10; 00043 const int TABLE_AREA_BOTTOM_SPACE = 0; 00044 const int COLUMNHEADERHEIGHT = 20; 00045 00046 Color TABLE_HEADER_BASE_COLOR = Color (0xFF191919); 00047 Color TABLE_HEADER_TEXT_COLOR = Color (0xFFFFFFFF); 00048 // ROWHEADERWIDTH 00049 // ------------------------------DEFAULTWIDTH-------------------------- 00050 // | | | | 00051 // COLUMNHEADERHEIGHT | | | <---- Column Header 00052 // |_____________________|_______________________|______________________| 00053 // | | | | 00054 // | | | | 00055 // DEFAULTHEIGHT | | | 00056 // | | | | 00057 // |_____________________|_______________________|______________________| 00058 // | 00059 // 00060 // ^ 00061 // | 00062 // | 00063 // | 00064 // Row Header 00065 00066 TableCtrl::TableCtrl (bool floating_column) 00067 { 00068 m_bEnableRowResizing = false; 00069 m_bEnableColumnResizing = true; 00070 m_bShowRowHeader = true; 00071 m_bShowColumnHeader = true; 00072 m_bShowVerticalSeparationLine = true; 00073 m_bShowHorizontalSeparationLine = false; 00074 m_bEnableItemBestHeight = true; 00075 m_FloatingColumn = floating_column; 00076 m_ClickSelect = CLICK_SELECT_CELL; 00077 m_RowColorOdd = Color (0xFF343434); 00078 m_RowColorEven = Color (0xFF3f3f3f); 00079 m_TableBottomColor = Color (0xFF555555); 00080 m_SelectionColor = Color (0xFF202020); 00081 m_MouseOverColor = Color (0xFF666666); 00082 m_HorizontalSeparationLineColor = Color (0xFF747474); 00083 m_VerticalSeparationLineColor = Color (0xFF747474); 00084 m_IsEnableMouseOverColor = false; 00085 m_DrawBackgroundOnPreviousGeometry = false; 00086 m_TableItemHead = 0; 00087 00088 m_TableItemHead = new TableItem (TEXT ("TableRootNode") ); 00089 m_TableItemHead->m_Table = this; 00090 m_TableItemHead->Open(); 00091 m_TableItemHead->Show(); 00092 00093 m_TableArea = new InputArea (NUX_TRACKER_LOCATION); 00094 m_TableArea->mouse_down.connect (sigc::mem_fun (this, &TableCtrl::OnMouseDown) ); 00095 m_TableArea->mouse_double_click.connect (sigc::mem_fun (this, &TableCtrl::mouse_double_click) ); 00096 m_TableArea->mouse_up.connect (sigc::mem_fun (this, &TableCtrl::OnMouseUp) ); 00097 m_TableArea->mouse_drag.connect (sigc::mem_fun (this, &TableCtrl::mouse_drag) ); 00098 m_TableArea->begin_key_focus.connect (sigc::mem_fun (this, &TableCtrl::OnKeyboardFocus) ); 00099 m_TableArea->end_key_focus.connect (sigc::mem_fun (this, &TableCtrl::OnLostKeyboardFocus) ); 00100 00101 00102 00103 m_tableNumRow = 0; 00104 m_tableNumColumn = 0; 00105 00106 m_selectedRow = -1; 00107 m_selectedColumn = -1; 00108 00109 m_selectedTableItem = 0; 00110 m_selectedMouseDownTableItem = 0; 00111 m_OpenItemTotalHeight = 0; 00112 00113 EnableVerticalScrollBar (true); 00114 EnableHorizontalScrollBar (true); 00115 00116 m_VLayout = new VLayout (TEXT ("TABLELAYOUT"), NUX_TRACKER_LOCATION); 00117 m_VLayout->SetVerticalInternalMargin (4); 00118 00119 m_TableArea->SetGeometry (0, 0, 300, 40); 00120 // Setting the minimum of size m_TableArea forces the composition layout fit match the size of the Table area (+/- margins). if the layout is too large, then 00121 // the scrollbar will reflect that. 00122 // It is not enough to do something like: 00123 // m_VLayout->AddLayout(new WidgetLayout(&m_TableArea), 0, eLeft, eFull); 00124 // with a stretch factor equal to 0. Because m_VLayout is either a HLayout or a VLayout (here it is a VLayout), only one dimension of the composition layout 00125 // will match the similar dimension of TableArea. So only one scrollbar (Horizontal or Vertical) will be adjusted. 00126 // See FormatTable. 00127 m_VLayout->AddView (m_TableArea, 1, eLeft, eFull); 00128 m_VLayout->SetContentDistribution (eStackTop); 00129 m_VLayout->SetStretchFactor (1); 00130 SetMinimumSize (50, 50); 00131 SetGeometry (Geometry (0, 0, 50, 50) ); 00132 00133 m_top_border = 0; 00134 m_border = 0; 00135 00136 SetViewContentRightMargin (2); 00137 SetViewContentBottomMargin (2); 00138 00139 SetCompositionLayout (m_VLayout); 00140 FormatContent(); 00141 00142 m_TableArea->EnableDoubleClick (false); 00143 00144 ShowRowHeader (true); 00145 ShowColumnHeader (true); 00146 } 00147 00148 TableCtrl::~TableCtrl() 00149 { 00150 std::vector<ColumnHeader>::iterator it1; 00151 std::vector<RowHeader *>::iterator it2; 00152 std::vector<sizehandler2 *>::iterator it3; 00153 00154 EmptyTable(); 00155 00156 for (it2 = m_row_header.begin(); it2 != m_row_header.end(); it2++) 00157 { 00158 delete (*it2); 00159 } 00160 00161 for (it3 = m_column_sizehandler.begin(); it3 != m_column_sizehandler.end(); it3++) 00162 { 00163 (*it3)->UnReference(); 00164 } 00165 00166 for (it3 = m_row_sizehandler.begin(); it3 != m_row_sizehandler.end(); it3++) 00167 { 00168 (*it3)->UnReference(); 00169 } 00170 00171 //delete m_VLayout; 00172 } 00173 00174 long TableCtrl::ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00175 { 00176 long ret = TraverseInfo; 00177 long ProcEvInfo = ProcessEventInfo; 00178 bool AllowCellSelection = (TraverseInfo & eMouseEventSolved) ? false : true; 00179 00180 if (ievent.e_event == NUX_MOUSE_PRESSED) 00181 { 00182 Geometry ViewGeometry = Geometry (m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight); 00183 00184 if (!ViewGeometry.IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) ) 00185 { 00186 ProcEvInfo |= eDoNotProcess; 00187 } 00188 00189 Geometry TableGoe = GetGeometry(); 00190 00191 if (!TableGoe.IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) ) 00192 { 00193 sigLostFocus.emit(); 00194 } 00195 } 00196 00197 bool EventAlreadySolved = ret & eMouseEventSolved; 00198 00199 // Probe the column size handlers. 00200 std::vector<sizehandler2 *>::iterator it; 00201 00202 if (m_bEnableColumnResizing && m_bShowColumnHeader) 00203 { 00204 for (it = m_column_sizehandler.begin(); it != m_column_sizehandler.end(); it++) 00205 { 00206 ret = (*it)->OnEvent (ievent, ret, ProcEvInfo); 00207 } 00208 } 00209 00210 // Probe the row size handlers. 00211 if (m_bEnableRowResizing && m_bShowRowHeader) 00212 { 00213 std::vector<RowHeader *>::iterator row_iterator; 00214 00215 for (row_iterator = m_row_header.begin(), it = m_row_sizehandler.begin(); it != m_row_sizehandler.end(); it++, row_iterator++) 00216 { 00217 if ( (*row_iterator)->_table_item->IsParentOpen() == true) 00218 { 00219 ret = (*it)->OnEvent (ievent, ret, ProcEvInfo); 00220 } 00221 } 00222 } 00223 00224 00225 // This bool checks if there is at least one item that is dirty. 00226 bool ItemSolvedEvent = false; 00227 { 00228 std::vector<RowHeader *>::iterator row_iterator; 00229 00230 // The ScrollView layout position is fixed. The ScrollView keeps track of the delta offset in x and y of the layout it manages. 00231 // Modify the event to account for this offset; 00232 Event mod_event = ievent; 00233 mod_event.e_x -= _delta_x; 00234 mod_event.e_y -= _delta_y; 00235 00236 for (row_iterator = m_row_header.begin(), it = m_row_sizehandler.begin(); it != m_row_sizehandler.end(); it++, row_iterator++) 00237 { 00238 if ( (*row_iterator)->_table_item->IsParentOpen() == true) 00239 { 00240 ret = (*row_iterator)->_table_item->ProcessPropertyEvent (mod_event, ret, ProcEvInfo); 00241 00242 if (ret & eMouseEventSolved) 00243 ItemSolvedEvent = true; 00244 00245 // Pure TableItem elements do not inherit from View. Therefore, they cannot call QueueDraw() on themselves. 00246 // The TableCtrl that holds them must know that they need to be redrawn. Since Pure TableItem do not trap events, the event 00247 // will go to TableCtrl (like OnMouseDown) who will found out the cell where the event happened and set the dirty flag of the TableItem. 00248 //if((*row_iterator)->_table_item->isDirtyItem()) 00249 // DirtyItem = true; 00250 } 00251 } 00252 } 00253 00254 // if(DirtyItem) 00255 // QueueDraw(); 00256 00257 if (m_vertical_scrollbar_enable) 00258 ret = _vscrollbar->ProcessEvent (ievent, ret, ProcEvInfo & (~eDoNotProcess) ); 00259 00260 if (m_horizontal_scrollbar_enable) 00261 ret = _hscrollbar->ProcessEvent (ievent, ret, ProcEvInfo & (~eDoNotProcess) ); 00262 00263 if (IsPartOfCombobox() && ievent.e_event == NUX_MOUSE_RELEASED) 00264 { 00265 if (GetGeometry().IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) && 00266 m_TableArea->GetGeometry().IsPointInside (ievent.e_x - ievent.e_x_root, ievent.e_y - ievent.e_y_root) ) 00267 { 00268 m_TableArea->ForceStartFocus (0, 0); 00269 ret = m_TableArea->OnEvent (ievent, ret, ProcEvInfo); 00270 } 00271 else 00272 { 00273 ret = m_TableArea->OnEvent (ievent, ret, ProcEvInfo); 00274 } 00275 } 00276 else 00277 { 00278 // The ScrollView layout position is fixed. The ScrollView keeps track of the delta offset in x and y of the layout it manages. 00279 // Modify the event to account for this offset; 00280 Event mod_event = ievent; 00281 mod_event.e_x -= _delta_x; 00282 mod_event.e_y -= _delta_y; 00283 00284 if (mod_event.e_event == NUX_MOUSE_PRESSED && ItemSolvedEvent && ! (EventAlreadySolved) /*&& GetWindowCompositor().GetMouseFocusArea()*/) 00285 { 00286 // The mouse down event has already been captured. This call is going to find out if a cell was hit. 00287 OnMouseDown (mod_event.e_x - mod_event.e_x_root - m_TableArea->GetBaseX(), 00288 mod_event.e_y - mod_event.e_y_root - m_TableArea->GetBaseY(), mod_event.GetMouseState(), mod_event.GetKeyState() ); 00289 } 00290 else 00291 { 00292 ret = m_TableArea->OnEvent (mod_event, ret, ProcEvInfo); 00293 } 00294 } 00295 00296 00297 // PostProcessEvent2 must always have its last parameter set to 0 00298 // because the m_BackgroundArea is the real physical limit of the window. 00299 // So the previous test about IsPointInside do not prevail over m_BackgroundArea 00300 // testing the evnt by itself. 00301 ret = PostProcessEvent2 (ievent, ret, ProcEvInfo); 00302 00303 // If it is a mouse down, check for the selected row and column 00304 if ( (ievent.e_event == NUX_MOUSE_PRESSED) && ( (ProcEvInfo & eDoNotProcess) == 0) && AllowCellSelection) 00305 { 00306 bool in_column = false; 00307 bool in_row = false; 00308 00309 int x = ievent.e_x - ievent.e_x_root - m_TableArea->GetBaseX(); 00310 int y = ievent.e_y - ievent.e_y_root - m_TableArea->GetBaseY(); 00311 00312 if ( (0 <= x) && (x < m_TableArea->GetBaseWidth() ) ) 00313 { 00314 in_column = true; 00315 } 00316 00317 if ( (0 <= y) && (y < m_TableArea->GetBaseHeight() ) ) 00318 { 00319 in_row = true; 00320 } 00321 00322 if (in_column && in_row) 00323 { 00324 // OnMouseDown(ievent.e_x-m_TableArea->GetX(), 00325 // ievent.e_y-m_TableArea->GetY(), ievent.GetMouseState(), ievent.GetKeyState()); 00326 } 00327 else 00328 { 00329 if ( (m_selectedColumn != -1) || (m_selectedRow != -1) ) 00330 { 00331 m_selectedColumn = -1; 00332 m_selectedRow = -1; 00333 QueueDraw(); 00334 } 00335 } 00336 } 00337 else if ( (ievent.e_event == NUX_MOUSE_PRESSED) && ( (ProcEvInfo & eDoNotProcess) || EventAlreadySolved) ) 00338 { 00339 if ( (m_selectedColumn != -1) || (m_selectedRow != -1) ) 00340 { 00341 m_selectedColumn = -1; 00342 m_selectedRow = -1; 00343 QueueDraw(); 00344 } 00345 } 00346 00347 00348 //GetWindowCompositor()..AddToDrawList(this); 00349 return ret; 00350 } 00351 00352 void PresentBufferToScreen (ObjectPtr<IOpenGLBaseTexture> texture, int x, int y) 00353 { 00354 nuxAssert (texture.IsValid() ); 00355 00356 if (texture.IsNull() ) 00357 return; 00358 00359 t_u32 window_width, window_height; 00360 window_width = GetWindowThread ()->GetGraphicsEngine().GetWindowWidth(); 00361 window_height = GetWindowThread ()->GetGraphicsEngine().GetWindowHeight(); 00362 GetWindowThread ()->GetGraphicsEngine().EmptyClippingRegion(); 00363 GetWindowThread ()->GetGraphicsEngine().SetOpenGLClippingRectangle (0, 0, window_width, window_height); 00364 GetWindowThread ()->GetGraphicsEngine().SetViewport (0, 0, window_width, window_height); 00365 GetWindowThread ()->GetGraphicsEngine().Push2DWindow (window_width, window_height); 00366 00367 // Render the MAINFBO 00368 { 00369 t_u32 w, h; 00370 w = texture->GetWidth(); 00371 h = texture->GetHeight(); 00372 00373 TexCoordXForm texxform0; 00374 texxform0.uwrap = TEXWRAP_CLAMP; 00375 texxform0.vwrap = TEXWRAP_CLAMP; 00376 texxform0.FlipVCoord (true); 00377 GetGraphicsDisplay()->GetGraphicsEngine()->QRP_1Tex (x, y, w, h, texture, texxform0, color::White); 00378 } 00379 } 00380 00381 void TableCtrl::Draw (GraphicsEngine &GfxContext, bool force_draw) 00382 { 00383 if (IsSizeMatchContent() ) 00384 { 00385 if (m_DrawBackgroundOnPreviousGeometry) 00386 GetPainter().PaintBackground (GfxContext, m_PreviousGeometry); 00387 00388 m_DrawBackgroundOnPreviousGeometry = false; 00389 } 00390 00391 00392 Geometry base = GetGeometry(); 00393 GfxContext.PushClippingRectangle (base); 00394 GetPainter().PaintBackground (GfxContext, base); 00395 00396 PushShapeCornerBackgroundScope pbs (GetPainter(), GfxContext, 00397 Geometry (m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight), 00398 eSHAPE_CORNER_ROUND10, 00399 Color (0xFF4D4D4D), 00400 eAllCorners, true); 00401 00402 Geometry TableArea = m_TableArea->GetGeometry(); 00403 00404 base = GetGeometry(); 00405 00406 if (m_vertical_scrollbar_enable) 00407 { 00408 _vscrollbar->QueueDraw(); 00409 } 00410 00411 if (m_horizontal_scrollbar_enable) 00412 { 00413 _hscrollbar->QueueDraw(); 00414 } 00415 00416 DrawTable (GfxContext); 00417 GfxContext.PopClippingRectangle(); 00418 } 00419 00420 void TableCtrl::DrawContent (GraphicsEngine &GfxContext, bool force_draw) 00421 { 00422 GfxContext.PushClippingRectangle (GetGeometry() ); 00423 00428 00429 int num_row = (t_u32) m_row_header.size(); 00430 int ItemOffsetY = (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0); 00431 00432 GfxContext.PushClippingRectangle (Geometry (m_ViewX, m_ViewY + (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0), 00433 m_ViewWidth, m_ViewHeight - (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ) ); 00434 00435 GfxContext.PushClipOffset (_delta_x, _delta_y); 00436 GfxContext.Push2DTranslationModelViewMatrix (_delta_x, _delta_y, 0.0f); 00437 00438 { 00439 00440 int odd_or_even = 0; 00441 00442 for (int r = 0; r < num_row; r++) 00443 { 00444 if (m_row_header[r]->_table_item->IsParentOpen() ) 00445 { 00446 Geometry geo = m_row_header[r]->_table_item->_row_header_area->GetGeometry(); 00447 00448 if (m_row_header[r]->_table_item->FirstChildNode() != 0) 00449 { 00450 geo.SetX (m_TableArea->GetBaseX() + (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[r]->_table_item->m_depth + OPENCLOSE_BTN_WIDTH); 00451 geo.SetY (m_TableArea->GetBaseY() + ItemOffsetY); 00452 geo.SetWidth (m_column_header[0].m_header_area->GetBaseWidth() - ITEM_DEPTH_MARGIN * m_row_header[r]->_table_item->m_depth - OPENCLOSE_BTN_WIDTH); 00453 } 00454 else 00455 { 00456 geo.SetX (m_TableArea->GetBaseX() + (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[r]->_table_item->m_depth); 00457 geo.SetY (m_TableArea->GetBaseY() + ItemOffsetY); 00458 geo.SetWidth (m_column_header[0].m_header_area->GetBaseWidth() - ITEM_DEPTH_MARGIN * m_row_header[r]->_table_item->m_depth); 00459 } 00460 00461 // Draw content of a row 00462 { 00463 m_row_header[r]->_table_item->DrawProperty (GfxContext, this, force_draw, geo, GetPainter(), m_row_header[r], m_column_header, odd_or_even ? GetRowColorEven() : GetRowColorOdd() ); 00464 } 00465 ItemOffsetY += m_row_header[r]->_table_item->_row_header_area->GetBaseHeight(); 00466 } 00467 00468 odd_or_even = !odd_or_even; 00469 } 00470 } 00471 00472 GfxContext.PopModelViewMatrix (); 00473 GfxContext.PopClipOffset (); 00474 00475 GfxContext.PopClippingRectangle(); 00476 00477 00479 00480 00481 if (m_vertical_scrollbar_enable) 00482 { 00483 _vscrollbar->ProcessDraw (GfxContext, force_draw); 00484 } 00485 00486 if (m_horizontal_scrollbar_enable) 00487 { 00488 _hscrollbar->ProcessDraw (GfxContext, force_draw); 00489 } 00490 00491 GfxContext.PopClippingRectangle(); 00492 } 00493 00494 void TableCtrl::PostDraw (GraphicsEngine &GfxContext, bool force_draw) 00495 { 00496 if (IsRedrawNeeded() ) 00497 { 00498 // Drawing is complete 00499 // Reset the Item dirty flag to false; 00500 std::vector<RowHeader *>::iterator row_iterator; 00501 00502 for (row_iterator = m_row_header.begin(); row_iterator != m_row_header.end(); row_iterator++) 00503 { 00504 if ( (*row_iterator)->_table_item->IsParentOpen() == true) 00505 { 00506 // Mark all visible items as not dirty 00507 (*row_iterator)->_table_item->setDirtyItem (false); 00508 } 00509 } 00510 } 00511 00512 ScrollView::SwapTextureIndex(); 00513 } 00514 00515 void TableCtrl::PaintDecoration (GraphicsEngine &GfxContext, TableItem *item) 00516 { 00517 //int ItemOffsetY = (m_bShowColumnHeader? COLUMNHEADERHEIGHT : 0); 00518 00519 Geometry geo = item->m_ItemGeometryVector[0]; 00520 00521 if ( (item->FirstChildNode() != 0) /* || item->AlwaysShowOpeningButton()*/) 00522 { 00523 geo.SetX (m_TableArea->GetBaseX() + (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * item->m_depth + OPENCLOSE_BTN_WIDTH); 00524 //geo.SetY(m_TableArea->GetY() + ItemOffsetY); 00525 geo.SetWidth (m_column_header[0].m_header_area->GetBaseWidth() - ITEM_DEPTH_MARGIN * item->m_depth - OPENCLOSE_BTN_WIDTH); 00526 } 00527 else 00528 { 00529 geo.SetX (m_TableArea->GetBaseX() + (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * item->m_depth); 00530 //geo.SetY(m_TableArea->GetY() + ItemOffsetY); 00531 geo.SetWidth (m_column_header[0].m_header_area->GetBaseWidth() - ITEM_DEPTH_MARGIN * item->m_depth); 00532 } 00533 00534 if ( (item->FirstChildNode() != 0) /* || item->AlwaysShowOpeningButton()*/) 00535 { 00536 if (item->isOpen() ) 00537 { 00538 GfxContext.PushClippingRectangle (item->m_ItemGeometryVector[0]); 00539 geo.OffsetPosition (-OPENCLOSE_BTN_WIDTH, 0); 00540 geo.SetWidth (OPENCLOSE_BTN_WIDTH); 00541 00542 GeometryPositioning gp (eHACenter, eVACenter); 00543 Geometry GeoPo = ComputeGeometryPositioning (geo, GetTheme().GetImageGeometry (eTREE_NODE_OPEN), gp); 00544 GetPainter().PaintShape (GfxContext, GeoPo, Color (0xFF000000), eTREE_NODE_OPEN); 00545 00546 GfxContext.PopClippingRectangle(); 00547 } 00548 else 00549 { 00550 GfxContext.PushClippingRectangle (item->m_ItemGeometryVector[0]); 00551 geo.OffsetPosition (-OPENCLOSE_BTN_WIDTH, 0); 00552 geo.SetWidth (OPENCLOSE_BTN_WIDTH); 00553 00554 GeometryPositioning gp (eHACenter, eVACenter); 00555 Geometry GeoPo = ComputeGeometryPositioning (geo, GetTheme().GetImageGeometry (eTREE_NODE_CLOSE), gp); 00556 GetPainter().PaintShape (GfxContext, GeoPo, Color (0xFF000000), eTREE_NODE_CLOSE); 00557 00558 GfxContext.PopClippingRectangle(); 00559 } 00560 } 00561 } 00562 00563 void TableCtrl::PaintRowDecoration (GraphicsEngine &GfxContext, TableItem *item, Color color) 00564 { 00565 if (m_bShowRowHeader) 00566 { 00567 Geometry geo = item->m_RowHeaderGeometry; 00568 GetPainter().Paint2DQuadColor (GfxContext, geo, color); 00569 GetPainter().PaintTextLineStatic (GfxContext, GetFont (), geo, "i"); 00570 } 00571 } 00572 00573 t_u32 TableCtrl::PushItemBackground (GraphicsEngine &GfxContext, TableItem *item, bool MouseOver) 00574 { 00575 Geometry row_geometry = item->m_TotalGeometry; 00576 Color BackgroundColor = item->m_ItemBackgroundColor; 00577 00578 if (MouseOver && m_IsEnableMouseOverColor) 00579 BackgroundColor = GetMouseOverColor(); 00580 00581 t_u32 NumBackground = 0; 00582 00583 GetPainter().PushShapeLayer (GfxContext, 00584 Geometry (m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight), 00585 eSHAPE_CORNER_ROUND2, 00586 Color (0xFF4D4D4D), 00587 eAllCorners); 00588 00589 NumBackground++; 00590 00591 if (item->m_bIsFirstVisibleItem && item->m_bIsLastVisibleItem) 00592 { 00593 if (m_bShowColumnHeader) 00594 { 00595 GetPainter().PushDrawShapeLayer (GfxContext, row_geometry, eSHAPE_CORNER_ROUND2, BackgroundColor, eCornerBottomLeft | eCornerBottomRight); 00596 NumBackground++; 00597 } 00598 else 00599 { 00600 GetPainter().PushDrawShapeLayer (GfxContext, row_geometry, eSHAPE_CORNER_ROUND2, BackgroundColor, eAllCorners); 00601 NumBackground++; 00602 } 00603 } 00604 else if (item->m_bIsFirstVisibleItem) 00605 { 00606 if (m_bShowColumnHeader) 00607 { 00608 GetPainter().PushDrawColorLayer (GfxContext, row_geometry, BackgroundColor); 00609 NumBackground++; 00610 } 00611 else 00612 { 00613 GetPainter().PushDrawShapeLayer (GfxContext, row_geometry, eSHAPE_CORNER_ROUND2, BackgroundColor, eCornerTopLeft | eCornerTopRight); 00614 NumBackground++; 00615 } 00616 } 00617 else if (item->m_bIsLastVisibleItem) 00618 { 00619 GetPainter().PushDrawShapeLayer (GfxContext, row_geometry, eSHAPE_CORNER_ROUND2, BackgroundColor, eCornerBottomLeft | eCornerBottomRight); 00620 NumBackground++; 00621 } 00622 else 00623 { 00624 GetPainter().PushDrawColorLayer (GfxContext, row_geometry, BackgroundColor); 00625 NumBackground++; 00626 } 00627 00628 bool isSelected = (item == GetSelectedItem() ); 00629 Color SelectionColor = GetSelectionColor(); 00630 00631 if (MouseOver && m_IsEnableMouseOverColor) 00632 SelectionColor = GetMouseOverColor(); 00633 00634 int SelectedColumn = GetSelectedColumn(); 00635 00636 for (t_s32 Column = 0; Column < GetNumColumn(); Column++) 00637 { 00638 if (isSelected && (SelectedColumn == Column) ) 00639 { 00640 if (item->m_bIsFirstVisibleItem && item->m_bIsLastVisibleItem) 00641 { 00642 if (m_bShowColumnHeader) 00643 { 00644 t_s32 corners = 0L; 00645 00646 if (Column == 0 && !m_bShowRowHeader) 00647 corners |= eCornerBottomLeft; 00648 00649 if (Column == GetNumColumn() - 1) 00650 corners |= eCornerBottomRight; 00651 00652 GetPainter().PushDrawShapeLayer (GfxContext, item->m_ItemGeometryVector[Column], eSHAPE_CORNER_ROUND2, SelectionColor, corners); 00653 NumBackground++; 00654 } 00655 else 00656 { 00657 GetPainter().PushDrawShapeLayer (GfxContext, item->m_ItemGeometryVector[Column], eSHAPE_CORNER_ROUND2, SelectionColor, eAllCorners); 00658 NumBackground++; 00659 } 00660 } 00661 else if (item->m_bIsFirstVisibleItem) 00662 { 00663 if (m_bShowColumnHeader) 00664 { 00665 GetPainter().PushDrawColorLayer (GfxContext, item->m_ItemGeometryVector[Column], SelectionColor); 00666 NumBackground++; 00667 } 00668 else 00669 { 00670 t_s32 corners = 0L; 00671 00672 if (Column == 0 && !m_bShowRowHeader) 00673 corners |= eCornerTopLeft; 00674 00675 if (Column == GetNumColumn() - 1) 00676 corners |= eCornerTopRight; 00677 00678 GetPainter().PushDrawShapeLayer (GfxContext, item->m_ItemGeometryVector[Column], eSHAPE_CORNER_ROUND2, SelectionColor, corners); 00679 NumBackground++; 00680 } 00681 } 00682 else if (item->m_bIsLastVisibleItem) 00683 { 00684 if (Column == 0) 00685 { 00686 if (m_bShowRowHeader == false) 00687 { 00688 GetPainter().PushDrawShapeLayer (GfxContext, item->m_ItemGeometryVector[Column], eSHAPE_CORNER_ROUND2, SelectionColor, eCornerBottomLeft); 00689 NumBackground++; 00690 } 00691 else 00692 { 00693 GetPainter().PushDrawColorLayer (GfxContext, item->m_ItemGeometryVector[Column], SelectionColor); 00694 NumBackground++; 00695 } 00696 } 00697 else if (Column == GetNumColumn() - 1) 00698 { 00699 GetPainter().PushDrawShapeLayer (GfxContext, item->m_ItemGeometryVector[Column], eSHAPE_CORNER_ROUND2, SelectionColor, eCornerBottomRight); 00700 NumBackground++; 00701 } 00702 else 00703 { 00704 GetPainter().PushDrawColorLayer (GfxContext, item->m_ItemGeometryVector[Column], SelectionColor); 00705 NumBackground++; 00706 } 00707 } 00708 else 00709 { 00710 GetPainter().PushDrawColorLayer (GfxContext, item->m_ItemGeometryVector[Column], SelectionColor); 00711 NumBackground++; 00712 } 00713 } 00714 00715 if (m_bShowRowHeader == true || Column != 0) 00716 { 00717 if (m_bShowVerticalSeparationLine) 00718 { 00719 GetPainter().Draw2DLine (GfxContext, 00720 item->m_ItemGeometryVector[Column].x, 00721 item->m_ItemGeometryVector[Column].y, 00722 item->m_ItemGeometryVector[Column].x, 00723 item->m_ItemGeometryVector[Column].y + item->m_ItemGeometryVector[Column].GetHeight(), 00724 GetVerticalSeparationLineColor() ); 00725 } 00726 } 00727 00728 if (Column == 0) 00729 PaintDecoration (GfxContext, item); 00730 00731 } 00732 00733 // Draw horizontal line 00734 if (item->m_bIsLastVisibleItem == false) 00735 if (m_bShowHorizontalSeparationLine) 00736 GetPainter().Draw2DLine (GfxContext, row_geometry.x, row_geometry.y + row_geometry.GetHeight() - 1, row_geometry.x + row_geometry.GetWidth(), row_geometry.y + row_geometry.GetHeight() - 1, GetHorizontalSeparationLineColor() ); 00737 00738 return NumBackground; 00739 } 00740 00741 void TableCtrl::PopItemBackground (GraphicsEngine &GfxContext, t_u32 NumBackground) 00742 { 00743 GetPainter().PopBackground (NumBackground); 00744 } 00745 00746 void TableCtrl::DrawTable (GraphicsEngine &GfxContext) 00747 { 00748 ObjectPtr<IOpenGLFrameBufferObject> CurrentFrameBuffer = GetWindowCompositor().GetWindowFrameBufferObject(); 00749 00750 Geometry tableGeometry = m_TableArea->GetGeometry(); 00751 int xl, yl; 00752 00753 //--->GetPainter().Paint2DQuadColor(tableGeometry, Color(HEADER_BACKGROUND_COLOR)); 00754 00755 int colum_width = (m_bShowRowHeader ? ROWHEADERWIDTH : 0); 00756 std::vector<ColumnHeader>::iterator column_iterator; 00757 00758 for (column_iterator = m_column_header.begin(); column_iterator != m_column_header.end(); column_iterator++) 00759 { 00760 colum_width += (*column_iterator).m_header_area->GetGeometry().GetWidth(); 00761 } 00762 00763 std::vector<RowHeader *>::iterator row_iterator; 00764 std::vector<sizehandler2 *>::iterator row_sizehandler_iterator; 00765 int ItemOffsetY = 0; 00766 00767 GfxContext.PushClippingRectangle (Geometry (m_ViewX, m_ViewY + (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0), 00768 m_ViewWidth, m_ViewHeight - (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ) ); 00769 { 00770 int every_two = 0; 00771 00772 for (row_iterator = m_row_header.begin(); row_iterator != m_row_header.end(); row_iterator++) 00773 { 00774 if ( (*row_iterator)->_table_item->IsParentOpen() == true) 00775 { 00776 Geometry row_geometry = (*row_iterator)->_table_item->m_TotalGeometry; 00777 00778 // Mark all visible items as dirty 00779 (*row_iterator)->_table_item->setDirtyItem (true); 00780 } 00781 00782 every_two++; 00783 } 00784 00785 // Render row name and horizontal separation 00786 xl = m_TableArea->GetGeometry().x; 00787 yl = m_TableArea->GetGeometry().y + (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0); // skip the Height of the Column header; 00788 00789 // Paint the first horizontal separation line. 00790 GetPainter().Draw2DLine (GfxContext, xl, yl, xl + m_ContentGeometry.GetWidth(), yl, GetHorizontalSeparationLineColor() ); 00791 00792 for (row_iterator = m_row_header.begin(), row_sizehandler_iterator = m_row_sizehandler.begin(); 00793 row_iterator != m_row_header.end(); 00794 row_iterator++, row_sizehandler_iterator++) 00795 { 00796 if ( (*row_iterator)->_table_item->IsParentOpen() == true) 00797 { 00798 // elements in m_column_header are relative to m_TableArea-> Get their absolute position in geo. 00799 Geometry geo = (*row_iterator)->_table_item->_row_header_area->GetGeometry(); 00800 geo.OffsetPosition (m_TableArea->GetBaseX(), m_TableArea->GetBaseY() /* - ItemOffsetY*/); 00801 00802 // Paint the number of the row 00803 //GetPainter().PaintTextLineStatic(geo, (*row_iterator)->header.GetBaseString()); 00804 00805 // Paint row horizontal separation line. 00806 yl += (*row_iterator)->_table_item->_row_header_area->GetGeometry().GetHeight(); 00807 GetPainter().Draw2DLine (GfxContext, xl, yl, xl + m_ContentGeometry.GetWidth(), yl, GetHorizontalSeparationLineColor() ); 00808 00809 // Draw the row size handler on the separation line. 00810 Geometry sizehandler_geo (xl, yl - HANDLERSIZE / 2, (m_bShowRowHeader ? ROWHEADERWIDTH : 0), HANDLERSIZE); 00811 } 00812 else 00813 { 00814 ItemOffsetY += (*row_iterator)->_table_item->_row_header_area->GetBaseHeight(); 00815 } 00816 } 00817 } 00818 GfxContext.PopClippingRectangle(); 00819 00820 DrawHeader (GfxContext); 00821 } 00822 00823 void TableCtrl::DrawHeader (GraphicsEngine &GfxContext) 00824 { 00825 GfxContext.PushClippingRectangle (Geometry (m_ViewX, m_ViewY /*+ (!m_bShowColumnHeader? COLUMNHEADERHEIGHT : 0)*/, 00826 m_ViewWidth, m_ViewHeight /*- (!m_bShowColumnHeader? COLUMNHEADERHEIGHT : 0)*/) ); 00827 00828 00829 std::vector<ColumnHeader>::iterator column_iterator; 00830 std::vector<RowHeader*>::iterator row_iterator; 00831 00832 int ItemOffsetY = 0; 00836 t_u32 num_row = (t_u32) m_row_header.size(); 00837 ItemOffsetY = (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0); 00838 00839 for (t_u32 r = 0; r < num_row; r++) 00840 { 00841 if (m_row_header[r]->_table_item->IsParentOpen() ) 00842 { 00843 ItemOffsetY += m_row_header[r]->_table_item->_row_header_area->GetBaseHeight(); 00844 } 00845 } 00846 00847 int row_height = 0; 00848 00849 for (row_iterator = m_row_header.begin(); row_iterator != m_row_header.end(); row_iterator++) 00850 { 00851 if ( (*row_iterator)->_table_item->IsParentOpen() ) 00852 row_height += (*row_iterator)->_table_item->_row_header_area->GetBaseHeight(); 00853 } 00854 00858 // Draw Top Header Background 00859 Geometry header_geo = Geometry (m_ViewX, m_ViewY, m_ViewWidth, (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ); 00860 //--->GetPainter().Paint2DQuadColor(header_geo, Color(HEADER_BACKGROUND_COLOR)); 00861 00862 if (m_bShowColumnHeader) 00863 { 00864 //GetPainter().PaintShapeCorner(GfxContext, header_geo, 0xFF2f2f2f, eSHAPE_CORNER_ROUND10, eCornerTopLeft|eCornerTopRight); 00865 } 00866 00867 int xl, yl; 00868 // Render header name and vertical separations 00869 xl = m_TableArea->GetGeometry().x + (m_bShowRowHeader ? ROWHEADERWIDTH : 0); // skip the width of the Row header 00870 yl = m_TableArea->GetGeometry().y + (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0); 00871 00872 // Paint the first vertical separation line. 00873 if (m_bShowRowHeader == false) 00874 { 00875 // Do not draw the first vertical separation line if the row header is not visible. 00876 } 00877 else 00878 { 00879 GetPainter().Draw2DLine (GfxContext, xl, yl, xl, yl + row_height, GetVerticalSeparationLineColor() ); 00880 } 00881 00882 if (m_bShowColumnHeader) 00883 { 00884 if (m_bShowRowHeader) 00885 { 00886 // Draw the Top-Left corner of the header 00887 Geometry geo = Geometry (GetBaseX(), GetBaseY(), ROWHEADERWIDTH, COLUMNHEADERHEIGHT); 00888 geo.OffsetSize (-1, 0); 00889 GetPainter().PaintShape (GfxContext, geo, TABLE_HEADER_BASE_COLOR, eSHAPE_CORNER_ROUND4/*, eCornerTopLeft|eCornerTopRight*/); 00890 } 00891 00892 for (column_iterator = m_column_header.begin(); column_iterator != m_column_header.end(); column_iterator++) 00893 { 00894 // if(!isFloatingColumn() && (column_iterator + 1 == m_column_header.end())) 00895 // { 00896 // // Do not draw the last vertical separation line 00897 // break; 00898 // } 00899 00900 // elements in m_column_header are relative to m_TableArea-> Get their absolute position in geo. 00901 Geometry geo = (*column_iterator).m_header_area->GetGeometry(); 00902 Geometry header_title_geo = geo; 00903 geo.OffsetPosition (m_TableArea->GetBaseX(), m_ViewY); 00904 header_title_geo = geo; 00905 00906 if ( (column_iterator == m_column_header.begin() ) && (m_bShowRowHeader == false) ) 00907 { 00908 header_title_geo.OffsetSize (-1, 0); 00909 // this is not the first column 00910 } 00911 else if (column_iterator + 1 == m_column_header.end() ) 00912 { 00913 // The last column 00914 header_title_geo.OffsetSize (-1, 0); 00915 header_title_geo.OffsetPosition (1, 0); 00916 } 00917 else 00918 { 00919 header_title_geo.OffsetSize (-2, 0); 00920 header_title_geo.OffsetPosition (1, 0); 00921 } 00922 00923 GetPainter().PaintShape (GfxContext, header_title_geo, TABLE_HEADER_BASE_COLOR/*0xFF2f2f2f*/, eSHAPE_CORNER_ROUND4/*, eCornerTopLeft|eCornerTopRight*/); 00924 // This is arbitrary to get the text away from the borders of the column. 00925 { 00926 geo.OffsetPosition (4, 0); 00927 geo.OffsetSize (-8, 0); 00928 } 00929 00930 GetPainter().PaintTextLineStatic (GfxContext, GetSysBoldFont(), geo, (*column_iterator).m_header_area->GetBaseString().GetTCharPtr(), TABLE_HEADER_TEXT_COLOR); 00931 00932 if (!isFloatingColumn() && (column_iterator + 1 == m_column_header.end() ) ) 00933 { 00934 // Do not draw the last vertical separation line if the columns are not floating 00935 break; 00936 } 00937 else 00938 { 00939 // Paint column vertical separation. 00940 xl += (*column_iterator).m_header_area->GetGeometry().GetWidth(); 00941 //GetPainter().Draw2DLine(GfxContext, xl, yl, xl, yl + row_height, GetVerticalSeparationLineColor()); 00942 } 00943 00945 // Draw the column size handler on the line 00946 Geometry sizehandler_geo (xl - HANDLERSIZE / 2, m_ViewY, HANDLERSIZE, (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ); 00947 //GetPainter().Paint2DQuadColor(sizehandler_geo, Color(0.1, 0.1, 0.1, 1.0)); 00948 } 00949 00950 if (isFloatingColumn() && (m_column_header.size() > 0) ) 00951 { 00952 column_iterator = m_column_header.end() - 1; 00953 // Draw the Top-Left corner of the header 00954 int width = m_ViewWidth - ( (*column_iterator).m_header_area->GetBaseX() + (*column_iterator).m_header_area->GetBaseWidth() ); 00955 00956 if (width > 5) 00957 { 00958 Geometry geo = Geometry ( (*column_iterator).m_header_area->GetBaseX() + (*column_iterator).m_header_area->GetBaseWidth(), 00959 GetBaseY(), width, COLUMNHEADERHEIGHT); 00960 geo.OffsetSize (-2, 0); 00961 geo.OffsetPosition (4, 0); 00962 GetPainter().PaintShape (GfxContext, geo, TABLE_HEADER_BASE_COLOR, eSHAPE_CORNER_ROUND4/*, eCornerTopLeft|eCornerTopRight*/); 00963 } 00964 } 00965 } 00966 00967 GfxContext.PopClippingRectangle(); 00968 } 00969 00970 void TableCtrl::DrawHeaderPreview (GraphicsEngine &GfxContext) 00971 { 00972 GfxContext.PushClippingRectangle (Geometry (m_ViewX, m_ViewY, m_ViewWidth, m_ViewHeight) ); 00973 std::vector<ColumnHeader>::iterator column_iterator; 00974 std::vector<RowHeader *>::iterator row_iterator; 00975 00976 int row_height = 0; 00977 int TotalHeight = (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0); 00978 00979 for (row_iterator = m_row_header.begin(); row_iterator != m_row_header.end(); row_iterator++) 00980 { 00981 if ( (*row_iterator)->_table_item->IsParentOpen() ) 00982 { 00983 row_height += (*row_iterator)->_table_item->_row_header_area->GetBaseHeight(); 00984 TotalHeight += (*row_iterator)->_table_item->_row_header_area->GetBaseHeight(); 00985 } 00986 } 00987 00988 // Draw Top Header Background 00989 Geometry header_geo = Geometry (m_ViewX, m_ViewY, m_ViewWidth, (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ); 00990 00991 GetPainter().PaintShape (GfxContext, header_geo, TABLE_HEADER_BASE_COLOR, eSHAPE_CORNER_ROUND4/*, eCornerTopLeft|eCornerTopRight*/); 00992 00993 Color header_base_color = Color (0xa0808080); 00994 00995 if (m_bShowColumnHeader) 00996 { 00997 if (m_bShowRowHeader) 00998 { 00999 // Draw the Top-Left corner of the header 01000 Geometry geo = Geometry (GetBaseX(), GetBaseY(), ROWHEADERWIDTH, COLUMNHEADERHEIGHT); 01001 geo.OffsetSize (-1, 0); 01002 GetPainter().PaintShape (GfxContext, geo, header_base_color, eSHAPE_CORNER_ROUND4/*, eCornerTopLeft|eCornerTopRight*/); 01003 } 01004 01005 for (column_iterator = m_column_header.begin(); column_iterator != m_column_header.end(); column_iterator++) 01006 { 01007 // elements in m_column_header are relative to m_TableArea-> Get their absolute position in geo. 01008 Geometry geo = (*column_iterator).m_header_area->GetGeometry(); 01009 Geometry header_title_geo = geo; 01010 geo.OffsetPosition (m_TableArea->GetBaseX(), m_ViewY); 01011 header_title_geo = geo; 01012 01013 if ( (column_iterator == m_column_header.begin() ) && (m_bShowRowHeader == false) ) 01014 { 01015 header_title_geo.OffsetSize (-1, 0); 01016 // this is not the first column 01017 } 01018 else if (column_iterator + 1 == m_column_header.end() ) 01019 { 01020 // The last column 01021 header_title_geo.OffsetSize (-1, 0); 01022 header_title_geo.OffsetPosition (1, 0); 01023 } 01024 else 01025 { 01026 header_title_geo.OffsetSize (-2, 0); 01027 header_title_geo.OffsetPosition (1, 0); 01028 } 01029 01030 GetPainter().PaintShape (GfxContext, header_title_geo, header_base_color/*0xFF2f2f2f*/, eSHAPE_CORNER_ROUND4/*, eCornerTopLeft|eCornerTopRight*/); 01031 // This is arbitrary to get the text away from the borders of the column. 01032 { 01033 geo.OffsetPosition (4, 0); 01034 geo.OffsetSize (-8, 0); 01035 } 01036 GetPainter().PaintTextLineStatic (GfxContext, GetSysBoldFont(), geo, (*column_iterator).m_header_area->GetBaseString().GetTCharPtr(), TABLE_HEADER_TEXT_COLOR); 01037 } 01038 01039 if (isFloatingColumn() && (m_column_header.size() > 0) ) 01040 { 01041 column_iterator = m_column_header.end() - 1; 01042 // Draw the Top-Left corner of the header 01043 int width = m_ViewWidth - ( (*column_iterator).m_header_area->GetBaseX() + (*column_iterator).m_header_area->GetBaseWidth() ); 01044 01045 if (width > 5) 01046 { 01047 Geometry geo = Geometry ( (*column_iterator).m_header_area->GetBaseX() + (*column_iterator).m_header_area->GetBaseWidth(), 01048 GetBaseY(), width, COLUMNHEADERHEIGHT); 01049 geo.OffsetSize (-2, 0); 01050 geo.OffsetPosition (4, 0); 01051 GetPainter().PaintShape (GfxContext, geo, header_base_color, eSHAPE_CORNER_ROUND4/*, eCornerTopLeft|eCornerTopRight*/); 01052 } 01053 } 01054 } 01055 01056 GfxContext.PopClippingRectangle(); 01057 } 01058 01059 void TableCtrl::OverlayDrawing (GraphicsEngine &GfxContext) 01060 { 01061 DrawHeaderPreview (GfxContext); 01062 } 01063 01065 // API // 01067 01068 void TableCtrl::SetGeometry (const Geometry &geo) 01069 { 01070 ScrollView::SetGeometry (geo); 01071 } 01072 01073 void TableCtrl::AdjustNonFloatingColumn() 01074 { 01075 int new_width = m_ViewWidth; 01076 01077 new_width -= (m_bShowRowHeader ? ROWHEADERWIDTH : 0); 01078 01079 // space_to_share represents the difference between the available width and the total width occupied by the headers. 01080 // This value can be close but not equal to 0 due to fractional errors when computing the sizes. 01081 // Computations is done is float but results are stored in integers. Every things below 1.0 is rounded down to the integer value 0. 01082 01083 int space_to_share = new_width; 01084 int total_non_fix_width = 0; 01085 std::vector<ColumnHeader>::iterator it; 01086 ColumnHeader *LastNonFixHeader = 0; 01087 01088 for (it = m_column_header.begin(); it != m_column_header.end(); it++) 01089 { 01090 if ( (*it)._fix_width) 01091 { 01092 // First do a little correction in case the fix width is less than MIN_COLUMN_WIDTH. 01093 if ( (*it)._fix_width_value < MIN_COLUMN_WIDTH) 01094 { 01095 (*it)._fix_width_value = MIN_COLUMN_WIDTH; 01096 } 01097 01098 space_to_share -= (*it)._fix_width_value; 01099 } 01100 else 01101 { 01102 LastNonFixHeader = & (*it); 01103 total_non_fix_width += (*it).m_header_area->GetBaseWidth(); 01104 space_to_share -= (*it).m_header_area->GetBaseWidth(); 01105 } 01106 } 01107 01108 int RemainingSpace = new_width; 01109 01110 for (it = m_column_header.begin(); it != m_column_header.end(); it++) 01111 { 01112 if ( (*it)._fix_width) 01113 { 01114 RemainingSpace -= (*it)._fix_width_value; 01115 } 01116 } 01117 01118 for (it = m_column_header.begin(); it != m_column_header.end(); it++) 01119 { 01120 if (! (*it)._fix_width) 01121 { 01122 int w = (*it).m_header_area->GetBaseWidth(); 01123 int nw = w + space_to_share * (float (w) / float (total_non_fix_width) ); 01124 01125 if (nw < MIN_COLUMN_WIDTH) 01126 nw = MIN_COLUMN_WIDTH; 01127 01128 if (& (*it) == LastNonFixHeader) 01129 { 01130 // This is to absorb the remaining space completely. We do that because of rounding 01131 // error(in the division and multiply calculus) that might leave some space unoccupied. 01132 // Set the RemainingSpace only if it is bigger than nw. 01133 if (RemainingSpace > nw) 01134 (*it).m_header_area->SetBaseWidth (RemainingSpace); 01135 else 01136 (*it).m_header_area->SetBaseWidth (nw); 01137 } 01138 else 01139 { 01140 RemainingSpace -= nw; 01141 (*it).m_header_area->SetBaseWidth (nw); 01142 } 01143 } 01144 } 01145 } 01146 01147 void TableCtrl::ComputeNonFloatingColumn() 01148 { 01149 int total_non_fix_column_width = m_ViewWidth; 01150 t_u32 num_non_fix_column = (t_u32) m_column_header.size(); 01151 01152 total_non_fix_column_width -= (m_bShowRowHeader ? ROWHEADERWIDTH : 0); 01153 01154 std::vector<ColumnHeader>::iterator it; 01155 01156 for (it = m_column_header.begin(); it != m_column_header.end(); it++) 01157 { 01158 if ( (*it)._fix_width) 01159 { 01160 // First do a little correction in case the fix width is less than MIN_COLUMN_WIDTH. 01161 if ( (*it)._fix_width_value < MIN_COLUMN_WIDTH) 01162 { 01163 (*it)._fix_width_value = MIN_COLUMN_WIDTH; 01164 } 01165 01166 total_non_fix_column_width -= (*it)._fix_width_value; 01167 num_non_fix_column--; 01168 } 01169 } 01170 01171 int initial_column_width = 0; 01172 01173 if (num_non_fix_column != 0) 01174 { 01175 initial_column_width = total_non_fix_column_width / num_non_fix_column; 01176 } 01177 01178 if (initial_column_width < MIN_COLUMN_WIDTH) 01179 { 01180 initial_column_width = MIN_COLUMN_WIDTH; 01181 } 01182 01183 for (it = m_column_header.begin(); it != m_column_header.end(); it++) 01184 { 01185 if ( (*it)._fix_width) 01186 { 01187 (*it).m_header_area->SetBaseWidth ( (*it)._fix_width_value); 01188 } 01189 else 01190 { 01191 if (initial_column_width < MIN_COLUMN_WIDTH) 01192 (*it).m_header_area->SetBaseWidth (MIN_COLUMN_WIDTH); 01193 else 01194 (*it).m_header_area->SetBaseWidth (initial_column_width); 01195 } 01196 } 01197 } 01198 01199 void TableCtrl::addHeader (const TCHAR *name, bool fixed_width, int column_width) 01200 { 01201 sizehandler2 *column_sizehandler = new sizehandler2 (NUX_TRACKER_LOCATION); 01202 column_sizehandler->Reference(); 01203 column_sizehandler->SetBaseWidth (HANDLERSIZE); 01204 column_sizehandler->SetBaseHeight ( (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ); 01205 01206 t_u32 no = (t_u32) m_column_sizehandler.size(); 01207 column_sizehandler->mouse_down.connect (sigc::bind ( sigc::mem_fun (this, &TableCtrl::OnResizeHeaderMouseDown), no) ); 01208 column_sizehandler->mouse_up.connect (sigc::bind ( sigc::mem_fun (this, &TableCtrl::OnResizeHeaderMouseUp), no) ); 01209 column_sizehandler->mouse_drag.connect (sigc::bind ( sigc::mem_fun (this, &TableCtrl::OnResizeHeaderMouseDrag), no) ); 01210 m_column_sizehandler.push_back (column_sizehandler); 01211 01212 01213 01214 t_u32 num_header = (t_u32) m_column_header.size(); 01215 01216 if (num_header == 0) 01217 { 01218 ColumnHeader h2; 01219 h2.m_header_area->SetBaseString (name); 01220 h2.m_header_area->SetBaseX ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) ); // if has row header, this should be ROWHEADERWIDTH 01221 h2.m_header_area->SetBaseY (0); 01222 h2.m_header_area->SetBaseWidth (ITEMDEFAULTWIDTH); 01223 h2.m_header_area->SetBaseHeight ( (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ); 01224 h2._fix_width = fixed_width; 01225 h2._fix_width_value = column_width; 01226 m_column_header.push_back (h2); 01227 } 01228 else 01229 { 01230 Geometry g = m_column_header[num_header-1].m_header_area->GetGeometry(); 01231 ColumnHeader h2; 01232 h2.m_header_area->SetBaseString (name); 01233 h2.m_header_area->SetBaseX (g.x + g.GetWidth() ); 01234 h2.m_header_area->SetBaseY (0); 01235 h2.m_header_area->SetBaseWidth (ITEMDEFAULTWIDTH); 01236 h2.m_header_area->SetBaseHeight ( (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ); 01237 h2._fix_width = fixed_width; 01238 h2._fix_width_value = column_width; 01239 m_column_header.push_back (h2); 01240 } 01241 01242 if (isFloatingColumn() == false) 01243 { 01244 ComputeNonFloatingColumn(); 01245 } 01246 01247 FormatTable(); 01248 } 01249 01250 int TableCtrl::FormatHeader() 01251 { 01252 int x = m_TableArea->GetBaseX(); 01253 int y = m_TableArea->GetBaseY(); 01254 int totalWidth = (m_bShowRowHeader ? ROWHEADERWIDTH : 0); 01255 01256 std::vector<sizehandler2 *>::iterator size_it; 01257 std::vector<ColumnHeader>::iterator column_it; 01258 01259 for (column_it = m_column_header.begin(), size_it = m_column_sizehandler.begin(); 01260 (column_it != m_column_header.end() ) && (size_it != m_column_sizehandler.end() ); 01261 column_it++, size_it++) 01262 { 01263 (*column_it).m_header_area->SetBaseX (x - m_TableArea->GetBaseX() + (m_bShowRowHeader ? ROWHEADERWIDTH : 0) ); 01264 (*column_it).m_header_area->SetBaseY (y - m_TableArea->GetBaseY() ); 01265 int w = (*column_it).m_header_area->GetBaseWidth(); 01266 01267 if ( (column_it + 1) == m_column_header.end() ) 01268 { 01269 // This is the last column 01270 //int w = (*column_it)->header.GetWidth(); 01271 } 01272 01273 x += w; 01274 totalWidth += w; 01275 01276 (*size_it)->SetBaseXY (x + (m_bShowRowHeader ? ROWHEADERWIDTH : 0) - HANDLERSIZE / 2, m_ViewY); 01277 } 01278 01279 return totalWidth; 01280 } 01281 01282 void TableCtrl::FormatTable() 01283 { 01284 int x = m_TableArea->GetBaseX(); 01285 int y = m_TableArea->GetBaseY(); 01286 int totalWidth = (m_bShowRowHeader ? ROWHEADERWIDTH : 0); 01287 int totalHeight = (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0); 01288 01289 totalWidth = FormatHeader(); 01290 x = m_TableArea->GetBaseX(); 01291 y = m_TableArea->GetBaseY(); 01292 01293 bool FirstVisibleItem = true; 01294 TableItem *LastVisibleItem = 0; 01295 01296 int i = 0; 01297 std::vector<sizehandler2 *>::iterator it2; 01298 std::vector<ColumnHeader>::iterator it3; 01299 std::vector<RowHeader *>::iterator it4; 01300 01301 // position the visible parts of m_row_header and m_row_sizehandler only according to m_row_header[i]->_table_item->IsParentOpen() 01302 for (it4 = m_row_header.begin(), it2 = m_row_sizehandler.begin(), i = 0; it4 != m_row_header.end(); it4++, it2++, i++) 01303 { 01304 if (m_row_header[i]->_table_item->IsParentOpen() == true) 01305 { 01306 //---> 01307 int ItemBestHeight = ITEMDEFAULTHEIGHT; 01308 01309 if ( (m_bEnableRowResizing == false) && (m_bEnableItemBestHeight == true) ) 01310 ItemBestHeight = m_row_header[i]->_table_item->GetItemBestHeight(); 01311 01312 //<--- 01313 01314 // This mean we found the first visible item in the tree 01315 if (FirstVisibleItem) 01316 { 01317 FirstVisibleItem = false; 01318 m_row_header[i]->_table_item->m_bIsFirstVisibleItem = true; 01319 } 01320 01321 LastVisibleItem = m_row_header[i]->_table_item; 01322 m_row_header[i]->_table_item->m_bIsLastVisibleItem = false; 01323 01324 m_row_header[i]->_table_item->_row_header_area->SetBaseX (x - m_TableArea->GetBaseX() ); 01325 m_row_header[i]->_table_item->_row_header_area->SetBaseY (y - m_TableArea->GetBaseY() + (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) ); 01326 m_row_header[i]->_table_item->_row_header_area->SetBaseWidth ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) ); 01327 m_row_header[i]->_table_item->_row_header_area->SetBaseHeight (ItemBestHeight); 01328 01329 if (m_bShowRowHeader) 01330 { 01331 m_row_header[i]->_table_item->m_RowHeaderGeometry = Geometry (x, y + (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0), 01332 ROWHEADERWIDTH, m_row_header[i]->_table_item->_row_header_area->GetBaseHeight() ); 01333 } 01334 else 01335 { 01336 m_row_header[i]->_table_item->m_RowHeaderGeometry = Geometry (0, 0, 0, 0); 01337 } 01338 01339 int h = (*it4)->_table_item->_row_header_area->GetBaseHeight(); 01340 01341 y += h; 01342 totalHeight += h; 01343 01344 (*it2)->SetBaseXY (x, y + (m_bShowColumnHeader ? COLUMNHEADERHEIGHT : 0) - HANDLERSIZE / 2); 01345 01346 01347 m_row_header[i]->_table_item->m_ItemGeometryVector.clear(); 01348 01349 for (t_u32 j = 0; j < (t_u32) m_column_header.size(); j++) 01350 { 01351 int x_column, 01352 y_row, 01353 column_width, 01354 row_height; 01355 01356 if (j == 0) 01357 { 01358 // geometry of the first column of the row (minus the open/close bitmap decoration geometry). 01359 if (m_row_header[i]->_table_item->FirstChildNode() != 0) 01360 { 01361 x_column = m_TableArea->GetBaseX() + m_column_header[j].m_header_area->GetBaseX() /*+ (m_bShowRowHeader? ROWHEADERWIDTH : 0)*/ + 01362 ITEM_DEPTH_MARGIN * m_row_header[i]->_table_item->m_depth + OPENCLOSE_BTN_WIDTH; 01363 y_row = m_TableArea->GetBaseY() + m_row_header[i]->_table_item->_row_header_area->GetBaseY(); 01364 column_width = m_column_header[j].m_header_area->GetBaseWidth() - 01365 (ITEM_DEPTH_MARGIN * m_row_header[i]->_table_item->m_depth + OPENCLOSE_BTN_WIDTH); 01366 row_height = m_row_header[i]->_table_item->_row_header_area->GetBaseHeight(); 01367 01368 m_row_header[i]->_table_item->m_FirstColumnUsableGeometry = Geometry (x_column, y_row, column_width, row_height); 01369 } 01370 else 01371 { 01372 x_column = m_TableArea->GetBaseX() + m_column_header[j].m_header_area->GetBaseX() /*+ (m_bShowRowHeader? ROWHEADERWIDTH : 0)*/ + 01373 ITEM_DEPTH_MARGIN * m_row_header[i]->_table_item->m_depth; 01374 y_row = m_TableArea->GetBaseY() + m_row_header[i]->_table_item->_row_header_area->GetBaseY(); 01375 column_width = m_column_header[j].m_header_area->GetBaseWidth() - 01376 (ITEM_DEPTH_MARGIN * m_row_header[i]->_table_item->m_depth); 01377 row_height = m_row_header[i]->_table_item->_row_header_area->GetBaseHeight(); 01378 01379 m_row_header[i]->_table_item->m_FirstColumnUsableGeometry = Geometry (x_column, y_row, column_width, row_height); 01380 } 01381 } 01382 01383 // geometry of the column of the row. 01384 x_column = m_TableArea->GetBaseX() + m_column_header[j].m_header_area->GetBaseX() /*+ (m_bShowRowHeader? ROWHEADERWIDTH : 0)*/; 01385 y_row = m_TableArea->GetBaseY() + m_row_header[i]->_table_item->_row_header_area->GetBaseY(); 01386 column_width = m_column_header[j].m_header_area->GetBaseWidth(); 01387 row_height = m_row_header[i]->_table_item->_row_header_area->GetBaseHeight(); 01388 01389 Geometry geo (x_column, y_row, column_width, row_height); 01390 01391 m_row_header[i]->_table_item->m_ItemGeometryVector.push_back (geo); 01392 } 01393 01394 m_row_header[i]->_table_item->ComputePropertyLayout (m_TableArea->GetBaseX(), 01395 m_TableArea->GetBaseY(), 01396 m_row_header[i], m_column_header); 01397 } 01398 01399 m_row_header[i]->_table_item->m_TotalGeometry = Geometry (m_TableArea->GetBaseX() /* + m_column_header[0].m_header_area->x*/, 01400 m_TableArea->GetBaseY() + m_row_header[i]->_table_item->_row_header_area->GetBaseY(), 01401 m_TableArea->GetBaseWidth() /* - m_column_header[0].m_header_area->x*/, 01402 m_row_header[i]->_table_item->_row_header_area->GetBaseHeight() ); 01403 } 01404 01405 if (LastVisibleItem) 01406 { 01407 LastVisibleItem->m_bIsLastVisibleItem = true; 01408 } 01409 01410 if ( (m_selectedRow != -1) && (m_selectedColumn != -1) ) 01411 { 01412 m_selectedGeometry = Geometry (m_column_header[m_selectedColumn].m_header_area->GetBaseX(), m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY(), 01413 m_column_header[m_selectedColumn].m_header_area->GetBaseWidth(), m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight() ); 01414 } 01415 01416 // Setting the minimum size of m_TableArea forces the composition layout fit match the size of the m_TableArea (+/- margins). If the layout is too large, then 01417 // the scrollbar will reflect that. 01418 // It is not enough to do something like: 01419 // m_VLayout->AddLayout(new WidgetLayout(&m_TableArea), 0, eLeft, eFull); 01420 // with a stretch factor equal to 0. Because m_VLayout is either a HLayout or a VLayout (here it is a VLayout), only one dimension of the composition layout 01421 // will match the similar dimension of m_TableArea-> So only one scrollbar (Horizontal or Vertical) will be adjusted. 01422 m_TableArea->SetMinimumSize (totalWidth, totalHeight + TABLE_AREA_BOTTOM_SPACE); 01423 m_TableArea->SetBaseSize (totalWidth, totalHeight + TABLE_AREA_BOTTOM_SPACE); 01424 01425 // Force the Stretch factor of m_TableArea so that it does not grow bigger than its content if IsSizeMatchContent() returns TRUE. 01426 if (IsSizeMatchContent() ) 01427 { 01428 m_TableArea->SetStretchFactor (0); 01429 } 01430 else 01431 { 01432 m_TableArea->SetStretchFactor (1); 01433 } 01434 } 01435 01436 void TableCtrl::AddColumn (const TCHAR *title, bool fixed_width, int width) 01437 { 01438 if (width < MIN_COLUMN_WIDTH) 01439 addHeader (title, fixed_width, MIN_COLUMN_WIDTH); 01440 else 01441 addHeader (title, fixed_width, width); 01442 01443 m_tableNumColumn += 1; 01444 // m_tableNumColumn = HeaderList.size(); 01445 } 01446 01447 void TableCtrl::AddItem (TableItem *item /*const TCHAR* item_name*/) 01448 { 01449 if (m_tableNumColumn == 0) 01450 { 01451 return; 01452 } 01453 01454 if (item == 0) 01455 return; 01456 01457 TableItem *element = item; 01458 01459 while (element) 01460 { 01461 sizehandler2 *row_sizehandler = new sizehandler2 (NUX_TRACKER_LOCATION); 01462 row_sizehandler->Reference(); 01463 row_sizehandler->SetBaseWidth ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) ); 01464 row_sizehandler->SetBaseHeight (HANDLERSIZE); 01465 01466 t_u32 row_no = (t_u32) m_row_sizehandler.size(); 01467 row_sizehandler->mouse_down.connect (sigc::bind ( sigc::mem_fun (this, &TableCtrl::OnResizeRowMouseDown), row_no) ); 01468 row_sizehandler->mouse_drag.connect (sigc::bind ( sigc::mem_fun (this, &TableCtrl::OnResizeRowMouseDrag), row_no) ); 01469 m_row_sizehandler.push_back (row_sizehandler); 01470 01471 01472 //_table_item.push_back(item->GetName()); 01473 m_tableNumRow += 1; 01474 01475 t_u32 num_row = (t_u32) m_row_header.size(); 01476 01477 if (num_row == 0) 01478 { 01479 RowHeader *h2 = new RowHeader; 01480 Color ItemBackgroundColor = ( (num_row - 1) & 0x1) ? GetRowColorOdd() : GetRowColorEven(); 01481 element->SetBackgroundColor (ItemBackgroundColor); 01482 h2->_table_item = element; 01483 //h2->header.setCaption(num_row); 01484 h2->_table_item->_row_header_area->SetBaseX (0); 01485 h2->_table_item->_row_header_area->SetBaseY (ITEMDEFAULTHEIGHT); 01486 h2->_table_item->_row_header_area->SetBaseWidth ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) ); 01487 h2->_table_item->_row_header_area->SetBaseHeight (ITEMDEFAULTHEIGHT); 01488 m_row_header.push_back (h2); 01489 } 01490 else 01491 { 01492 Geometry g = m_row_header[num_row-1]->_table_item->_row_header_area->GetGeometry(); 01493 RowHeader *h2 = new RowHeader; 01494 01495 Color ItemBackgroundColor = ( (num_row - 1) & 0x1) ? GetRowColorOdd() : GetRowColorEven(); 01496 element->SetBackgroundColor (ItemBackgroundColor); 01497 h2->_table_item = element; 01498 //h2->header.setCaption(num_row); 01499 h2->_table_item->_row_header_area->SetBaseX(0); 01500 h2->_table_item->_row_header_area->SetBaseY(g.y + g.GetHeight()); 01501 h2->_table_item->_row_header_area->SetBaseWidth ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) ); 01502 h2->_table_item->_row_header_area->SetBaseHeight (ITEMDEFAULTHEIGHT); 01503 m_row_header.push_back (h2); 01504 } 01505 01506 if (element->FirstChildNode() ) 01507 AddItem (static_cast<TableItem *> (element->FirstChildNode() ) ); 01508 01509 element = static_cast<TableItem *> (element->Next() ); 01510 } 01511 01512 //FormatTable(); 01513 } 01514 01515 void TableCtrl::ResetItems() 01516 { 01517 std::vector<RowHeader *>::iterator it; 01518 01519 // position the visible parts of m_row_header and m_row_sizehandler only according to m_row_header[i]->_table_item->IsParentOpen() 01520 for (it = m_row_header.begin(); it != m_row_header.end(); it++) 01521 { 01522 (*it)->_table_item->setDirtyItem (false); 01523 (*it)->_table_item->m_bIsMouseInside = false; 01524 01525 } 01526 01527 m_selectedColumn = -1; 01528 m_selectedRow = -1; 01529 m_selectedTableItem = 0; 01530 01531 } 01532 01533 void TableCtrl::setTableItems (TableItem *item, bool isOpen) 01534 { 01535 if (item == 0) 01536 return; 01537 01538 m_TableItemHead->PushChildBack (item); 01539 01540 if (isOpen) 01541 OpOpenItem (item); 01542 else 01543 OpCloseItem (item); 01544 01545 item->Show(); 01546 01547 TraverseItem (item, false, &TableCtrl::OpAddItem); 01548 OpBuildItemDepth (item, 0); 01549 01550 FormatTable(); 01551 ComputeChildLayout(); 01552 } 01553 01554 void TableCtrl::ResetTable() 01555 { 01556 DeleteRowSizeHandler(); 01557 DeleteRowHeader(); 01558 m_tableNumRow = 0; 01559 m_selectedRow = -1; 01560 m_selectedColumn = -1; 01561 m_selectedTableItem = 0; 01562 01563 TableItem *child = (TableItem *) m_TableItemHead->FirstChildNode(); 01564 01565 if (child == 0) 01566 return; 01567 01568 while (child) 01569 { 01570 if (child->isOpen() ) 01571 OpOpenItem (child); 01572 else 01573 OpCloseItem (child); 01574 01575 child->Show(); 01576 child = (TableItem *) child->Next(); 01577 } 01578 01579 child = (TableItem *) m_TableItemHead->FirstChildNode(); 01580 TraverseItem (child, false, &TableCtrl::OpAddItem); 01581 OpBuildItemDepth (child, 0); 01582 01583 FormatTable(); 01584 ComputeChildLayout(); 01585 } 01586 01587 void TableCtrl::DeleteRowSizeHandler() 01588 { 01589 std::vector<sizehandler2 *>::iterator it; 01590 01591 for (it = m_row_sizehandler.begin(); it != m_row_sizehandler.end(); it++) 01592 { 01593 (*it)->UnReference(); 01594 } 01595 01596 m_row_sizehandler.clear(); 01597 } 01598 01599 void TableCtrl::DeleteRowHeader() 01600 { 01601 std::vector<RowHeader *>::iterator it; 01602 01603 for (it = m_row_header.begin(); it != m_row_header.end(); it++) 01604 { 01605 delete (*it); 01606 } 01607 01608 m_row_header.clear(); 01609 } 01610 01611 void TableCtrl::TraverseItem (TableItem *item, bool open_only, ItemOperator f) 01612 { 01613 (this->*f) (item); 01614 01615 // TableItem* item_traverser = item; 01616 // 01617 // while(item_traverser) 01618 // { 01619 // (this->*f)(item_traverser); 01620 // if(open_only) 01621 // { 01622 // if(item_traverser->isOpen() && (item_traverser->FirstChildNode() != 0)) 01623 // { 01624 // TraverseItem(static_cast<TableItem*>(item_traverser->FirstChildNode()), open_only, f); 01625 // } 01626 // } 01627 // else if(item_traverser->FirstChildNode() != 0) 01628 // { 01629 // TraverseItem(static_cast<TableItem*>(item_traverser->FirstChildNode()), open_only, f); 01630 // 01631 // } 01632 // item_traverser = static_cast<TableItem*>(item_traverser->Next()); 01633 // } 01634 } 01635 01636 void TableCtrl::OpBuildItemDepth (TableItem *item, int depth) 01637 { 01638 while (item) 01639 { 01640 item->m_depth = depth; 01641 01642 if (item->FirstChildNode() != 0) 01643 { 01644 OpBuildItemDepth (static_cast<TableItem *> (item->FirstChildNode() ), depth + 1); 01645 } 01646 01647 item = static_cast<TableItem *> (item->Next() ); 01648 } 01649 } 01650 01651 void TableCtrl::OpAddItem (TableItem *item) 01652 { 01653 AddItem (item); 01654 } 01655 01656 void TableCtrl::OpCloseItem (TableItem *item) 01657 { 01658 item->Close(); 01659 OpHideItem (static_cast<TableItem *> (item->FirstChildNode() ) ); 01660 } 01661 01662 // Open the argument item. Then 01663 void TableCtrl::OpOpenItem (TableItem *item) 01664 { 01665 item->Open(); 01666 OpShowItem (static_cast<TableItem *> (item->FirstChildNode() ) ); 01667 } 01668 01669 void TableCtrl::OpHideItem (TableItem *item) 01670 { 01671 while (item) 01672 { 01673 item->Hide(); 01674 01675 if (item->FirstChildNode() ) 01676 { 01677 OpHideItem (static_cast<TableItem *> (item->FirstChildNode() ) ); 01678 } 01679 01680 item = static_cast<TableItem *> (item->Next() ); 01681 } 01682 } 01683 01684 void TableCtrl::OpShowItem (TableItem *item) 01685 { 01686 while (item) 01687 { 01688 item->Show(); 01689 01690 if (item->FirstChildNode() && (item->isOpen() ) ) 01691 { 01692 OpShowItem (static_cast<TableItem *> (item->FirstChildNode() ) ); 01693 } 01694 01695 item = static_cast<TableItem *> (item->Next() ); 01696 } 01697 } 01698 01699 void TableCtrl::FindItemUnderPointer (int x, int y, TableItem **ppItem, int &row, int &column) 01700 { 01701 std::vector<Geometry>::iterator it; 01702 01703 row = -1; 01704 t_u32 num_row = (t_u32) m_row_header.size(); 01705 01706 // test the visible parts of m_row_header only according to m_row_header[i]->_table_item->IsParentOpen() 01707 for (t_u32 i = 0; i < num_row; i++) 01708 { 01709 if (m_row_header[i]->_table_item->IsParentOpen() ) 01710 { 01711 if ( (m_row_header[i]->_table_item->_row_header_area->GetBaseY() <= y) && 01712 (m_row_header[i]->_table_item->_row_header_area->GetBaseY() + m_row_header[i]->_table_item->_row_header_area->GetBaseHeight() > y) ) 01713 { 01714 row = i; 01715 break; 01716 } 01717 } 01718 } 01719 01720 column = -1; 01721 t_u32 num_col = (t_u32) m_column_header.size(); 01722 01723 for (t_u32 i = 0; i < num_col; i++) 01724 { 01725 if ( (m_column_header[i].m_header_area->GetBaseX() <= x) && (m_column_header[i].m_header_area->GetBaseX() + m_column_header[i].m_header_area->GetBaseWidth() > x) ) 01726 { 01727 column = i; 01728 break; 01729 } 01730 } 01731 01732 *ppItem = 0; 01733 01734 if ( (row != -1) && (column != -1) ) 01735 { 01736 *ppItem = m_row_header[row]->_table_item; 01737 } 01738 } 01739 01740 void TableCtrl::OnMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) 01741 { 01742 if (m_selectedTableItem) 01743 { 01744 // Dirty the previously selected item. No need to call QueueDraw because this is a mouse down and the 01745 // WindowThread will call Draw(event, false) on a NUX_MOUSE_PRESSED event. 01746 // When this item redraws, it will draw without the selection background color. 01747 m_selectedTableItem->setDirtyItem (true); 01748 } 01749 01750 m_selectedTableItem = 0; 01751 FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn); 01752 01753 m_selectedGeometry.SetX (0); 01754 m_selectedGeometry.SetY (0); 01755 m_selectedGeometry.SetWidth (0); 01756 m_selectedGeometry.SetHeight (0); 01757 01758 if (m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/) 01759 { 01760 // selected item geometry 01761 int sx, sy, sw, sh; 01762 sx = m_column_header[m_selectedColumn].m_header_area->GetBaseX(); 01763 sw = m_column_header[m_selectedColumn].m_header_area->GetBaseWidth(); 01764 sy = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY(); 01765 sh = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight(); 01766 01767 m_selectedGeometry = Geometry (sx, sy, sw, sh); 01768 sigItemSelected.emit (m_selectedRow, m_selectedColumn); 01769 sigTableItemSelected.emit (*this, *m_selectedTableItem, m_selectedRow, m_selectedColumn); 01770 01771 // Dirty the newly selected item. No need to call QueueDraw because this is a mouse down and the 01772 // WindowThread will call Draw(event, false) on a NUX_MOUSE_PRESSED event. 01773 // When this item redraws, it will draw with the selection background color. 01774 m_selectedTableItem->setDirtyItem (true); 01775 } 01776 01777 if ( (m_selectedRow == -1) || (m_selectedColumn == -1) ) 01778 return; 01779 01780 bool Reorganize = false; 01781 01782 if (m_row_header[m_selectedRow]->_table_item->FirstChildNode() || m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton() ) 01783 { 01784 Geometry geo = m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0]; 01785 geo.SetX ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[m_selectedRow]->_table_item->m_depth); 01786 geo.SetY (m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0].y - m_TableArea->GetBaseY() ); 01787 geo.SetWidth (OPENCLOSE_BTN_WIDTH); 01788 01789 if (geo.IsPointInside (x, y) ) 01790 { 01791 if (m_row_header[m_selectedRow]->_table_item->isOpen() ) 01792 { 01793 Reorganize = true; 01794 OpCloseItem (m_row_header[m_selectedRow]->_table_item); 01795 01796 if (IsSizeMatchContent() ) 01797 { 01798 // when closing and item, the Table gets shorter and might leave a dirty area filled with part of the Table content. 01799 // We need to call a PaintBackground on the area of the Table (area before the item is closed). 01800 m_DrawBackgroundOnPreviousGeometry = true; 01801 m_PreviousGeometry = GetGeometry(); 01802 // Initiate layout re computation from the top. This should be done with InitiateResizeLayout(); 01803 // but it is a private member of Area. We can do it with a call to SetGeometry(GetGeometry()); 01804 SetGeometry (GetGeometry() ); 01805 } 01806 } 01807 else 01808 { 01809 Reorganize = true; 01810 OpOpenItem (m_row_header[m_selectedRow]->_table_item); 01811 } 01812 } 01813 else 01814 { 01815 //do nothing 01816 // You have to click on the Open/Close button to close the item 01817 } 01818 } 01819 01820 if (Reorganize == true) 01821 { 01822 // The TableCtrl is completely dirty. 01823 // By calling QueueDraw(), we make sure we go through TableCtrl::Draw() then TableCtrl::DrawContent() when drawing happens. 01824 ComputeChildLayout(); 01825 PositionChildLayout (0, 0); 01826 QueueDraw(); 01827 } 01828 } 01829 01830 //All Windows users are occasionally slowed by the need to double-click the mouse several times 01831 //to launch an icon. Even after you have adjusted your mouse's Double Click Speed setting in the 01832 //Windows Control Panel, you may still be plagued by double takes on your double-clicks. This is 01833 //because there is a second, often overlooked setting that controls Windows' ability to register 01834 //a double-click. By default, Windows allows the mouse to move the distance of only two pixels 01835 //during a double-click. If you move your mouse more than two pixels in any direction between 01836 //mouse clicks, Windows will interpret this as two single clicks instead of a single double-click. 01837 //As monitor resolutions get higher and pixel density increases, jerky mouse movements are even 01838 //more susceptible to double-click failures. 01839 //Fortunately, you can increase the two-pixel limit by: 01840 //Open Start Menu/Control Panel/Mouse/Buttons Tab Click on Options and choose a higher number, 01841 //(5-12), and you should begin to notice that Windows is no longer ignoring as many double-clicks 01842 //as it did before. 01843 01844 void TableCtrl::mouse_double_click (int x, int y, unsigned long button_flags, unsigned long key_flags) 01845 { 01846 if ( (m_selectedRow == -1) || (m_selectedColumn == -1) ) 01847 { 01848 // The double click becomes a simple click if we know in advance that the first click didn't select anything. 01849 //OnMouseDown(x, y, button_flags, key_flags); 01850 return; 01851 } 01852 01853 int previous_click_row = m_selectedRow; 01854 01855 m_selectedTableItem = 0; 01856 FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn); 01857 01858 if ( (m_selectedTableItem == 0) || (m_selectedRow == -1) || (m_selectedColumn == -1) ) 01859 return; 01860 01861 if (m_selectedRow != previous_click_row) 01862 { 01863 // The second button down of this double click is not on the same row. Interpret this as a mouse down. 01864 OnMouseDown (x, y, button_flags, key_flags); 01865 return; 01866 } 01867 01868 m_selectedGeometry.SetX (0); 01869 m_selectedGeometry.SetY (0); 01870 m_selectedGeometry.SetWidth (0); 01871 m_selectedGeometry.SetHeight (0); 01872 01873 if (m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/) 01874 { 01875 // selected item geometry 01876 int sx, sy, sw, sh; 01877 sx = m_column_header[m_selectedColumn].m_header_area->GetBaseX(); 01878 sw = m_column_header[m_selectedColumn].m_header_area->GetBaseWidth(); 01879 sy = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY(); 01880 sh = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight(); 01881 01882 m_selectedGeometry = Geometry (sx, sy, sw, sh); 01883 // we couldsend a signal meaning a double click has happened on an item. 01884 //sigItemDoubleClick.emit(m_row_header[m_selectedRow]->_table_item); 01885 } 01886 01887 bool Reorganize = false; 01888 01889 // Check if item as a child node. If not, there is no point in opening/closing it. 01890 if (m_row_header[m_selectedRow]->_table_item->FirstChildNode() || m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton() ) 01891 { 01892 Geometry geo = m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0]; 01893 geo.SetX ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[m_selectedRow]->_table_item->m_depth); 01894 geo.SetY (m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0].y - m_TableArea->GetBaseY() ); 01895 geo.SetWidth (OPENCLOSE_BTN_WIDTH); 01896 01897 if (geo.IsPointInside (x, y) ) 01898 { 01899 Reorganize = true; 01900 OnMouseDown (x, y, button_flags, key_flags); 01901 } 01902 else 01903 { 01904 if (m_row_header[m_selectedRow]->_table_item->isOpen() ) 01905 { 01906 Reorganize = true; 01907 OpCloseItem (m_row_header[m_selectedRow]->_table_item); 01908 01909 if (IsSizeMatchContent() ) 01910 { 01911 // when closing and item, the Table gets shorter and might leave a dirty area filled with part of the Table content. 01912 // We need to call a PaintBackground on the area of the Table (area before the item is closed). 01913 m_DrawBackgroundOnPreviousGeometry = true; 01914 m_PreviousGeometry = GetGeometry(); 01915 // Initiate layout re computation from the top. This should be done with InitiateResizeLayout(); 01916 // but it is a private member of Area. We can do it with a call to SetGeometry(GetGeometry()); 01917 SetGeometry (GetGeometry() ); 01918 } 01919 } 01920 else 01921 { 01922 Reorganize = true; 01923 OpOpenItem (m_row_header[m_selectedRow]->_table_item); 01924 } 01925 } 01926 } 01927 01928 if (Reorganize) 01929 { 01930 FormatTable(); 01931 ComputeChildLayout(); 01932 QueueDraw(); 01933 } 01934 } 01935 01936 void TableCtrl::OnMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags) 01937 { 01938 return; 01939 m_selectedTableItem = 0; 01940 FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn); 01941 01942 m_selectedGeometry.SetX (0); 01943 m_selectedGeometry.SetY (0); 01944 m_selectedGeometry.SetWidth (0); 01945 m_selectedGeometry.SetHeight (0); 01946 01947 if (m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/) 01948 { 01949 // selected item geometry 01950 int sx, sy, sw, sh; 01951 sx = m_column_header[m_selectedColumn].m_header_area->GetBaseX(); 01952 sw = m_column_header[m_selectedColumn].m_header_area->GetBaseWidth(); 01953 sy = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY(); 01954 sh = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight(); 01955 01956 m_selectedGeometry = Geometry (sx, sy, sw, sh); 01957 // These signals are called at the mouse down on an item. Do not call them here. 01958 //sigItemSelected.emit(m_selectedRow, m_selectedColumn); 01959 //sigTableItemSelected.emit(*this, *m_selectedTableItem, m_selectedRow, m_selectedColumn); 01960 } 01961 } 01962 01963 void TableCtrl::mouse_drag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) 01964 { 01965 return; 01966 01967 if (m_selectedTableItem) 01968 m_selectedTableItem->setDirtyItem (true); 01969 01970 m_selectedTableItem = 0; 01971 FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn); 01972 01973 if ( (m_selectedRow != -1) && (m_selectedColumn != -1) ) 01974 { 01975 m_selectedTableItem->setDirtyItem (true); 01976 } 01977 01978 QueueDraw(); 01979 } 01980 01981 void TableCtrl::OnKeyboardFocus() 01982 { 01983 01984 } 01985 void TableCtrl::OnLostKeyboardFocus() 01986 { 01987 01988 } 01989 01990 void TableCtrl::OnResizeHeaderMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags, t_u32 header_pos) 01991 { 01992 //m_column_header_preview = m_column_header; 01993 m_point0 = Point(x, y); 01994 } 01995 01996 void TableCtrl::OnResizeHeaderMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags, t_u32 header_pos) 01997 { 01998 //m_column_header = m_column_header_preview; 01999 //m_column_header_preview.clear(); 02000 GetWindowCompositor().SetWidgetDrawingOverlay (NULL, GetWindowCompositor().GetProcessingTopView() ); 02001 02002 if (true) 02003 { 02004 FormatTable(); 02005 //ComputeChildLayout(); 02006 } 02007 02008 QueueDraw(); 02009 } 02010 02011 void TableCtrl::OnResizeHeaderMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags, t_u32 header_pos) 02012 { 02013 GetWindowCompositor().SetWidgetDrawingOverlay (this, GetWindowCompositor().GetProcessingTopView() ); 02014 02015 bool recompute = false; 02016 02017 t_s32 num_header = (t_s32) m_column_header.size(); 02018 02019 if ( (isFloatingColumn() == false) && (header_pos >= m_column_header.size() - 1) ) 02020 { 02021 // The columns takes all available space. The last column size handler 02022 // is fix(always at the extreme right of the available space. 02023 return; 02024 } 02025 02026 Geometry geo = m_column_header[header_pos].m_header_area->GetGeometry(); 02027 02028 int deltax = 0; 02029 02030 if (isFloatingColumn() == true) 02031 { 02032 recompute = false; 02033 02034 if ( (dx > 0) && (x > m_point0.x) ) 02035 { 02036 geo.OffsetSize ( x - m_point0.x, 0); 02037 recompute = true; 02038 } 02039 02040 if ( (dx < 0) && (x < m_point0.x) ) 02041 { 02042 geo.OffsetSize (x - m_point0.x, 0); 02043 recompute = true; 02044 } 02045 02046 deltax = x - m_point0.x; 02047 int w = m_column_header[header_pos].m_header_area->GetBaseWidth() + deltax; 02048 m_column_header[header_pos].m_header_area->SetBaseWidth (w); 02049 02050 if (m_column_header[header_pos].m_header_area->GetBaseWidth() < MIN_COLUMN_WIDTH) 02051 { 02052 m_column_header[header_pos].m_header_area->SetBaseWidth (MIN_COLUMN_WIDTH); 02053 } 02054 02055 } 02056 02057 if (isFloatingColumn() == false) 02058 { 02059 // Need to find the next element who can absorb the difference 02060 int element_pos; 02061 int deltax = x - m_point0.x; 02062 02063 if (m_column_header[header_pos]._fix_width == true) 02064 { 02065 bool found = false; 02066 02067 for (int i = header_pos - 1; i >= 0; i--) 02068 { 02069 if (m_column_header[i]._fix_width == false) 02070 { 02071 header_pos = i; 02072 found = true; 02073 break; 02074 } 02075 } 02076 02077 if (found == false) 02078 return; 02079 } 02080 02081 int header_width = m_column_header[header_pos].m_header_area->GetBaseWidth(); 02082 02083 for (t_s32 i = (t_s32) header_pos + 1; ( (i < num_header) && (deltax != 0) ); i++) 02084 { 02085 t_s32 element_width = (t_s32) m_column_header[i].m_header_area->GetBaseWidth(); 02086 02087 if ( (m_column_header[i]._fix_width == false) /*&& (element_width > 10)*/) 02088 { 02089 element_pos = i; 02090 02091 if ( (dx > 0) && (x > m_point0.x) ) 02092 { 02093 // Increasing the width of the header; delta is > 0. 02094 02095 int absorbed_width = 0; 02096 02097 if (element_width - deltax < MIN_COLUMN_WIDTH) 02098 { 02099 absorbed_width = element_width - MIN_COLUMN_WIDTH; 02100 } 02101 else 02102 { 02103 // the element can absorb the totality of deltax 02104 absorbed_width = deltax; 02105 } 02106 02107 int w = m_column_header[header_pos].m_header_area->GetBaseWidth() + absorbed_width; 02108 m_column_header[header_pos].m_header_area->SetBaseWidth (w); 02109 02110 int x = m_column_header[element_pos].m_header_area->GetBaseX() + absorbed_width; 02111 m_column_header[element_pos].m_header_area->SetBaseX (x); 02112 w = m_column_header[element_pos].m_header_area->GetBaseWidth() - absorbed_width; 02113 m_column_header[element_pos].m_header_area->SetBaseWidth (w); 02114 02115 for (int j = header_pos + 1; j < element_pos; j++) 02116 { 02117 int x = m_column_header[j].m_header_area->GetBaseX() + absorbed_width; 02118 m_column_header[j].m_header_area->SetBaseX (x); 02119 } 02120 02121 recompute = true; 02122 deltax = deltax - absorbed_width; 02123 } 02124 02125 if ( (dx < 0) && (x < m_point0.x) ) 02126 { 02127 // Decreasing the width of the header; delta is < 0. 02128 02129 int absorbed_width = 0; 02130 header_width = m_column_header[header_pos].m_header_area->GetBaseWidth(); 02131 02132 if (header_width + deltax < MIN_COLUMN_WIDTH) 02133 { 02134 absorbed_width = header_width - MIN_COLUMN_WIDTH; 02135 } 02136 else 02137 { 02138 // the element can absorb the totality of deltax 02139 absorbed_width = -deltax; 02140 } 02141 02142 int w = m_column_header[header_pos].m_header_area->GetBaseWidth() - absorbed_width; 02143 m_column_header[header_pos].m_header_area->SetBaseWidth (w); 02144 02145 int x = m_column_header[element_pos].m_header_area->GetBaseX() - absorbed_width; 02146 m_column_header[element_pos].m_header_area->SetBaseX (x); 02147 w = m_column_header[element_pos].m_header_area->GetBaseWidth() + absorbed_width; 02148 m_column_header[element_pos].m_header_area->SetBaseWidth (w); 02149 02150 for (int j = header_pos + 1; j < element_pos; j++) 02151 { 02152 int x = m_column_header[j].m_header_area->GetBaseX() - absorbed_width; 02153 m_column_header[j].m_header_area->SetBaseX (x); 02154 } 02155 02156 recompute = true; 02157 deltax = deltax + absorbed_width; 02158 } 02159 } 02160 } 02161 } 02162 02163 if (recompute == true) 02164 { 02165 FormatHeader(); 02166 } 02167 02168 //QueueDraw(); 02169 } 02170 02171 void TableCtrl::OnResizeRowMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags, t_u32 header_pos) 02172 { 02173 m_point1 = Point(x, y); 02174 02175 char s[42]; 02176 sprintf (s, "%d ", header_pos); 02177 //OutputDebugString(s); 02178 } 02179 02180 void TableCtrl::OnResizeRowMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags, t_u32 header_pos) 02181 { 02182 bool recompute = false; 02183 Geometry geo = m_row_header[header_pos]->_table_item->_row_header_area->GetGeometry(); 02184 02185 if ( (dy > 0) && (y > m_point1.y) ) 02186 { 02187 geo.OffsetSize (0, y - m_point1.y); 02188 recompute = true; 02189 } 02190 02191 if ( (dy < 0) && (y < m_point1.y) ) 02192 { 02193 geo.OffsetSize (0, y - m_point1.y); 02194 recompute = true; 02195 } 02196 02197 m_row_header[header_pos]->_table_item->_row_header_area->SetGeometry (geo); 02198 02199 if (m_row_header[header_pos]->_table_item->_row_header_area->GetBaseHeight() < MIN_COLUMN_WIDTH) 02200 { 02201 m_row_header[header_pos]->_table_item->_row_header_area->SetBaseHeight (MIN_COLUMN_WIDTH); 02202 } 02203 02204 if (recompute == true) 02205 { 02206 FormatTable(); 02207 ComputeChildLayout(); 02208 } 02209 02210 QueueDraw(); 02211 } 02212 02213 void TableCtrl::PreLayoutManagement() 02214 { 02215 // This will configure sizes of different elements of the window. Including the size of the layout. 02216 ScrollView::PreLayoutManagement(); 02217 02218 if (isFloatingColumn() == false) 02219 { 02220 // This will adjust the width of header according to the new size. 02221 AdjustNonFloatingColumn(); 02222 } 02223 02224 // This is going to resize the m_TableArea according to the header width and the height 02225 // of individual rows summed up together. 02226 FormatTable(); 02227 // During the layout computation, the m_VLayout (which has a stretch factor of 1) will respect the size of m_TableArea-> 02228 } 02229 02230 // Get a change to do any work on an element. 02231 // Here we need to position the header by hand because it is not under the control of m_VLayout. 02232 long TableCtrl::PostLayoutManagement (long LayoutResult) 02233 { 02234 // Set the ViewContext Size and position before going into ScrollView::PostLayoutManagement. 02235 // this is needed for SetSizeMatchContent() to work correctly. 02236 m_ViewContentX = m_TableArea->GetBaseX(); 02237 m_ViewContentY = m_TableArea->GetBaseY(); 02238 m_ViewContentWidth = m_TableArea->GetBaseWidth(); 02239 m_ViewContentHeight = m_TableArea->GetBaseHeight(); 02240 02241 long result = ScrollView::PostLayoutManagement (LayoutResult); 02242 02243 if (isFloatingColumn() == false) 02244 { 02245 AdjustNonFloatingColumn(); 02246 } 02247 02248 ScrollView::PositionChildLayout (0, 0); 02249 FormatTable(); 02250 return result; 02251 } 02252 02253 // Get a change to do any work on an element. 02254 // Here we need to position the header by hand because it is not under the control of m_VLayout. 02255 void TableCtrl::PositionChildLayout (float offsetX, float offsetY) 02256 { 02257 ScrollView::PositionChildLayout (offsetX, offsetY); 02258 FormatTable(); 02259 } 02260 02261 void TableCtrl::ScrollLeft (float stepx, int mousedx) 02262 { 02263 ScrollView::ScrollLeft (stepx, mousedx); 02264 //FormatTable(); 02265 } 02266 02267 void TableCtrl::ScrollRight (float stepx, int mousedx) 02268 { 02269 ScrollView::ScrollRight (stepx, mousedx); 02270 //FormatTable(); 02271 } 02272 02273 void TableCtrl::ScrollUp (float stepy, int mousedy) 02274 { 02275 ScrollView::ScrollUp (stepy, mousedy); 02276 //FormatTable(); 02277 } 02278 02279 void TableCtrl::ScrollDown (float stepy, int mousedy) 02280 { 02281 ScrollView::ScrollDown (stepy, mousedy); 02282 //FormatTable(); 02283 } 02284 02285 void TableCtrl::ShowRowHeader (bool b) 02286 { 02287 m_bShowRowHeader = b; 02288 FormatTable(); 02289 } 02290 02291 void TableCtrl::ShowColumnHeader (bool b) 02292 { 02293 m_bShowColumnHeader = b; 02294 FormatTable(); 02295 } 02296 02297 void TableCtrl::ShowVerticalSeparationLine (bool b) 02298 { 02299 m_bShowVerticalSeparationLine = b; 02300 FormatTable(); 02301 } 02302 02303 void TableCtrl::ShowHorizontalSeparationLine (bool b) 02304 { 02305 m_bShowHorizontalSeparationLine = b; 02306 FormatTable(); 02307 } 02308 02309 void TableCtrl::ShowSeparationLine (bool bHor, bool bVert) 02310 { 02311 m_bShowHorizontalSeparationLine = bHor; 02312 m_bShowVerticalSeparationLine = bVert; 02313 FormatTable(); 02314 } 02315 02316 void TableCtrl::SetFloatingColumn (bool b) 02317 { 02318 m_FloatingColumn = b; 02319 02320 if (m_FloatingColumn == false) 02321 { 02322 ComputeNonFloatingColumn(); 02323 } 02324 02325 FormatTable(); 02326 } 02327 02328 bool TableCtrl::isFloatingColumn() 02329 { 02330 return m_FloatingColumn; 02331 } 02332 02333 t_s32 TableCtrl::GetNumColumn() 02334 { 02335 return (t_u32) m_column_header.size(); 02336 } 02337 02338 t_s32 TableCtrl::GetNumRow() 02339 { 02340 return (t_u32) m_row_header.size(); 02341 } 02342 02343 void TableCtrl::EnableApplyItemBestHeight (bool b) 02344 { 02345 m_bEnableItemBestHeight = b; 02346 } 02347 02348 void TableCtrl::ForceStartFocusOnContentTable (int x, int y) 02349 { 02350 m_TableArea->ForceStartFocus (x, y); 02351 } 02352 02353 void TableCtrl::EmptyTable() 02354 { 02355 m_TableItemHead->DeleteTree(); 02356 QueueDraw(); 02357 } 02358 02359 void TableCtrl::QueueDraw() 02360 { 02361 nuxAssertNoRecursion(); 02362 View::QueueDraw(); 02363 } 02364 02365 void TableCtrl::HighlightItem (int row, int column) 02366 { 02367 m_selectedRow = row; 02368 m_selectedColumn = column; 02369 QueueDraw(); 02370 } 02371 02372 02373 }