5d9eae3c5460ff25567f9f9f732c036e7099e210
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / popup / popup-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_POPUP_H
2 #define DALI_TOOLKIT_INTERNAL_POPUP_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/animation/animation-data.h>
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/public-api/adaptor-framework/timer.h>
25 #include <dali/public-api/animation/animation.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/devel-api/controls/popup/popup.h>
29 #include <dali-toolkit/devel-api/controls/table-view/table-view.h>
30 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
31 #include <dali-toolkit/public-api/controls/control-impl.h>
32
33 namespace Dali
34 {
35 namespace Toolkit
36 {
37 namespace Internal
38 {
39 class Popup;
40
41 typedef IntrusivePtr<Popup> PopupPtr;
42
43 /**
44  * @copydoc Toolkit::Popup
45  */
46 class Popup : public Control
47 {
48 public:
49   /**
50    * Create a new Popup.
51    * @return A public handle to the newly allocated Popup.
52    */
53   static Dali::Toolkit::Popup New();
54
55 public:
56   /**
57    * @copydoc Toolkit::Popup::SetPopupBackgroundImage
58    */
59   void SetPopupBackgroundImage(Actor image);
60
61   /**
62    * @copydoc Toolkit::Popup::GetPopupBackgroundImage
63    */
64   Actor GetPopupBackgroundImage() const;
65
66   /**
67    * @copydoc Toolkit::Popup::SetTitle( Actor titleActor )
68    */
69   void SetTitle(Actor titleActor);
70
71   /**
72    * @copydoc Toolkit::Popup::GetTitle
73    */
74   Actor GetTitle() const;
75
76   /**
77    * @copydoc Toolkit::Popup::SetContent
78    */
79   void SetContent(Actor content);
80
81   /**
82    * @copydoc Toolkit::Popup::GetContent
83    */
84   Actor GetContent() const;
85
86   /**
87    * @copydoc Toolkit::Popup::SetFooter
88    */
89   void SetFooter(Actor control);
90
91   /**
92    * @copydoc Toolkit::Popup::GetFooter
93    */
94   Actor GetFooter() const;
95
96   /**
97    * @copydoc Toolkit::Popup::SetDisplayState
98    */
99   void SetDisplayState(Toolkit::Popup::DisplayState displayState);
100
101   /**
102    * @copydoc Toolkit::Popup::GetDisplayState
103    */
104   Toolkit::Popup::DisplayState GetDisplayState() const;
105
106   /**
107    * @copydoc Toolkit::Popup::SetTailVisibility
108    */
109   void SetTailVisibility(bool visible);
110
111   /**
112    * @copydoc Toolkit::Popup::IsTailVisible
113    */
114   const bool IsTailVisible() const;
115
116   /**
117    * @copydoc Toolkit::Popup::SetTailPosition
118    */
119   void SetTailPosition(Vector3 position);
120
121   /**
122    * @copydoc Toolkit::Popup::GetTailPosition
123    */
124   const Vector3& GetTailPosition() const;
125
126   /**
127    * @copydoc Toolkit::Popup::SetContextualMode
128    */
129   void SetContextualMode(Toolkit::Popup::ContextualMode mode);
130
131   /**
132    * @copydoc Toolkit::Popup::GetContextualMode
133    */
134   Toolkit::Popup::ContextualMode GetContextualMode() const;
135
136   /**
137    * @copydoc Toolkit::Popup::SetAnimationDuration
138    */
139   void SetAnimationDuration(float duration);
140
141   /**
142    * @copydoc Toolkit::Popup::GetAnimationDuration
143    */
144   float GetAnimationDuration() const;
145
146   /**
147    * @copydoc Toolkit::Popup::SetAnimationMode
148    */
149   void SetAnimationMode(Toolkit::Popup::AnimationMode animationMode);
150
151   /**
152    * @copydoc Toolkit::Popup::GetAnimationMode
153    */
154   Toolkit::Popup::AnimationMode GetAnimationMode() const;
155
156   /**
157    * @copydoc Toolkit::Popup::SetAutoHideDelay
158    */
159   void SetAutoHideDelay(int delay);
160
161   /**
162    * @copydoc Toolkit::Popup::GetAutoHideDelay
163    */
164   int GetAutoHideDelay() const;
165
166   /**
167    * @copydoc Toolkit::Popup::SetBackingEnabled
168    */
169   void SetBackingEnabled(bool enabled);
170
171   /**
172    * @copydoc Toolkit::Popup::IsBackingEnabled
173    */
174   const bool IsBackingEnabled() const;
175
176   /**
177    * @copydoc Toolkit::Popup::SetBackingColor
178    */
179   void SetBackingColor(Vector4 color);
180
181   /**
182    * @copydoc Toolkit::Popup::GetBackingColor
183    */
184   const Vector4& GetBackingColor() const;
185
186   /**
187    * @copydoc Toolkit::Popup::SetTailUpImage
188    */
189   void SetTailUpImage(std::string image);
190
191   /**
192    * @copydoc Toolkit::Popup::GetTailUpImage
193    */
194   const std::string& GetTailUpImage() const;
195
196   /**
197    * @copydoc Toolkit::Popup::SetTailDownImage
198    */
199   void SetTailDownImage(std::string image);
200
201   /**
202    * @copydoc Toolkit::Popup::GetTailDownImage
203    */
204   const std::string& GetTailDownImage() const;
205
206   /**
207    * @copydoc Toolkit::Popup::SetTailLeftImage
208    */
209   void SetTailLeftImage(std::string image);
210
211   /**
212    * @copydoc Toolkit::Popup::GetTailLeftImage
213    */
214   const std::string& GetTailLeftImage() const;
215
216   /**
217    * @copydoc Toolkit::Popup::SetTailRightImage
218    */
219   void SetTailRightImage(std::string image);
220
221   /**
222    * @copydoc Toolkit::Popup::GetTailRightImage
223    */
224   const std::string& GetTailRightImage() const;
225
226   /**
227    * Called when a property of an object of this type is set.
228    * @param[in] object The object whose property is set.
229    * @param[in] propertyIndex The property index.
230    * @param[in] value The new property value.
231    */
232   static void SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value);
233
234   /**
235    * Called to retrieve a property of an object of this type.
236    * @param[in] object The object whose property is to be retrieved.
237    * @param[in] propertyIndex The property index.
238    * @return The current value of the property.
239    */
240   static Property::Value GetProperty(BaseObject* object, Property::Index propertyIndex);
241
242 protected:
243   struct AccessibleImpl : public Control::Impl::AccessibleImpl
244   {
245     using Control::Impl::AccessibleImpl::AccessibleImpl;
246
247     std::string                 GetNameRaw() override;
248     Dali::Accessibility::States CalculateStates() override;
249   };
250
251   /**
252    * Construct a new Popup.
253    */
254   Popup();
255
256   /**
257    * A reference counted object may only be deleted by calling Unreference()
258    */
259   virtual ~Popup();
260
261 private:
262   /**
263    * @brief Creates the layout of the popup, to be done just before showing for the first time.
264    * Also calls OnLayoutSetup() to allow derived classes to perform layout at this stage.
265    */
266   void LayoutPopup();
267
268   /**
269    * @brief Creates or destroys the popup tail based on the current TAIL_DISPLAYED property.
270    * Also uses the TAIL_POSITION property to position it.
271    */
272   void LayoutTail();
273
274   /**
275    * @brief Performs any relative positioning required based on the current contextual mode, if set.
276    * If contextual mode is not enabled, this method has no effect.
277    * @param[in] size The Popups current size (can be accessed from within the OnRelayout() method).
278    */
279   void LayoutContext(const Vector2& size);
280
281   /**
282    * @brief All transition-in animation setup and layout is done here.
283    * Different types of animation mode require different layouts to work,
284    * this function encapsulates anything animation-mode specific.
285    * This is called once for multiple displays/hides of the pops.
286    * It is only re-called when the layout becomes dirty.
287    */
288   void LayoutAnimation();
289
290   /**
291    * @brief Initiates a transition-in or transition-out animation based
292    * on the current animation settings.
293    * @param[in] transitionIn True to perform a transition-in, false for transition out.
294    * @param[in] instantaneous Optional - If set to true will override the duration to provide an instant animation.
295    */
296   void StartTransitionAnimation(bool transitionIn, bool instantaneous = false);
297
298   /**
299    * @brief Invoked once a display state change has completed.
300    */
301   void DisplayStateChangeComplete();
302
303   /**
304    * @brief This is called when the auto-hide timer finishes.
305    * It performs a display-state change to HIDDEN.
306    * @return True as signal is consumed.
307    */
308   bool OnAutoHideTimeReached();
309
310   /**
311    * @brief Create Dimmed Backing (covers all content behind the dialog).
312    *
313    * @return The backing control.
314    */
315   Toolkit::Control CreateBacking();
316
317   /**
318    * @brief Creates the lower area within the popup.
319    */
320   void CreateFooter();
321
322   /**
323    * @brief Sets if the popup allows touch events to pass through or not.
324    *
325    * @param[in] enabled Set to true to make the popup touch-transparent.
326    */
327   void SetTouchTransparent(bool enabled);
328
329   /**
330    * @brief Returns if the popup allows touch events to pass through or not.
331    *
332    * @return True if the popup is touch-transparent.
333    */
334   const bool IsTouchTransparent() const;
335
336   /**
337    * @brief Allows the popup entry animation to be setup from a Property::Map that could
338    * originate, for example, from a JSON file.
339    *
340    * @param[in] map A Property::Map containing a description of an animation
341    */
342   void SetEntryAnimationData(const Property::Map& map);
343
344   /**
345    * @brief Allows the popup exit animation to be setup from a Property::Map that could
346    * originate, for example, from a JSON file.
347    *
348    * @param[in] map A Property::Map containing a description of an animation
349    */
350   void SetExitAnimationData(const Property::Map& map);
351
352   /**
353    * @briefs Updates the popup background's position and size.
354    */
355   void UpdateBackgroundPositionAndSize();
356
357 public: // Signals
358   /**
359    * @copydoc Dali::Toolkit::Popup::OutsideTouchedSignal()
360    */
361   Toolkit::Popup::TouchedOutsideSignalType& OutsideTouchedSignal();
362
363   /**
364    * @copydoc Dali::Toolkit::Popup::ShowingSignal()
365    */
366   Toolkit::Popup::DisplayStateChangeSignalType& ShowingSignal();
367
368   /**
369    * @copydoc Dali::Toolkit::Popup::ShownSignal()
370    */
371   Toolkit::Popup::DisplayStateChangeSignalType& ShownSignal();
372
373   /**
374    * @copydoc Dali::Toolkit::Popup::HidingSignal()
375    */
376   Toolkit::Popup::DisplayStateChangeSignalType& HidingSignal();
377
378   /**
379    * @copydoc Dali::Toolkit::Popup::HiddenSignal()
380    */
381   Toolkit::Popup::DisplayStateChangeSignalType& HiddenSignal();
382
383   /**
384    * Connects a callback function with the object's signals.
385    * @param[in] object The object providing the signal.
386    * @param[in] tracker Used to disconnect the signal.
387    * @param[in] signalName The signal to connect to.
388    * @param[in] functor A newly allocated FunctorDelegate.
389    * @return True if the signal was connected.
390    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
391    */
392   static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
393
394 private:
395   /**
396    * Signal occurs when the State animation (transition from hide <-> show) finishes.
397    * @param[in] source The animation that just finished.
398    */
399   void OnDisplayChangeAnimationFinished(Animation& source);
400
401   /**
402    * Signal occurs when the dimmed backing for the Popup is touched.
403    * @param[in] actor The Actor Touched
404    * @param[in] touch The Touch Data.
405    * @return Whether to consume event or not.
406    */
407   bool OnBackingTouched(Actor actor, const TouchEvent& touch);
408
409   /**
410    * Signal occurs when a mouse wheel event occurs on the dimmed backing.
411    * @param[in] actor The Actor that got the wheel event.
412    * @param[in] event The Wheel Event.
413    * @return Whether to consume event or not.
414    */
415   bool OnBackingWheelEvent(Actor actor, const WheelEvent& event);
416
417   /**
418    * Signal occurs when the dialog has been touched.
419    * @param[in] actor The Actor Touched
420    * @param[in] touch The Touch Data.
421    * @return Whether to consume event or not.
422    */
423   bool OnDialogTouched(Actor actor, const TouchEvent& touch);
424
425   /**
426    * @copydoc Toolkit::Control::OnInitialize()
427    */
428   void OnInitialize() override;
429
430   /**
431    * Called whenever the popup layout is re-set up.
432    * Normally due to a change in contents.
433    * Note: This is only done when the popup is shown.
434    */
435   virtual void OnLayoutSetup()
436   {
437   }
438
439   /**
440    * Called when the popup is directly or indirectly parented to the stage.
441    */
442   void OnSceneConnection(int depth) override;
443
444   /**
445    * From Control; called after a child has been added to the owning actor.
446    * @param[in] child The child which has been added.
447    */
448   void OnChildAdd(Actor& child) override;
449
450   /**
451    * @copydoc Control::OnRelayOut()
452    */
453   void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
454
455   /**
456    * @copydoc Control::OnSetResizePolicy()
457    */
458   void OnSetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension) override;
459
460   /**
461    * @copydoc Control::GetNaturalSize()
462    */
463   Vector3 GetNaturalSize() override;
464
465   /**
466    * @copydoc Control::GetHeightForWidth()
467    */
468   float GetHeightForWidth(float width) override;
469
470   /**
471    * @copydoc Control::GetWidthForHeight()
472    */
473   float GetWidthForHeight(float height) override;
474
475   /**
476    * @copydoc Control::OnKeyEvent()
477    */
478   bool OnKeyEvent(const KeyEvent& event) override;
479
480   /**
481    * @copydoc Control::GetNextKeyboardFocusableActor()
482    */
483   Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
484
485 private:
486   /**
487    * Recursively add any focusable actors or layout containers to the provided vector.
488    * Include the top level actor if it is a layout container.
489    *
490    * @param[in]     parent          The actor to start from
491    * @param[in/out] focusableActors The vector to add focusable actors to
492    */
493   void AddFocusableChildren(Actor parent, std::vector<Actor>& focusableActors);
494
495   /**
496    * Recursively add any focusable actors or layout containers to the provided vector.
497    *
498    * @param[in]     parent          The actor to start from
499    * @param[in/out] focusableActors The vector to add focusable actors to
500    */
501   void AddFocusableChildrenRecursive(Actor parent, std::vector<Actor>& focusableActors);
502
503   /**
504    * Sets up the touch signals connections as required.
505    * @note This must be called after all the members have been created.
506    */
507   void SetupTouch();
508
509 private:
510   // Undefined.
511   Popup(const Popup&);
512
513   // Undefined.
514   Popup& operator=(const Popup& rhs);
515
516 private:
517   Toolkit::Popup::TouchedOutsideSignalType     mTouchedOutsideSignal;
518   Toolkit::Popup::DisplayStateChangeSignalType mShowingSignal;
519   Toolkit::Popup::DisplayStateChangeSignalType mShownSignal;
520   Toolkit::Popup::DisplayStateChangeSignalType mHidingSignal;
521   Toolkit::Popup::DisplayStateChangeSignalType mHiddenSignal;
522
523   Layer              mLayer;                ///< Popup Layer (i.e. Dim backing and PopupBg reside in this).
524   Toolkit::TableView mPopupLayout;          ///< Popup Background (i.e. dialog reside in this).
525   Toolkit::Control   mBacking;              ///< Backing actor (dim effect).
526   Actor              mPreviousFocusedActor; ///< Store the previous focused actor to restore the focus when popup hide.
527   Actor              mTailImage;            ///< Stores the tail image.
528   Actor              mPopupContainer;       ///< This actor is used to house the background image and the main popup layout.
529   Animation          mAnimation;            ///< The current animation in use used to manage display state changing.
530   bool               mAlterAddedChild;      ///< Flag used to control whether children are reparented or not.
531   bool               mLayoutDirty;          ///< Set to true whenever any property that would require a layout update is modified.
532   Timer              mAutoHideTimer;        ///< Used to perform an auto-hide of the popup if desired.
533   bool               mTouchTransparent;     ///< Allows all events to pass through the popup.
534
535   // Main Content related properties:
536   Actor mTitle;   ///< Stores the text title.
537   Actor mContent; ///< Stores the unselected content.
538   Actor mFooter;  ///< Stores the footer content (typically controls).
539
540   // Display related properties.
541   Toolkit::Popup::DisplayState   mDisplayState;       ///< The current display state of the popup.
542   bool                           mTailVisible;        ///< True if the popup tail should be visible.
543   Vector3                        mTailPosition;       ///< The position of the tail.
544   Toolkit::Popup::ContextualMode mContextualMode;     ///< Allows the popup to be layed out adjacent to its parent in different directions.
545   float                          mAnimationDuration;  ///< The duration of the transition in and out animations.
546   Toolkit::Popup::AnimationMode  mAnimationMode;      ///< The animation to use to transition in and out.
547   Dali::AnimationData            mEntryAnimationData; ///< Stores description data that can be used for generating a custom entry animation.
548   Dali::AnimationData            mExitAnimationData;  ///< Stores description data that can be used for generating a custom exit animation.
549   unsigned int                   mAutoHideDelay;      ///< If set, will auto-hide the popup after a specified amount of time.
550
551   // Style related properties:
552   bool        mBackingEnabled;       ///< True if a dimmed backing will be used.
553   Vector4     mBackingColor;         ///< The color of the backing.
554   Actor       mPopupBackgroundImage; ///< Stores the background image.
555   Rect<int>   mBackgroundBorder;     ///< Background border.
556   float       mMargin;               ///< Internal margin for popup contents.
557   std::string mTailUpImage;          ///< Image used for the tail for the up direction.
558   std::string mTailDownImage;        ///< Image used for the tail for the down direction.
559   std::string mTailLeftImage;        ///< Image used for the tail for the left direction.
560   std::string mTailRightImage;       ///< Image used for the tail for the right direction.
561 };
562
563 } // namespace Internal
564
565 // Helpers for public-api forwarding methods
566
567 inline Toolkit::Internal::Popup& GetImpl(Toolkit::Popup& publicObject)
568 {
569   DALI_ASSERT_ALWAYS(publicObject);
570
571   Dali::RefObject& handle = publicObject.GetImplementation();
572
573   return static_cast<Toolkit::Internal::Popup&>(handle);
574 }
575
576 inline const Toolkit::Internal::Popup& GetImpl(const Toolkit::Popup& publicObject)
577 {
578   DALI_ASSERT_ALWAYS(publicObject);
579
580   const Dali::RefObject& handle = publicObject.GetImplementation();
581
582   return static_cast<const Toolkit::Internal::Popup&>(handle);
583 }
584
585 } // namespace Toolkit
586
587 } // namespace Dali
588
589 #endif // DALI_TOOLKIT_INTERNAL_POPUP_H