b3488ea2f61daf545a9a5cc226d1c32ef83f4e6a
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / buttons / button-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_BUTTON_H
2 #define DALI_TOOLKIT_INTERNAL_BUTTON_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 // EXTERNAL INCLUDES
22 #include <dali/public-api/adaptor-framework/timer.h>
23 #include <dali/public-api/animation/animation.h>
24
25 // INTERNAL INCLUDES
26 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
27 #include <dali-toolkit/public-api/controls/buttons/button.h>
28 #include <dali-toolkit/public-api/controls/control-impl.h>
29
30 namespace Dali
31 {
32
33 namespace Toolkit
34 {
35
36 class Button;
37
38 namespace Internal
39 {
40
41 /**
42  * @copydoc Toolkit::Button
43  *
44  * Button is the base class implementation for all buttons.
45  *
46  * @note
47  *
48  * All Foreground/Icon visuals expected to be the same size.
49  * Background visuals will take the size of the control.
50  * Padding and struts take size precedence over visuals when available space is limited.
51  * Icon/Foreground visuals take size precedence over Labels when available space is limited.
52  */
53 class Button : public Control
54 {
55
56 public:
57
58   /**
59    * Enum describing the position the text label can be in relation to the control (and foreground/icon)
60    */
61   enum Align
62   {
63     BEGIN,  // At the start of the control before the foreground/icon
64     END,    // At the end of the control after the foreground/icon
65     TOP,    // At the top of the control above the foreground/icon
66     BOTTOM  // At the bottom of the control below the foreground/icon
67   };
68
69 public:
70
71   /**
72    * @copydoc Dali::Toolkit::Button::SetDisabled
73    */
74   void SetDisabled( bool disabled );
75
76   /**
77    * @copydoc Dali::Toolkit::Button::IsDisabled
78    */
79   bool IsDisabled() const;
80
81   /**
82    * @copydoc Dali::Toolkit::Button::SetAutoRepeating
83    */
84   void SetAutoRepeating( bool autoRepeating );
85
86   /**
87    * @copydoc Dali::Toolkit::Button::IsAutoRepeating
88    */
89   bool IsAutoRepeating() const;
90
91   /**
92    * @copydoc Dali::Toolkit::Button::SetInitialAutoRepeatingDelay
93    */
94   void SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay );
95
96   /**
97    * @copydoc Dali::Toolkit::Button::GetInitialAutoRepeatingDelay
98    */
99   float GetInitialAutoRepeatingDelay() const;
100
101   /**
102    * @copydoc Dali::Toolkit::Button::SetNextAutoRepeatingDelay
103    */
104   void SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay );
105
106   /**
107    * @copydoc Dali::Toolkit::Button::GetNextAutoRepeatingDelay
108    */
109   float GetNextAutoRepeatingDelay() const;
110
111   /**
112    * @copydoc Dali::Toolkit::Button::SetTogglableButton
113    */
114   void SetTogglableButton( bool togglable );
115
116   /**
117    * @copydoc Dali::Toolkit::Button::IsTogglableButton
118    */
119   bool IsTogglableButton() const;
120
121   /**
122    * @copydoc Dali::Toolkit::Button::SetSelected
123    */
124   void SetSelected( bool selected );
125
126   /**
127    * @copydoc Dali::Toolkit::Button::IsSelected
128    */
129   bool IsSelected() const;
130
131   /**
132    * @copydoc Dali::Toolkit::Button::SetAnimationTime
133    */
134   void SetAnimationTime( float animationTime );
135
136   /**
137    * @copydoc Dali::Toolkit::Button::GetAnimationTime
138    */
139   float GetAnimationTime() const;
140
141   /**
142    * @copydoc Dali::Toolkit::Button::SetLabelText
143    */
144   void SetLabelText( const std::string& label );
145
146   /**
147    * @copydoc Dali::Toolkit::Button::GetLabelText
148    */
149   std::string GetLabelText() const;
150
151   /**
152    * @brief Sets the specified properties on the button label.
153    * If the label does not exist yet, it is created.
154    * The derived buttons are notified if any properties are changed.
155    * @param[in] properties A Property::Map of key-value pairs of properties to set.
156    */
157   void SetupLabel( const Property::Map& properties );
158
159   /**
160    * Performs actions as requested using the action name.
161    * @param[in] object The object on which to perform the action.
162    * @param[in] actionName The action to perform.
163    * @param[in] attributes The attributes with which to perfrom this action.
164    * @return true if action has been accepted by this control
165    */
166   static bool DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes );
167
168 public: // Deprecated API
169
170   /**
171    * @copydoc Dali::Toolkit::Button::SetLabel( Actor label )
172    */
173   void SetLabel( Actor label );
174
175   /**
176    * @deprecated Sets the unselected image with an url.
177    * @param[in] image The Actor to use.
178    */
179   void SetUnselectedImage( const std::string& filename );
180
181   /**
182    * @deprecated Sets the selected image with an url.
183    * @param[in] filename The url of the image to use to use.
184    */
185   void SetSelectedImage( const std::string& filename );
186
187   /**
188    * @deprecated Sets the selected background image with an url.
189    * @param[in] filename The url of the image to use to use.
190    */
191   void SetSelectedBackgroundImage( const std::string& filename );
192
193   /**
194    * @deprecated Sets the background image with an url.
195    * @param[in] filename The url of the image to use to use.
196    */
197   void SetBackgroundImage( const std::string& filename );
198
199   /**
200    * @deprecated Sets the disabled unselected background image with an url.
201    * @param[in] filename The url of the image to use to use.
202    */
203   void SetDisabledBackgroundImage( const std::string& filename );
204
205   /**
206    * @deprecated Sets the disabled unselected image with an url.
207    * @param[in] filename The url of the image to use to use.
208    */
209   void SetDisabledImage( const std::string& filename );
210
211   /**
212    * @deprecated Sets the disabled selected image with an url.
213    * @param[in] filename The url of the image to use to use.
214    */
215   void SetDisabledSelectedImage( const std::string& filename );
216
217   /**
218    * @deprecated Sets the unselected image with an Actor.
219    * @param[in] image The Image to use.
220    */
221   void SetButtonImage( Image image );
222
223   /**
224    * @deprecated Sets the selected image with an Actor.
225    * @param[in] image The Image to use.
226    */
227   void SetSelectedImage( Image image );
228
229   /**
230    * @Gets url of a image visual, used by GetProperty but for deprecated Properties
231    * @param[in] index Visual index of url required
232    * @return filename for the corresponding visual
233    */
234   std::string GetUrlForImageVisual( const Property::Index index ) const;
235
236   /**
237    * @copydoc Dali::Toolkit::Button::GetButtonImage
238    */
239   Actor GetButtonImage() const;
240
241   /**
242    * @copydoc Dali::Toolkit::Button::GetSelectedImage
243    */
244   Actor GetSelectedImage() const;
245
246 public:
247
248   /**
249    * Button's state
250    */
251   enum State
252   {
253     UNSELECTED_STATE,              ///< The button is unselected.
254     SELECTED_STATE,                ///< The button is selected.
255     DISABLED_UNSELECTED_STATE,     ///< The button is disabled and unselected.
256     DISABLED_SELECTED_STATE,       ///< The button is disabled and selected.
257     STATE_COUNT,                   ///< Number of States
258   };
259
260   /**
261    * Enum to distinguish the different style-able components of the button
262    */
263   enum Visuals
264   {
265     UNSELECTED_FOREGROUND = 0,
266     SELECTED_FOREGROUND,
267     DISABLED_SELECTED_FOREGROUND,
268     DISABLED_UNSELECTED_FOREGROUND,
269     UNSELECTED_BACKGROUND,
270     SELECTED_BACKGROUND,
271     DISABLED_UNSELECTED_BACKGROUND,
272     DISABLED_SELECTED_BACKGROUND,
273     VISUALS_COUNT
274   };
275
276   /**
277    * Enum to list types of visual a state can have.
278    */
279   enum VisualState
280   {
281     BACKGROUND = 0,
282     FOREGROUND,
283     VISUAL_STATE_COUNT
284   };
285
286 protected:
287
288   /**
289    * Button press state which is not the same as the actual button's state.
290    * For example An UNSELECTED button can be DEPRESSED, but until released, the actual button state doesn't change to SELECTED
291    */
292   enum PressState
293   {
294     DEPRESSED,                           ///< The button is up.
295     UNPRESSED,                           ///< The button is down.
296     TOGGLE_DEPRESSED,                    ///< The button has been pressed down and will stay depressed when released.
297   };
298
299   /**
300    * Construct a new Button.
301    */
302   Button();
303
304   /**
305    * A reference counted object may only be deleted by calling Unreference()
306    */
307   virtual ~Button();
308   /**
309    * @return A reference to the label actor.
310    */
311   Actor& GetLabelActor();
312
313   /**
314    * @return A reference to the unselected button image.
315    */
316   Actor GetUnselectedImage();
317
318   /**
319    * @return A reference to the selected image.
320    */
321   Actor GetSelectedImage();
322
323 private:
324
325   /**
326    * Perform the click action to click the button.
327    * @param[in] attributes The attributes to perfrom this action.
328    * @return true if this control can perform action.
329    */
330   bool DoClickAction( const Property::Map& attributes );
331
332   /**
333    * This method is called when the button is a Toggle button and released
334    * Could be reimplemented in subclasses to provide specific behaviour.
335    * @return bool returns true if state changed.
336    */
337   virtual bool OnToggleReleased();
338
339   /**
340    * This method is called when touch leaves the boundary of the button or several touch points are received.
341    * Could be reimplemented in subclasses to provide specific behaviour.
342    */
343   virtual void OnTouchPointLeave();
344
345   /**
346    * This method is called when the touch is interrupted.
347    * Could be reimplemented in subclasses to provide specific behaviour.
348    */
349   virtual void OnTouchPointInterrupted();
350
351   /**
352    * This method is called when the \e selected property is changed.
353    */
354   virtual void OnStateChange( State newState ){}
355
356   /**
357    * This method is called when the \e disabled property is changed.
358    */
359   virtual void OnDisabled() {}
360
361   /**
362    * This method is called when the button is pressed.
363    */
364   virtual void OnPressed() {}
365
366   /**
367    * This method is called when the button is released.
368    */
369   virtual void OnReleased() {}
370
371 public:
372
373   /**
374    * @copydoc Dali::Toolkit::PushButton::PressedSignal()
375    */
376   Toolkit::Button::ButtonSignalType& PressedSignal();
377
378   /**
379    * @copydoc Dali::Toolkit::PushButton::ReleasedSignal()
380    */
381   Toolkit::Button::ButtonSignalType& ReleasedSignal();
382
383   /**
384    * @copydoc Dali::Toolkit::Button::ClickedSignal()
385    */
386   Toolkit::Button::ButtonSignalType& ClickedSignal();
387
388   /**
389    * @copydoc Dali::Toolkit::Button::StateChangedSignal()
390    */
391   Toolkit::Button::ButtonSignalType& StateChangedSignal();
392
393   /**
394    * Connects a callback function with the object's signals.
395    * @param[in] object The object providing the signal.
396    * @param[in] tracker Used to disconnect the signal.
397    * @param[in] signalName The signal to connect to.
398    * @param[in] functor A newly allocated FunctorDelegate.
399    * @return True if the signal was connected.
400    * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
401    */
402   static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
403
404   // Properties
405
406   /**
407    * Called when a property of an object of this type is set.
408    * @param[in] object The object whose property is set.
409    * @param[in] index The property index.
410    * @param[in] value The new property value.
411    */
412   static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
413
414   /**
415    * Called to retrieve a property of an object of this type.
416    * @param[in] object The object whose property is to be retrieved.
417    * @param[in] index The property index.
418    * @return The current value of the property.
419    */
420   static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
421
422 protected: // From Control
423
424   /**
425    * @copydoc Toolkit::Control::OnInitialize()
426    * @note If overridden by deriving button classes, then an up-call to Button::OnInitialize MUST be made at the start.
427    */
428   virtual void OnInitialize();
429
430   /**
431    * @copydoc Toolkit::Control::OnAccessibilityActivated()
432    */
433   virtual bool OnAccessibilityActivated();
434
435   /**
436    * @copydoc Toolkit::Control::OnKeyboardEnter()
437    */
438   virtual bool OnKeyboardEnter();
439
440   /**
441    * @copydoc Toolkit::Control::OnStageDisconnection()
442    * @note If overridden by deriving button classes, then an up-call to Button::OnStageDisconnection MUST be made at the end.
443    */
444   virtual void OnStageDisconnection();
445
446   /**
447    * @copydoc Toolkit::Control::OnStageConnnection()
448    */
449   virtual void OnStageConnection( int depth );
450
451   /**
452    * @copydoc Toolkit::Control::GetNaturalSize
453    */
454   virtual Vector3 GetNaturalSize();
455
456   /**
457    * @copydoc Toolkit::Control::OnSetResizePolicy
458    */
459   virtual void OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension );
460
461   /**
462    * @copydoc Toolkit::Control::OnRelayout
463    */
464   virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
465
466 private:
467
468   /**
469    * @brief Handler for touch data
470    * @param[in]  actor  The touched actor.
471    * @param[in]  touch  The touch info.
472    * @return true, if consumed, false otherwise.
473    */
474   bool OnTouch( Actor actor, const TouchData& touch );
475
476   /**
477    * Handler for tap events.
478    * We do not actually do anything when we receive a tap as the button handles tap event through
479    * the touch event system itself as it requires more than just tap handling (e.g. leave events).
480    * This stops any of our parents receiving a tap gesture when it occurs within our area.
481    * @param[in]  actor  The tapped actor.
482    * @param[in]  tap    The tap gesture.
483    */
484   void OnTap(Actor actor, const TapGesture& tap);
485
486   /**
487    * Sets up the autorepeating timer.
488    * @param[in] delay The delay time in seconds.
489    */
490   void SetUpTimer( float delay );
491
492   /**
493    * Button has been pressed
494    */
495   void Pressed();
496
497   /**
498    * This method is called the button is down.
499    */
500   void ButtonDown();
501
502   /**
503    * This method is called when the button is up.
504    */
505   void ButtonUp();
506
507   /**
508    * Slot called when Dali::Timer::SignalTick signal. Resets the autorepeating timer.
509    */
510   bool AutoRepeatingSlot();
511
512   /**
513    *  Check the requested state is an allowed transition.
514    *  Some states can not be transitioned to from certain states.
515    *  @param[in] requestedState check if can transition to this state
516    *  @return bool true if state change valid
517    */
518   bool ValidateState( State requestedState );
519
520   /**
521    * Perform the given function on the visuals in the given state. Can be used to add and remove visuals.
522    * @param[in] functionPtr pointer to the function to perform an action on a visual
523    * @param[in] state Visuals in this state will be the target
524    */
525   void PerformFunctionOnVisualsInState( void(Button::*functionPtr)( Property::Index visualIndex), State state  );
526
527   /**
528    * Changes the button state when an action occurs on it
529    * @param[in] requestedState the state to change to
530    */
531   void ChangeState( State requestedState );
532
533   /**
534    * @brief Get unselected button color
535    * @return color as vector4
536    */
537   const Vector4 GetUnselectedColor() const;
538
539   /**
540    * @brief Get selected button color
541    * @return color as vector4
542    */
543   const Vector4 GetSelectedColor() const;
544
545   /**
546    * Sets the color of button in selected or unselected state, if image also supplied this color will be appplied to it.
547    * If no visual exists, it is created.
548    * @param[in]  color The color to use.
549    * @param[in]  visualIndex The Visual to apply the color
550    */
551   void SetColor( const Vector4& color, Property::Index visualIndex );
552
553   /**
554    * This method is called when the button is released.
555    */
556   void Released();
557
558 protected:
559
560   /**
561    * Set Text Label Padding
562    * @param[in] padding BEGIN END BOTTOM TOP
563    */
564   void SetLabelPadding( const Padding& padding );
565
566   /**
567    * Get Text Label padding
568    * @return Padding
569    */
570   Padding GetLabelPadding();
571
572   /**
573    * Set Foreground/icon Padding
574    * @param[in] padding BEGIN END BOTTOM TOP
575    */
576   void SetForegroundPadding( const Padding& padding);
577
578   /**
579    * Get Foreground padding
580    * @ return Padding
581    */
582   Padding GetForegroundPadding();
583
584   /**
585    * @brief Setup the button components for example foregrounds and background
586    * @param[in] index the index of the visual to set
587    * @param[in] value the value to set on the component
588    * @param[in] visualDepth the depth of the visual if overlapping another
589    */
590   void CreateVisualsForComponent( Property::Index index ,const Property::Value& value, const float visualDepth );
591
592   /**
593    * Returns the animation to be used for transition, creating the animation if needed.
594    * @return The initialised transition animation.
595    */
596   Dali::Animation GetTransitionAnimation();
597
598   /**
599    * @brief Set the position of the label relative to foreground/icon, if both present
600    * @param[in] labelAlignment given alignment setting
601    */
602   void SetLabelAlignment( Align labelAlignment);
603
604   /**
605    * @brief Get set alignment of label in relation to foreground/icon
606    * @return Set alignment value
607    */
608   Align GetLabelAlignment();
609
610   /**
611    * Removes the visual from the button (un-staged)
612    * If the derived button does not want the visual removed then use this virtual function to
613    * define the required behaviour.
614    * Can decide to only remove specified visuals via index
615    */
616   virtual void OnButtonVisualRemoval( Property::Index visualIndex );
617
618
619 private:
620
621   /**
622    * Removes the visual from the button and prepares it to be transitioned out
623    * @param[in] visualIndex the visual to remove
624    */
625   void RemoveVisual( Property::Index visualIndex );
626
627   /**
628    * Adds the required visual to the button.
629    * @param[in] visualIndex The Property index of the visual required
630    */
631   void SelectRequiredVisual( Property::Index visualIndex );
632
633   // Undefined
634   Button( const Button& );
635
636   // Undefined
637   Button& operator = ( const Button& );
638
639 private:
640
641   // Signals
642   Toolkit::Button::ButtonSignalType mPressedSignal;           ///< Signal emitted when the button is pressed.
643   Toolkit::Button::ButtonSignalType mReleasedSignal;          ///< Signal emitted when the button is released.
644   Toolkit::Button::ButtonSignalType mClickedSignal;           ///< Signal emitted when the button is clicked.
645   Toolkit::Button::ButtonSignalType mStateChangedSignal;      ///< Signal emitted when the button's state is changed.
646
647   Timer            mAutoRepeatingTimer;
648
649   Actor            mLabel;                      ///< Stores the button text label.
650   Padding          mLabelPadding;               ///< The padding around the label (if present).
651   Padding          mForegroundPadding;          ///< The padding around the foreground/icon visual (if present).
652
653   Align            mTextLabelAlignment;           ///< Position of text label in relation to foreground/icon when both are present.
654
655   TapGestureDetector mTapDetector;
656
657   Vector4          mUnselectedColor;
658   Vector4          mSelectedColor;
659
660   bool             mAutoRepeating;              ///< Stores the autorepeating property.
661   bool             mTogglableButton;            ///< Stores the togglable property as a flag.
662   float            mInitialAutoRepeatingDelay;  ///< Stores the initial autorepeating delay in seconds.
663   float            mNextAutoRepeatingDelay;     ///< Stores the next autorepeating delay in seconds.
664
665   float            mAnimationTime;
666
667   PressState       mButtonPressedState;         ///< In relation to the button being pressed/released
668   State            mButtonState;
669   State            mPreviousButtonState;        ///< During a transition between two states, this stores the previous state so Visuals can be removed.
670
671   // Actions
672   bool             mClickActionPerforming;      ///< Used to manage signal emissions during action
673 };
674
675 } // namespace Internal
676
677 // Helpers for public-api forwarding methods
678
679 inline Toolkit::Internal::Button& GetImplementation( Toolkit::Button& button )
680 {
681   DALI_ASSERT_ALWAYS( button );
682
683   Dali::RefObject& handle = button.GetImplementation();
684
685   return static_cast<Toolkit::Internal::Button&>( handle );
686 }
687
688 inline const Toolkit::Internal::Button& GetImplementation( const Toolkit::Button& button )
689 {
690   DALI_ASSERT_ALWAYS( button );
691
692   const Dali::RefObject& handle = button.GetImplementation();
693
694   return static_cast<const Toolkit::Internal::Button&>( handle );
695 }
696
697 } // namespace Toolkit
698
699 } // namespace Dali
700
701 #endif // DALI_TOOLKIT_INTERNAL_BUTTON_H