nux-1.16.0
TreeControl.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 "TreeControl.h"
00025 
00026 namespace nux
00027 {
00028 
00029   TreeItem::TreeItem (const TCHAR *name, NodeParameterType type)
00030     :   TableItem (name, type)
00031   {
00032     Close();
00033   }
00034 
00035   TreeItem::~TreeItem()
00036   {
00037 
00038   }
00039 
00040   long TreeItem::ProcessPropertyEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo)
00041   {
00042     long ret = TraverseInfo;
00043 
00044     return ret;
00045   }
00046 
00047   void TreeItem::DrawProperty (GraphicsEngine &GfxContext, TableCtrl *table, bool force_draw, Geometry geo, const BasePainter &Painter,
00048                                RowHeader *row, const std::vector<ColumnHeader>& column_vector, Color ItemBackgroundColor)
00049   {
00050     Geometry FirstColumnGeometry = m_ItemGeometryVector[0];
00051 
00052     if (isDirtyItem() )
00053     {
00054       t_u32 nBackground;
00055 
00056       if (m_bIsMouseInside)
00057       {
00058         nBackground = table->PushItemBackground (GfxContext, this, true);
00059       }
00060       else
00061       {
00062         nBackground = table->PushItemBackground (GfxContext, this, false);
00063       }
00064 
00065       Painter.PaintTextLineStatic (GfxContext, GetSysFont(), geo, row->_table_item->GetName(), GetItemTextColor());
00066       table->PopItemBackground (GfxContext, nBackground);
00067     }
00068   }
00069 
00070   void TreeItem::ComputePropertyLayout (int x, int y, RowHeader *row, const std::vector<ColumnHeader>& column_vector)
00071   {
00072 
00073   }
00074 
00075   int TreeItem::GetItemBestHeight()
00076   {
00077     return ITEMDEFAULTHEIGHT;
00078   }
00079 
00081   TreeControl::TreeControl()
00082     :   TableCtrl (false)
00083   {
00084     TableCtrl::ShowColumnHeader (true);
00085     TableCtrl::ShowRowHeader (false);
00086     TableCtrl::EnableColumnResizing (true);
00087     TableCtrl::EnableApplyItemBestHeight (false);
00088   }
00089 
00090   TreeControl::~TreeControl()
00091   {
00092 
00093   }
00094 
00095   void TreeControl::OnMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags)
00096   {
00097     int previous_click_row = m_selectedRow;
00098 
00099     m_selectedTableItem = 0;
00100     FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn);
00101 
00102     m_selectedGeometry.SetX (0);
00103     m_selectedGeometry.SetY (0);
00104     m_selectedGeometry.SetWidth (0);
00105     m_selectedGeometry.SetHeight (0);
00106 
00107     if (m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/)
00108     {
00109       // selected item geometry
00110       int sx, sy, sw, sh;
00111       sx = m_column_header[m_selectedColumn].m_header_area->GetBaseX();
00112       sw = m_column_header[m_selectedColumn].m_header_area->GetBaseWidth();
00113       sy = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY();
00114       sh = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight();
00115 
00116       m_selectedGeometry = Geometry (sx, sy, sw, sh);
00117       //        sigItemSelected.emit(m_selectedRow, m_selectedColumn);
00118       //        sigTableItemSelected.emit(*this, *m_selectedTableItem, m_selectedRow, m_selectedColumn);
00119     }
00120 
00121     if (1)
00122     {
00123       // This is a double click
00124       if ( (m_selectedRow == -1) || (m_selectedColumn == -1) )
00125         return;
00126 
00127 
00128       if (!m_row_header[m_selectedRow]->_table_item->isOpen() && (m_row_header[m_selectedRow]->_table_item->FirstChildNode() || m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton() ) )
00129       {
00130         // If it is not open, then open it.
00131         OpOpenItem (m_row_header[m_selectedRow]->_table_item);
00132         //if(m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/)
00133       }
00134       else
00135       {
00136         if (m_row_header[m_selectedRow]->_table_item->FirstChildNode() /*|| m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton()*/)
00137         {
00138           Geometry geo = m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0];
00139           geo.SetX ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[m_selectedRow]->_table_item->m_depth);
00140           geo.SetY (m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0].y - m_TableArea->GetBaseY() );
00141           geo.SetWidth (OPENCLOSE_BTN_WIDTH);
00142 
00143           if (geo.IsPointInside (x, y) )
00144           {
00145             if (m_row_header[m_selectedRow]->_table_item->isOpen() )
00146             {
00147               OpCloseItem (m_row_header[m_selectedRow]->_table_item);
00148 
00149               if (IsSizeMatchContent() )
00150               {
00151                 // when closing and item, the Table gets shorter and might leave a dirty area filled with part of the Table content.
00152                 // We need to call a PaintBackground on the area of the Table (area before the item is closed).
00153                 m_DrawBackgroundOnPreviousGeometry = true;
00154                 m_PreviousGeometry = GetGeometry();
00155                 // Initiate layout re computation from the top. This should be done with InitiateResizeLayout();
00156                 // but it is a private member of Area. We can do it with a call to SetGeometry(GetGeometry());
00157                 SetGeometry (GetGeometry() );
00158               }
00159             }
00160             else
00161             {
00162               OpOpenItem (m_row_header[m_selectedRow]->_table_item);
00163             }
00164           }
00165           else
00166           {
00167             //do nothing
00168             // You have to click on the Open/Close button to close the item
00169           }
00170         }
00171       }
00172 
00173       FormatTable();
00174       ComputeChildLayout();
00175     }
00176 
00177     if ( (previous_click_row >= 0) && (previous_click_row != m_selectedRow) && (m_row_header[previous_click_row]->_table_item->FirstChildNode() == 0) )
00178       OpCloseItem (m_row_header[previous_click_row]->_table_item);
00179 
00180     //else if((previous_click_row >= 0) && (m_row_header[previous_click_row]->_table_item->FirstChildNode() == 0))
00181     //  OpCloseItem(m_row_header[previous_click_row]->_table_item);
00182 
00183 
00184     {
00185       sigItemSelected.emit (m_selectedRow, m_selectedColumn);
00186       sigTableItemSelected.emit (*this, *m_selectedTableItem, m_selectedRow, m_selectedColumn);
00187     }
00188     QueueDraw();
00189   }
00190 
00191   void TreeControl::mouse_double_click (int x, int y, unsigned long button_flags, unsigned long key_flags)
00192   {
00193     if ( (m_selectedRow == -1) || (m_selectedColumn == -1) )
00194     {
00195       // The double click becomes a simple click if we know in advance that the first click didn't select anything.
00196       //OnMouseDown(x, y, button_flags, key_flags);
00197       return;
00198     }
00199 
00200     int previous_click_row = m_selectedRow;
00201 
00202     m_selectedTableItem = 0;
00203     FindItemUnderPointer (x, y, &m_selectedTableItem, m_selectedRow, m_selectedColumn);
00204 
00205     if ( (m_selectedTableItem == 0) || (m_selectedRow == -1) || (m_selectedColumn == -1) )
00206       return;
00207 
00208     if (m_selectedRow != previous_click_row)
00209     {
00210       // The second button down of this double click is not on the same row. Interpret this as a mouse down.
00211       OnMouseDown (x, y, button_flags, key_flags);
00212       return;
00213     }
00214 
00215     m_selectedGeometry.SetX (0);
00216     m_selectedGeometry.SetY (0);
00217     m_selectedGeometry.SetWidth (0);
00218     m_selectedGeometry.SetHeight (0);
00219 
00220     if (m_selectedTableItem /*(m_selectedRow != -1) && (m_selectedColumn != -1)*/)
00221     {
00222       // selected item geometry
00223       int sx, sy, sw, sh;
00224       sx = m_column_header[m_selectedColumn].m_header_area->GetBaseX();
00225       sw = m_column_header[m_selectedColumn].m_header_area->GetBaseWidth();
00226       sy = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseY();
00227       sh = m_row_header[m_selectedRow]->_table_item->_row_header_area->GetBaseHeight();
00228 
00229       m_selectedGeometry = Geometry (sx, sy, sw, sh);
00230       // we could send a signal meaning a double click has happened on an item.
00231       //sigItemDoubleClick.emit(m_row_header[m_selectedRow]->_table_item);
00232     }
00233 
00234     // Check if item as a child node. If not, there is no point in opening/closing it.
00235     if (m_row_header[m_selectedRow]->_table_item->FirstChildNode() /*|| m_row_header[m_selectedRow]->_table_item->AlwaysShowOpeningButton()*/)
00236     {
00237       Geometry geo = m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0];
00238       geo.SetX ( (m_bShowRowHeader ? ROWHEADERWIDTH : 0) + ITEM_DEPTH_MARGIN * m_row_header[m_selectedRow]->_table_item->m_depth);
00239       geo.SetY (m_row_header[m_selectedRow]->_table_item->m_ItemGeometryVector[0].y - m_TableArea->GetBaseY() );
00240       geo.SetWidth (OPENCLOSE_BTN_WIDTH);
00241 
00242       if (geo.IsPointInside (x, y) )
00243       {
00244         OnMouseDown (x, y, button_flags, key_flags);
00245       }
00246       else
00247       {
00248         //            if(m_row_header[m_selectedRow]->_table_item->isOpen())
00249         //            {
00250         //                OpCloseItem(m_row_header[m_selectedRow]->_table_item);
00251         //                if(IsSizeMatchContent())
00252         //                {
00253         //                    // when closing and item, the Table gets shorter and might leave a dirty area filled with part of the Table content.
00254         //                    // We need to call a PaintBackground on the area of the Table (area before the item is closed).
00255         //                    m_DrawBackgroundOnPreviousGeometry = true;
00256         //                    m_PreviousGeometry = GetGeometry();
00257         //                    // Initiate layout re computation from the top. This should be done with InitiateResizeLayout();
00258         //                    // but it is a private member of Area. We can do it with a call to SetGeometry(GetGeometry());
00259         //                    SetGeometry(GetGeometry());
00260         //                }
00261         //            }
00262         //            else
00263         //            {
00264         //                OpOpenItem(m_row_header[m_selectedRow]->_table_item);
00265         //            }
00266       }
00267     }
00268 
00269     FormatTable();
00270     ComputeChildLayout();
00271   }
00272 
00273 
00274 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends