[dali_2.3.20] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / controls / scrollable / item-view / item-layout.h
1 #ifndef DALI_TOOLKIT_ITEM_LAYOUT_H
2 #define DALI_TOOLKIT_ITEM_LAYOUT_H
3
4 /*
5  * Copyright (c) 2020 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/animation/alpha-function.h>
23 #include <dali/public-api/object/property-key.h>
24 #include <dali/public-api/object/property-map.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/public-api/controls/control.h>
28 #include <dali-toolkit/public-api/enums.h>
29
30 #undef min
31 #undef max
32
33 namespace Dali
34 {
35 namespace Toolkit
36 {
37 /**
38  * @addtogroup dali_toolkit_controls_item_view
39  * @{
40  */
41
42 class ItemLayout;
43
44 typedef IntrusivePtr<ItemLayout> ItemLayoutPtr; ///< Pointer to a Dali::Toolkit::ItemLayout object @SINCE_1_0.0
45
46 /**
47  * @brief A support class for managing ranges of items.
48  * @SINCE_1_0.0
49  */
50 struct ItemRange
51 {
52   /**
53    * @brief Creates a range of item identifiers.
54    *
55    * @SINCE_1_0.0
56    * @param[in] beginItem The first item within the range
57    * @param[in] endItem The past-the-end item
58    */
59   ItemRange(unsigned int beginItem, unsigned int endItem)
60   : begin(beginItem),
61     end(endItem)
62   {
63   }
64
65   /**
66    * @brief Copy Constructor.
67    *
68    * @SINCE_1_0.0
69    * @param[in] copy ItemRange we should copy from
70    */
71   ItemRange(const ItemRange& copy)
72   : begin(copy.begin),
73     end(copy.end)
74   {
75   }
76
77   /**
78    * @brief Assignment operator.
79    *
80    * @SINCE_1_0.0
81    * @param[in] range The Range to assign from
82    * @return The updated range
83    */
84   ItemRange& operator=(const ItemRange& range)
85   {
86     if(this != &range)
87     {
88       begin = range.begin;
89       end   = range.end;
90     }
91     return *this;
92   }
93
94   /**
95    * @brief Tests whether an item is within the range.
96    *
97    * @SINCE_1_0.0
98    * @param[in] itemId The item identifier
99    * @return true if the item is within the range
100    */
101   bool Within(unsigned int itemId)
102   {
103     return itemId >= begin &&
104            itemId < end;
105   }
106
107   /**
108    * @brief Creates the intersection of two ranges.
109    *
110    * @SINCE_1_0.0
111    * @param[in] second The second range
112    * @return The intersection
113    */
114   ItemRange Intersection(const ItemRange& second)
115   {
116     ItemRange intersection(0u, 0u);
117
118     // If the ranges intersect
119     if((begin < second.end && end > second.begin) ||
120        (second.begin < end && second.end > begin))
121     {
122       intersection.begin = std::max(begin, second.begin);
123       intersection.end   = std::min(end, second.end);
124     }
125
126     return intersection;
127   }
128
129   unsigned int begin; ///< The start of the range
130   unsigned int end;   ///< The end of the range
131 };
132
133 /**
134  * @brief An ItemLayout describes the constraints which are imposed on items in the layout.
135  *
136  *   - Potentially visible items are represented by Actors, created for ItemView by the ItemFactory.
137  *   - Constraints are applied after ItemView activates a layout.
138  *
139  * An ItemLayout also describes the direction of input gestures, used to scroll through the layout.
140  * Whilst scrolling, the layout provides a range of items that are within a layout-area (3D bounding volume).
141  * @SINCE_1_0.0
142  */
143 class DALI_TOOLKIT_API ItemLayout : public RefObject
144 {
145 public:
146   class Extension; ///< Forward declare future extension interface
147
148   /**
149    * @brief Virtual destructor.
150    * @SINCE_1_0.0
151    */
152   virtual ~ItemLayout();
153
154   /**
155    * @brief Set the orientation of the layout.
156    *
157    * @SINCE_1_0.0
158    * @param[in] orientation The orientation of the layout.
159    */
160   void SetOrientation(ControlOrientation::Type orientation);
161
162   /**
163    * @brief Query the orientation of the layout.
164    *
165    * @SINCE_1_0.0
166    * @return the orientation of the layout.
167    */
168   ControlOrientation::Type GetOrientation() const;
169
170   /**
171    * @brief Apply the layout Properties.
172    * @SINCE_1_2.20
173    * @param[in] properties The properties the layout.
174    */
175   void SetLayoutProperties(const Property::Map& properties);
176
177   /**
178    * @brief Get the layout Properties.
179    * @SINCE_1_2.20
180    * @return the property of the layout.
181    */
182   Property::Map GetLayoutProperties();
183
184   /**
185    * @brief Retrieve the target size of an item in the layout.
186    *
187    * This will return the default size for the layout unless overridden by calling SetItemSize().
188    *
189    * @SINCE_1_0.0
190    * @param[in] itemId The ID of an item in the layout.
191    * @param[in] layoutSize The layout size
192    * @param[out] itemSize The target size of an item.
193    * @note layout-position is not provided as a parameter, since applying size constraints is not recommended.
194    * Animating to target-sizes is preferable, since this allows controls to perform layouting without constraints.
195    */
196   void GetItemSize(unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize) const;
197
198   /**
199    * @brief Overrides the default size for the layout.
200    *
201    * @SINCE_1_0.0
202    * @param[in] itemSize The size of each item.
203    */
204   void SetItemSize(const Vector3& itemSize);
205
206   /**
207    * @brief Query the minimum valid layout position; this is a negative value.
208    *
209    * When scrolling, the first item will move within the range 0 to GetMinimumLayoutPosition().
210    * @SINCE_1_0.0
211    * @param[in] numberOfItems The current number of items in the layout.
212    * @param[in] layoutSize The size of the layout area.
213    * @return The minimum layout position.
214    */
215   virtual float GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const = 0;
216
217   /**
218    * @brief Query the closest anchor position for the given layout position.
219    *
220    * This anchor position is the position where all the items in the layout are aligned to
221    * their rounded layout positions in integer.
222    * @SINCE_1_0.0
223    * @param[in] layoutPosition The layout position.
224    * @return The closest anchor position for the given layout position.
225    */
226   virtual float GetClosestAnchorPosition(float layoutPosition) const = 0;
227
228   /**
229    * @brief Query the layout position for the first item in the layout to move to when the layout
230    * needs to scroll to a particular item.
231    *
232    * @SINCE_1_0.0
233    * @param[in] itemId The ID of an item in the layout.
234    * @return The layout position for the first item in the layout to move to.
235    */
236   virtual float GetItemScrollToPosition(unsigned int itemId) const = 0;
237
238   /**
239    * @brief Query the items within a given layout-area.
240    *
241    * @SINCE_1_0.0
242    * @param[in] firstItemPosition The layout-position of the first item in the layout.
243    * @param[in] layoutSize The size of the layout area.
244    * @return The ID of the first & last visible item.
245    */
246   virtual ItemRange GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const = 0;
247
248   /**
249    * @brief Get the closest layout position to bring an item onto the screen.
250    *
251    * If the item is already fully on the screen this function will
252    * return the current layout position.
253    *
254    * This function is used by systems such as KeyboardFocusManager to
255    * bring the next focusable item into view and all layout
256    * implementations should provide their own version of this function
257    * to ensure proper functionality of internal toolkit systems.
258    *
259    * @SINCE_1_0.0
260    * @param[in] itemID id of the item to bring within the viewable screen area
261    * @param[in] currentLayoutPosition the current layout position of the item view instance
262    * @param[in] layoutSize the current size of the item view instance
263    * @return The layout position
264    */
265   virtual float GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize);
266
267   /**
268    * @brief Query the number of items that should be reserved, for scrolling purposes.
269    *
270    * @SINCE_1_0.0
271    * @param[in] layoutSize The size of the layout area.
272    * @return The number of extra items. ItemView will populate itself with actors within the layout-area
273    * (see GetItemsWithinArea), plus this number of additional items on either-side.
274    */
275   virtual unsigned int GetReserveItemCount(Vector3 layoutSize) const = 0;
276
277   /**
278    * @brief Retrieve the default size of an item in the layout.
279    *
280    * @SINCE_1_0.0
281    * @param[in] itemId The ID of an item in the layout.
282    * @param[in] layoutSize The layout size
283    * @param[out] itemSize The target size of an item.
284    * @note layout-position is not provided as a parameter, since applying size constraints is not recommended.
285    * Animating to target-sizes is preferable, since this allows controls to perform layouting without constraints.
286    */
287   virtual void GetDefaultItemSize(unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize) const = 0;
288
289   /**
290    * @brief Query the scroll direction of the layout.
291    *
292    * When an input gesture follows this direction, the layout-position of items will be increased.
293    * If the input gesture points in the opposite direction, then the layout-positions will decrease.
294    * @SINCE_1_0.0
295    * @return The scroll direction in degrees.
296    */
297   virtual Degree GetScrollDirection() const = 0;
298
299   /**
300    * @brief Query the scroll speed factor of the layout while dragging.
301    *
302    * This factor is used by the layout to customise its scroll speed while dragging.
303    * The factor will be multiplied with the scroll distance of how many pixels in actor coordinate,
304    * and the layout position of the actors in ItemView will be moved by this result.
305    * For example, when the speed factor is 0.01, if the scroll distance is 100 pixels, the layout
306    * position of actors will be moved by 1.
307    * Therefore, the bigger the factor is, the faster the scroll speed will be.
308    *
309    * @SINCE_1_0.0
310    * @return The scroll speed factor of the layout.
311    */
312   virtual float GetScrollSpeedFactor() const = 0;
313
314   /**
315    * @brief Query the maximum swipe speed in pixels per second.
316    *
317    * Swipe gestures will be clamped when exceeding this speed limit.
318    * @SINCE_1_0.0
319    * @return speed The maximum swipe speed.
320    */
321   virtual float GetMaximumSwipeSpeed() const = 0;
322
323   /**
324    * @brief Get the duration of the flick animation in second.
325    *
326    * This is the time taken to animate each
327    * item to its next layout position (e.g. from 1.0 to 2.0) when a flick animation is triggered
328    * by a swipe gesture.
329    * @SINCE_1_0.0
330    * @return The duration of the flick animation.
331    */
332   virtual float GetItemFlickAnimationDuration() const = 0;
333
334   /**
335    * @brief Gets the id of the next item for KeyboardFocusManager to focus on depending on the inputted item ID.
336    *
337    * @SINCE_1_0.0
338    * @param[in] itemID The current focused item
339    * @param[in] maxItems The maximum number of items in the list
340    * @param[in] direction The directional key pressed on the keyboard
341    * @param[in] loopEnabled Whether the KeyboardFocusManager is set to wrap around between first and last item
342    * @return The next item ID.
343    */
344   virtual int GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
345
346   /**
347    * @brief Query the flick speed factor of the layout while swipping.
348    *
349    * This factor is used by the layout to customise its scroll speed while swiping.
350    * The factor will be multiplied with the scroll distance of how many pixels in actor coordinate,
351    * and the layout position of the actors in ItemView will be moved by this result.
352    * For example, when the speed factor is 0.01, if the scroll distance is 100 pixels, the layout
353    * position of actors will be moved by 1.
354    * Therefore, the bigger the factor is, the faster the flick speed will be.
355    *
356    * @SINCE_1_0.0
357    * @return The scroll speed factor of the layout.
358    */
359   virtual float GetFlickSpeedFactor() const;
360
361   /**
362    * @brief Applies constraints defined by the layout to an actor.
363    *
364    * @param[in] actor The actor to constrain.
365    * @param[in] itemId The ID of the item represented by the actor.
366    * @param[in] layoutSize The current size of the item view instance.
367    * @param[in] itemViewActor The item view instance which requests the application of constraints.
368    */
369   virtual void ApplyConstraints(Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor) = 0;
370
371   /**
372    * @brief Gets the position of a given item
373    *
374    * @SINCE_1_0.0
375    * @param[in] itemID The id of the item we want to get its position
376    * @param[in] currentLayoutPosition The current layout position of the item view instance
377    * @param[in] layoutSize The current size of the item view instance
378    * @return The item position (x,y,z)
379    */
380   virtual Vector3 GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const = 0;
381
382   /**
383    * @brief Retrieve the extension for this layout.
384    *
385    * @SINCE_1_0.0
386    * @return The extension if available, NULL otherwise
387    */
388   virtual Extension* GetExtension()
389   {
390     return NULL;
391   }
392
393 protected:
394   /**
395    * @brief Create a new ItemLayout; Only derived versions are instantiatable.
396    * @SINCE_1_0.0
397    */
398   ItemLayout();
399
400 private:
401   /**
402    * @brief Don't allow copy constructor
403    * @SINCE_1_0.0
404    */
405   ItemLayout(const ItemLayout& handle);
406
407   /**
408    * @brief Don't allow copy operator
409    * @SINCE_1_0.0
410    */
411   ItemLayout& operator=(const ItemLayout& handle);
412
413 protected:
414   struct Impl;
415   Impl* mImpl;
416 };
417
418 /**
419  * @}
420  */
421 } // namespace Toolkit
422
423 } // namespace Dali
424
425 #endif // DALI_TOOLKIT_ITEM_LAYOUT_H