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