Merge "Fix the warning log in Control causing the wrong position" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / table-view / table-view-impl.h
1 #ifndef __DALI_TOOLKIT_INTERNAL_TABLE_VIEW_H__
2 #define __DALI_TOOLKIT_INTERNAL_TABLE_VIEW_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali-toolkit/public-api/controls/control-impl.h>
23 #include <dali-toolkit/public-api/controls/table-view/table-view.h>
24 #include "array-2d.h"
25
26 namespace Dali
27 {
28
29 namespace Toolkit
30 {
31
32 namespace Internal
33 {
34
35 /**
36  * TableView is a custom control for laying out actors in a table layout
37  * @see Dali::Toolkit:TableView for more details
38  */
39 class TableView : public Control
40 {
41 public:
42
43   /**
44    * Create a new TableView.
45    * @return A smart-pointer to the newly allocated TableView.
46    */
47   static Toolkit::TableView New( unsigned int initialRows, unsigned int initialColumns );
48
49   /**
50    * @copydoc Toolkit::TableView::AddChild
51    */
52   bool AddChild( Actor& child, const Toolkit::TableView::CellPosition& position );
53
54   /**
55    * @copydoc Toolkit::TableView::GetChildAt
56    */
57   Actor GetChildAt( const Toolkit::TableView::CellPosition& position );
58
59   /**
60    * @copydoc Toolkit::TableView::RemoveChildAt
61    */
62   Actor RemoveChildAt( const Toolkit::TableView::CellPosition& position );
63
64   /**
65    * @copydoc Toolkit::TableView::FindChildPosition
66    */
67   bool FindChildPosition( const Actor& child, Toolkit::TableView::CellPosition& positionOut );
68
69   /**
70    * @copydoc Toolkit::TableView::InsertRow
71    */
72   void InsertRow( unsigned int rowIndex );
73
74   /**
75    * @copydoc Toolkit::TableView::DeleteRow( unsigned int rowIndex )
76    */
77   void DeleteRow( unsigned int rowIndex );
78
79   /**
80    * @copydoc Toolkit::TableView::DeleteRow( unsigned int rowIndex, std::vector<Actor>& removed )
81    */
82   void DeleteRow( unsigned int rowIndex, std::vector<Actor>& removed );
83
84   /**
85    * @copydoc Toolkit::TableView::InsertColumn
86    */
87   void InsertColumn( unsigned int columnIndex );
88
89   /**
90    * @copydoc Toolkit::TableView::DeleteColumn( unsigned int columnIndex )
91    */
92   void DeleteColumn( unsigned int columnIndex );
93
94   /**
95    * @copydoc Toolkit::TableView::DeleteColumn( unsigned int columnIndex, std::vector<Actor>& removed )
96    */
97   void DeleteColumn( unsigned int columnIndex, std::vector<Actor>& removed );
98
99   /**
100    * @copydoc Toolkit::TableView::Resize( unsigned int rows, unsigned int columns )
101    */
102   void Resize( unsigned int rows, unsigned int columns );
103
104   /**
105    * @copydoc Toolkit::TableView::Resize( unsigned int rows, unsigned int columns, std::vector<Actor>& removed )
106    */
107   void Resize( unsigned int rows, unsigned int columns, std::vector<Actor>& removed );
108
109   /**
110    * @copydoc Toolkit::TableView::SetCellPadding
111    */
112   void SetCellPadding( Size padding );
113
114   /**
115    * @copydoc Toolkit::TableView::GetCellPadding
116    */
117   Size GetCellPadding();
118
119   /**
120    * @copydoc Toolkit::TableView::SetFitHeight
121    */
122   void SetFitHeight( unsigned int rowIndex );
123
124   /**
125    * @copydoc Toolkit::TableView::IsFitHeight
126    */
127   bool IsFitHeight( unsigned int rowIndex ) const;
128
129   /**
130    * @copydoc Toolkit::TableView::SetFitWidth
131    */
132   void SetFitWidth( unsigned int columnIndex );
133
134   /**
135    * @copydoc Toolkit::TableView::IsFitWidth
136    */
137   bool IsFitWidth( unsigned int columnIndex ) const;
138
139   /**
140    * @copydoc Toolkit::TableView::SetFixedWidth
141    */
142   void SetFixedWidth( unsigned int columnIndex, float width );
143
144   /**
145    * @copydoc Toolkit::TableView::GetFixedWidth
146    */
147   float GetFixedWidth( unsigned int columnIndex ) const;
148
149   /**
150    * @copydoc Toolkit::TableView::SetFixedHeight
151    */
152   void SetFixedHeight( unsigned int rowIndex, float height );
153
154   /**
155    * @copydoc Toolkit::TableView::GetFixedHeight
156    */
157   float GetFixedHeight( unsigned int rowIndex ) const;
158
159   /**
160    * @copydoc Toolkit::TableView::SetRelativeHeight
161    */
162   void SetRelativeHeight( unsigned int rowIndex, float heightPercentage );
163
164   /**
165    * @copydoc Toolkit::TableView::GetRelativeHeight
166    */
167   float GetRelativeHeight( unsigned int rowIndex ) const;
168
169   /**
170    * @copydoc Toolkit::TableView::SetRelativeWidth
171    */
172   void SetRelativeWidth( unsigned int columnIndex, float widthPercentage );
173
174   /**
175    * @copydoc Toolkit::TableView::GetRelativeWidth
176    */
177   float GetRelativeWidth( unsigned int columnIndex ) const;
178
179   /**
180    * @copydoc Toolkit::TableView::GetRows
181    */
182   unsigned int GetRows();
183
184   /**
185    * @copydoc Toolkit::TableView::GetColumns
186    */
187   unsigned int GetColumns();
188
189   /**
190    * @copydoc Toolkit::TableView::SetCellAlignment
191    */
192   void SetCellAlignment( Toolkit::TableView::CellPosition position, HorizontalAlignment::Type horizontal, VerticalAlignment::Type vertical );
193
194   // Properties
195
196   /**
197    * Called when a property of an object of this type is set.
198    * @param[in] object The object whose property is set.
199    * @param[in] index The property index.
200    * @param[in] value The new property value.
201    */
202   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
203
204   /**
205    * Called to retrieve a property of an object of this type.
206    * @param[in] object The object whose property is to be retrieved.
207    * @param[in] index The property index.
208    * @return The current value of the property.
209    */
210   static Property::Value GetProperty( BaseObject* object, Property::Index index );
211
212 private: // From Control
213
214   /**
215    * @copydoc Control::OnChildAdd(Actor& child)
216    */
217   virtual void OnChildAdd( Actor& child );
218
219   /**
220    * @copydoc Control::OnChildRemove(Actor& child)
221    */
222   virtual void OnChildRemove( Actor& child );
223
224   /**
225    * @copydoc Control::OnRelayout
226    */
227   virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
228
229   /**
230    * @copydoc Control::CalculateChildSize
231    */
232   virtual float CalculateChildSize( const Actor& child, Dimension::Type dimension );
233
234   /**
235    * @copydoc Control::OnInitialize()
236    */
237   virtual void OnInitialize();
238
239   /**
240    * @copydoc Control::GetNextKeyboardFocusableActor
241    */
242   virtual Actor GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled );
243
244   /**
245    * @copydoc Control::GetNaturalSize()
246    */
247   virtual Vector3 GetNaturalSize();
248
249   /**
250    * @copydoc Control::RelayoutDependentOnChildren()
251    */
252   virtual bool RelayoutDependentOnChildren( Dimension::Type dimension = Dimension::ALL_DIMENSIONS );
253
254   /**
255    * @copydoc Control::OnCalculateRelayoutSize
256    */
257   virtual void OnCalculateRelayoutSize( Dimension::Type dimension );
258
259   /**
260    * @copydoc Control::OnLayoutNegotiated
261    */
262   virtual void OnLayoutNegotiated( float size, Dimension::Type dimension );
263
264   /**
265    * @copydoc CustomActorImpl::OnSizeSet( const Vector3& size )
266    */
267   virtual void OnSizeSet( const Vector3& size );
268
269 private: // Implementation
270
271   /**
272    * Struct to hold data for rows and columns
273    *
274    * If sizePolicy is FIXED then size is the absolute size to use.
275    * If sizePolicy is FIT, RELATIVE or FILL then size is the calculated value of size.
276    */
277   struct RowColumnData
278   {
279     /**
280      * Default constructor
281      */
282     RowColumnData()
283     : size( 0.0f ),
284       fillRatio( 0.0f ),
285       position( 0.0f ),
286       sizePolicy( Toolkit::TableView::FILL )
287     {
288     }
289
290     /**
291      * Constructor
292      *
293      * @param[in] newSize The size to set for this data
294      * @param[in] newSizePolicy The policy used to interpret the size value
295      */
296     RowColumnData( float newSize, float newFillRatio, Toolkit::TableView::LayoutPolicy newSizePolicy )
297     : size( newSize ),
298       fillRatio( newFillRatio ),
299       position( 0.0f ),
300       sizePolicy( newSizePolicy )
301     {
302     }
303
304     float size;                                  ///< Set or calculated size
305     float fillRatio;                             ///< Ratio to fill remaining space, only valid with RELATIVE or FILL policy
306     float position;                              ///< Position of the row/column, this value is updated during every Relayout round
307     Toolkit::TableView::LayoutPolicy sizePolicy; ///< The size policy used to interpret the size value
308   };
309
310   typedef Dali::Vector<RowColumnData> RowColumnArray;
311
312 public:
313
314   /**
315    * Structure for the layout data
316    */
317   struct CellData
318   {
319     CellData()
320     : horizontalAlignment( HorizontalAlignment::LEFT ),
321       verticalAlignment( VerticalAlignment::TOP )
322     {
323     }
324
325     // data members
326     Dali::Actor actor;
327     Toolkit::TableView::CellPosition position;
328     HorizontalAlignment::Type horizontalAlignment;
329     VerticalAlignment::Type verticalAlignment;
330   };
331
332 private:
333
334   /**
335    * Construct a new TableView.
336    */
337   TableView( unsigned int initialRows, unsigned int initialColumns );
338
339   /**
340    * Resizes the data containers to match the new size
341    * @param [in] rows in the table
342    * @param [in] columns in the table
343    */
344   void ResizeContainers( unsigned int rows, unsigned int columns );
345
346   /**
347    * Resizes the data containers to match the new size
348    * @param [in] rows in the table
349    * @param [in] columns in the table
350    * @param [out] removed celldata
351    */
352   void ResizeContainers( unsigned int rows, unsigned int columns, std::vector<CellData>& removed );
353
354   /**
355    * Helper to get the list of lost actors in the case when table looses cells.
356    * Also handles the case when actors span multiple cells
357    * @param lost cells
358    * @param removed actors
359    * @param rowsRemoved from table
360    * @param columnsRemoved from table
361    */
362   void RemoveAndGetLostActors( const std::vector<CellData>& lost, std::vector<Actor>& removed,
363       unsigned int rowsRemoved, unsigned int columnsRemoved );
364
365   /**
366    * Helper to remove all instances of the actor
367    * @param child actor to remove
368    * @return true if the actor was found
369    */
370   bool RemoveAllInstances( const Actor& child );
371
372   /**
373    * @brief Calculate the ratio of FILL rows/columns
374    *
375    * @param[in] data The RowColumn data to compute the relative sizes for
376    */
377   void CalculateFillSizes( RowColumnArray& data );
378
379   /**
380    * @brief Calculate the total fixed sizes for a row or column
381    *
382    * @param[in] data The row or column data to process
383    */
384   float CalculateTotalFixedSize( const RowColumnArray& data );
385
386   /**
387    * @brief Calculate the sizes of FIT rows/columns
388    *
389    * @param[in] data The row or column data to process
390    * @param[in] dimension The dimension being calculated: row == Dimension::HEIGHT, column == Dimension::WIDTH
391    */
392   void CalculateFitSizes( RowColumnArray& data, Dimension::Type dimension );
393
394   /**
395    * @brief Search for a FIT cell in the array
396    *
397    * @param[in] data The row or column data to process
398    * @return Return if a FIT cell was found or not
399    */
400   bool FindFit( const RowColumnArray& data );
401
402   /**
403    * @brief Return the cell padding for a given dimension
404    *
405    * @param[in] dimension The dimension to return the padding for
406    * @return Return the padding (x = low, y = high)
407    */
408   Vector2 GetCellPadding( Dimension::Type dimension );
409
410   /**
411    * A reference counted object may only be deleted by calling Unreference()
412    */
413   virtual ~TableView();
414
415 private: // scripting support
416
417   /**
418    * Called to set the heights/widths property.
419    * @param[in] tableViewImpl The object whose property is set.
420    * @param[in] funcFixed The set function to call, it can be SetFixedHeight or SetFixedWidth.
421    * @param[in] funcRelative The set function to call, it can be SetRelativeHeight or SetRelativeWidth.
422    * @param[in] funcFit The set function to call, it can be SetFitHeight or SetFiltWidth.
423    * @param[in] value The new property value.
424    */
425   static void SetHeightOrWidthProperty( TableView& tableViewImpl,
426                                         void(TableView::*funcFixed)(unsigned int, float),
427                                         void(TableView::*funcRelative)(unsigned int, float),
428                                         void(TableView::*funcFit)(unsigned int),
429                                         const Property::Value& map );
430
431   /**
432    * Called to retrieve the property value of row heights.
433    * @return The property value of row heights.
434    */
435   Property::Value GetRowHeightsPropertyValue();
436
437   /**
438    * Called to retrieve the property value of column widths.
439    * @return The fixed-widths property value.
440    */
441   Property::Value GetColumnWidthsPropertyValue();
442
443   /**
444    * Generate the map type property value from the size vectors.
445    * @param[in] data The array of row or column data
446    * @param[out] map The property value.
447    */
448   void GetMapPropertyValue( const RowColumnArray& data, Property::Map& map );
449
450
451   /**
452    * Helper class to prevent child adds and removes from causing relayout
453    * when we're already anyways going to do one in the end
454    */
455   class RelayoutingLock
456   {
457   public: // API
458
459     /**
460      * Constructor, sets the lock boolean
461      */
462     RelayoutingLock( TableView& parent )
463     : mLock( parent.mLayoutingChild )
464     {
465       mLock = true;
466     }
467
468     /**
469      * Destructor, releases lock boolean
470      */
471     ~RelayoutingLock()
472     {
473       mLock = false;
474       // Note, we could also call Relayout here. This would save one line of code
475       // from each method that uses this lock but destructors are not meant to do
476       // big processing so better to not do it here. This destructor would also
477       // be called in case of an exception and we don't definitely want to do Relayout
478       // in that situation
479     }
480
481   private:
482     bool& mLock;
483   };
484
485 private:
486
487   // Undefined copy constructor and assignment operators
488   TableView(const TableView&);
489   TableView& operator=(const TableView& rhs);
490
491 private: // Data
492
493   Array2d<CellData> mCellData;   ///< Data for each cell: Actor, alignment settings etc
494
495   RowColumnArray mRowData;       ///< Data for each row
496   RowColumnArray mColumnData;    ///< Data for each column
497   Size mFixedTotals;             ///< Accumulated totals for fixed width and height
498
499   Size mPadding;                 ///< Padding to apply to each cell
500   unsigned int mCurrentRow;      ///< Last / current focused row
501   unsigned int mCurrentColumn;   ///< Last / current focused column
502   bool mLayoutingChild;          ///< Can't be a bitfield due to Relayouting lock
503   bool mRowDirty : 1;            ///< Flag to indicate the row data is dirty
504   bool mColumnDirty : 1;         ///< Flag to indicate the column data is dirty
505 };
506
507 } // namespace Internal
508
509 // Helpers for public-api forwarding methods
510
511 inline Toolkit::Internal::TableView& GetImpl( Toolkit::TableView& tableView )
512 {
513   DALI_ASSERT_ALWAYS(tableView);
514
515   Dali::RefObject& handle = tableView.GetImplementation();
516
517   return static_cast<Toolkit::Internal::TableView&>(handle);
518 }
519
520 inline const Toolkit::Internal::TableView& GetImpl( const Toolkit::TableView& tableView )
521 {
522   DALI_ASSERT_ALWAYS(tableView);
523
524   const Dali::RefObject& handle = tableView.GetImplementation();
525
526   return static_cast<const Toolkit::Internal::TableView&>(handle);
527 }
528
529 } // namespace Toolkit
530
531 } // namespace Dali
532
533 #endif // __DALI_TOOLKIT_INTERNAL_TABLE_VIEW_H__