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