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