nux-1.16.0
TableCtrl.cpp
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 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends