[dali_2.3.20] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / page-turn-view / page-turn-view-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H
2 #define DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H
3
4 /*
5  * Copyright (c) 2021 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/devel-api/common/map-wrapper.h>
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/public-api/rendering/renderer.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/devel-api/controls/page-turn-view/page-factory.h>
28 #include <dali-toolkit/devel-api/controls/page-turn-view/page-turn-view.h>
29 #include <dali-toolkit/devel-api/controls/shadow-view/shadow-view.h>
30 #include <dali-toolkit/public-api/controls/control-impl.h>
31
32 namespace Dali
33 {
34 namespace Toolkit
35 {
36 namespace Internal
37 {
38 class PageTurnView : public Control
39 {
40 protected:
41   /**
42    * The book page class
43    */
44   struct Page
45   {
46     /**
47      * Constructor
48      */
49     Page();
50     /**
51      * Destructor
52      */
53     ~Page(){};
54
55     /**
56      * Set the page texture content
57      * @param[in] texture The content of the page.
58      */
59     void SetTexture(Texture texture);
60
61     /**
62      * Apply an effect onto the page actor.
63      * @param[in] newShader The shader for rendering effect.
64      */
65     void UseEffect(Shader newShader);
66
67     /**
68      * Apply an effect onto the page actor.
69      * @param[in] newShader The shader for rendering effect.
70      * @param[in] geometry The geometry for rendering effect.
71      */
72     void UseEffect(Shader newShader, Geometry geometry);
73
74     /**
75      * Change the page turning direction.
76      */
77     void ChangeTurnDirection();
78
79     /**
80      * Set the pan displacement property
81      * @param[in] value The property value
82      */
83     void SetPanDisplacement(float value);
84
85     /**
86      * Set the pan center property
87      * @param[in] value The property value
88      */
89     void SetPanCenter(const Vector2& value);
90
91     /**
92      * Set the original center property to be used by shader
93      * @param[in] value The property value
94      */
95     void SetOriginalCenter(const Vector2& value);
96
97     /**
98      * Set the current center property to be used by shader
99      * @param[in] value The property value
100      */
101     void SetCurrentCenter(const Vector2& value);
102
103     Actor           actor;                   ///< The page actor
104     Shader          shader;                  ///< The shader used by the actor
105     TextureSet      textureSet;              ///< The set of textures used by the actor
106     Renderer        renderer;                ///< The renderer of the actor
107     bool            isTurnBack;              ///< The turning direction
108     Property::Index propertyPanDisplacement; ///< The horizontal displacement of the pan
109     Property::Index propertyPanCenter;       ///< The current pan position
110     Property::Index propertyOriginalCenter;  ///< The original center to be used by the shader
111     Property::Index propertyCurrentCenter;   ///< The current center to be used by the shader
112     Property::Index propertyTurnDirection;   ///< The turning direction property
113   };
114
115 protected:
116   /**
117    * Constructor.
118    * It initializes the PageTurnView members
119    */
120   PageTurnView(PageFactory& pageFactory, const Vector2& viewPageSize);
121
122   /**
123    * A reference counted object may only be deleted by calling Unreference()
124    */
125   virtual ~PageTurnView();
126
127 public:
128   /**
129    * Set the page size
130    * @param[in] viewPageSize The size of pages
131    */
132   void SetPageSize(const Vector2& viewPageSize);
133
134   /**
135    * Retrieve the page size.
136    * @return The page size.
137    */
138   Vector2 GetPageSize();
139
140   /**
141    * Set the spine shadow parameter to the shader effects.
142    * The two parameters are the major&minor radius (in pixels) to form an ellipse shape.
143    * The top-left quarter of this ellipse is used to calculate spine normal for simulating shadow.
144    * @param [in] spineShadowParameter The major&minor ellipse radius for the simulated spine shadow.
145    */
146   void SetSpineShadowParameter(const Vector2& spineShadowParameter);
147
148   /**
149    * Retrieve the spine shadow parameter of the shader effects.
150    * @return The spine shadow parameter.
151    */
152   Vector2 GetSpineShadowParameter();
153
154   /*
155    * Jump to a given page.
156    * @param[in] pageId The new current page id.
157    */
158   void GoToPage(unsigned int pageId);
159
160   /**
161    * Retrieve the id of the current Page.
162    * @return The current page id.
163    */
164   unsigned int GetCurrentPage();
165
166 protected:
167   /**
168    * This method gets a page from the factory and add to the control
169    * to keep NUMBER_OF_CACHED_PAGES_EACH_SIDE pages available in each side
170    * @param[in] pageIndex The index of the page to be added
171    */
172   void AddPage(int pageIndex);
173
174   /**
175    * This method removes a page from the control
176    * to keep only NUMBER_OF_CACHED_PAGES_EACH_SIDE pages available in each side
177    * @param[in] pageIndex The index of the page to be removed
178    */
179   void RemovePage(int pageIndex);
180
181   /**
182    * This method updates the actor and animation states after one page is turned over
183    * This method is a callback, connected when receiving the finished signal of a page turning over animation.
184    * @param [in] the page turning over animation handle
185    */
186   void TurnedOver(Animation& animation);
187
188   /**
189    * This method organize the depth of the pages on stage
190    * It is called when there is page added or removed from the control
191    */
192   void OrganizePageDepth();
193
194 private:
195   /**
196    * Create shader from a property map.
197    * @param[in] shaderMap The shader property map;
198    * @return The created shader.
199    */
200   Shader CreateShader(const Property::Map& shaderMap);
201
202   /**
203   * Set up the shadow view control to cast shadow
204   */
205   void SetupShadowView();
206
207   /**
208    * This method defines the processes when the pan started, gets called by OnPan( .. )
209    * @param[in] gesturePosition The current touch position in local page actor coordinates.
210    */
211   void PanStarted(const Vector2& gesturePosition);
212
213   /**
214    * This method defines the processes when the pan continuing, gets called by OnPan( .. )
215    * @param[in] gesturePosition The current touch position in local page actor coordinates.
216    */
217   void PanContinuing(const Vector2& gesturePosition);
218
219   /**
220    * This method defines the processes when the pan finished, gets called by OnPanGesture( .. )
221    * @param[in] gesturePosition The current touch position in local page actor coordinates.
222    * @param[in] gestureSpeed The speed of the pan ( in pixels per millisecond )
223    */
224   void PanFinished(const Vector2& gesturePosition, float gestureSpeed);
225
226   /**
227    * This method updates the actor and the animation states after one page is slidden back instead of turned over
228    * This method is a callback, connected when receiving the finished signal of a page sliding back animation.
229    * @param [in] the page sliding back animation handle
230    */
231   void SliddenBack(Animation& animation);
232
233   /**
234    * Stop the page turning animation and contraint.
235    * This method should be called when taking off stage or jump to a specified page.
236    */
237   void StopTurning();
238
239 private: // from Control
240   /**
241    * @copydoc Toolkit::Control::OnPan
242    */
243   void OnPan(const PanGesture& gesture) override;
244
245   /**
246    * @copydoc Toolkit::Control::OnInitialize
247    */
248   void OnInitialize() override;
249
250   /**
251    * @copydoc CustomActorImpl::OnSceneConnection()
252    */
253   void OnSceneConnection(int depth) override;
254
255   /**
256    * @copydoc CustomActorImpl::OnSceneDisconnection()
257    */
258   void OnSceneDisconnection() override;
259
260 private: // implemented differently by PageTurnLandscapeView and PageTurnPortraitView
261   /**
262    * This method is called after the pageTurnView initialization.
263    * To set the size of the control size and the parent origin of turning page layer
264    * Implemented in subclasses to provide specific behaviour.
265    */
266   virtual void OnPageTurnViewInitialize() = 0;
267
268   /**
269    * This method is called after the a new page is added to the stage.
270    * Could be re-implemented in subclasses to provide specific behaviour
271    * @param[in] newPage The added page actor
272    * @param[in] isLeftSide Which side the new page is added to
273    */
274   virtual void OnAddPage(Actor newPage, bool isLeftSide)
275   {
276   }
277
278   /**
279    * This method is called when pan started or continuing
280    * to calculate the pan position in local page actor coordinate given the pan position in control coordinate
281    * Implemented in subclasses to provide specific behaviour.
282    * @param[in] gesturePosition The pan position in the control coordinate
283    * @return The pan position in the page actor local coordinate
284    */
285   virtual Vector2 SetPanPosition(const Vector2& gesturePosition) = 0;
286
287   /**
288    * This method is called when pan started to determined which page is panned given the pan position in control coordinate
289    * Implemented in subclasses to provide specific behaviour.
290    * @param[in] gesturePosition The pan position in the control coordinate
291    */
292   virtual void SetPanActor(const Vector2& panPosition) = 0;
293
294   /**
295    * This method is called when pan finished to detect outwards flick
296    * In portrait view, start an animation of turning previous page back when outwards flick is detected
297    * In landscape view, nothing to do
298    * @param[in] panPosition The pan position in the page actor local coordinate
299    * @param[in] gestureSpeed The speed of the pan gesture( in pixels per millisecond )
300    */
301   virtual void OnPossibleOutwardsFlick(const Vector2& panPosition, float gestureSpeed)
302   {
303   }
304
305   /**
306    * This method is called when page is turned over
307    * In portrait view, the page on the left side is not rendered
308    * @param[in] actor The page actor
309    * @param[in] isLeftSide Which side the page is turned to
310    */
311   virtual void OnTurnedOver(Actor actor, bool isLeftSide)
312   {
313   }
314
315 public: //signal and property
316   /**
317    * @copydoc Toolkit::PageTurnView::PageTurnStartedSignal()
318    */
319   Toolkit::PageTurnView::PageTurnSignal& PageTurnStartedSignal();
320
321   /**
322    * @copydoc Toolkit::PageTurnView::PageTurnFinishedSignal()
323    */
324   Toolkit::PageTurnView::PageTurnSignal& PageTurnFinishedSignal();
325
326   /**
327    * @copydoc Toolkit::PageTurnView::PagePanStartSignal()
328    */
329   Toolkit::PageTurnView::PagePanSignal& PagePanStartedSignal();
330
331   /**
332    * @copydoc Toolkit::PageTurnView::PagePanFinishedSignal()
333    */
334   Toolkit::PageTurnView::PagePanSignal& PagePanFinishedSignal();
335
336   /**
337     * Connects a callback function with the object's signals.
338     * @param[in] object The object providing the signal.
339     * @param[in] tracker Used to disconnect the signal.
340     * @param[in] signalName The signal to connect to.
341     * @param[in] functor A newly allocated FunctorDelegate.
342     * @return True if the signal was connected.
343     * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
344     */
345   static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
346
347   // Properties
348
349   /**
350    * Called when a property of an object of this type is set.
351    * @param[in] object The object whose property is set.
352    * @param[in] index The property index.
353    * @param[in] value The new property value.
354    */
355   static void SetProperty(BaseObject* object, Property::Index index, const Property::Value& value);
356
357   /**
358    * Called to retrieve a property of an object of this type.
359    * @param[in] object The object whose property is to be retrieved.
360    * @param[in] index The property index.
361    * @return The current value of the property.
362    */
363   static Property::Value GetProperty(BaseObject* object, Property::Index index);
364
365 private:
366   //Undefined
367   PageTurnView(const PageTurnView&);
368
369   //undefined
370   PageTurnView& operator=(const PageTurnView& rhs);
371
372 protected:
373   Layer               mTurningPageLayer;      ///< The layer for the turning page, to avoid possible depth conflict
374   Toolkit::ShadowView mShadowView;            ///< The shadow view control for shadow casting
375   Actor               mShadowPlaneBackground; ///< The plane for the shadow to cast on
376   Actor               mPointLight;            ///< The point light used for shadow casting
377
378   PageFactory* const mPageFactory;       ///< The factory which provides the page actors
379   Shader             mTurnEffectShader;  ///< The group of PageTurnEffects
380   Shader             mSpineEffectShader; ///< The book spine shader effect
381   Geometry           mGeometry;          ///< The grid geometry for pages
382
383   std::vector<Page>        mPages;               ///< The vector of pages on stage
384   std::map<Animation, int> mAnimationPageIdPair; ///< The map to keep track which page actor is the animation act on
385
386   Vector2 mPageSize;             ///< The page size
387   Vector2 mControlSize;          ///< The size of the control, it is decided by the page size, the SetSize from application can not change it
388   Vector2 mSpineShadowParameter; ///< The spine shadow parameter for all the above shader effects
389   Vector2 mOriginalCenter;       ///< The original center set to the PageTurnEffect
390   Vector2 mCurrentCenter;        ///< The current center set to the PageTurnEffect
391   Vector2 mPressDownPosition;    ///< The first press down position of the pan gesture
392
393   float mDistanceUpCorner;     ///< The distance between the original center of PageTurnEffect and the top-left corner of the page
394   float mDistanceBottomCorner; ///< The distance between the original center of PageTurnEffect and the bottom-left corner of the page
395   float mPanDisplacement;      ///< The displacement of the pan after the constrains are applied
396
397   int mTotalPageCount;   ///< The total number of pages provided by the page factory
398   int mCurrentPageIndex; ///< The index of the current page, between 0 ~ mTotalPageCount-1
399   int mTurningPageIndex; ///< The index of the turning page
400   int mIndex;            ///< The index to keep track which PanDisplacementProperty, CurrentCenterProperty is used for the current panning page
401   int mSlidingCount;     ///< The boolean vector to keep track whether there are animating pages sliding back
402   int mAnimatingCount;   ///< The boolean vector to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is available for using
403
404   bool mConstraints; ///< The boolean to keep track the constrains are applied or not
405   bool mPress;       ///< The boolean to keep track the state of the pageTurnEffect is activated or not
406   bool mPageUpdated; ///< The boolean to keep track whether is page is updated after any turning activity
407
408   Toolkit::PageTurnView::PageTurnSignal mPageTurnStartedSignal;  ///< The signal to notify that a page has started turning
409   Toolkit::PageTurnView::PageTurnSignal mPageTurnFinishedSignal; ///< The signal to notify that a page has finished turning
410   Toolkit::PageTurnView::PagePanSignal  mPagePanStartedSignal;   ///< The signal to notify that a page has started panning
411   Toolkit::PageTurnView::PagePanSignal  mPagePanFinishedSignal;  ///< The signal to notify that a page has finished panning
412
413   static const char* const PROPERTY_TEXTURE_WIDTH;   ///< The uniform name of texture width
414   static const char* const PROPERTY_ORIGINAL_CENTER; ///< The property name of original center, which is used to constrain the uniforms
415   static const char* const PROPERTY_CURRENT_CENTER;  ///< The property name of current center, which is used to constrain the uniforms
416
417   static const int   MAXIMUM_TURNING_NUM;              ///< How many pages are allowed to animating in the same time
418   static const int   NUMBER_OF_CACHED_PAGES_EACH_SIDE; ///< The maximum number of pages kept, (MAXIMUM_ANIMATION_NUM+1) pages for each side
419   static const int   NUMBER_OF_CACHED_PAGES;           ///< The maximum number of pages kept, (MAXIMUM_ANIMATION_NUM+1)*2 pages in total
420   static const float STATIC_PAGE_INTERVAL_DISTANCE;    ///< The depth interval between stacked pages (static pages)
421 };
422
423 } // namespace Internal
424
425 // Helpers for public-api forwarding methods
426
427 inline Toolkit::Internal::PageTurnView& GetImplementation(Toolkit::PageTurnView& pub)
428 {
429   DALI_ASSERT_ALWAYS(pub);
430
431   Dali::RefObject& handle = pub.GetImplementation();
432
433   return static_cast<Toolkit::Internal::PageTurnView&>(handle);
434 }
435
436 inline const Toolkit::Internal::PageTurnView& GetImplementation(const Toolkit::PageTurnView& pub)
437 {
438   DALI_ASSERT_ALWAYS(pub);
439
440   const Dali::RefObject& handle = pub.GetImplementation();
441
442   return static_cast<const Toolkit::Internal::PageTurnView&>(handle);
443 }
444
445 } // namespace Toolkit
446
447 } // namespace Dali
448
449 #endif // DALI_TOOLKIT_INTERNAL_PAGE_TURN_VIEW_IMPL_H