1 #ifndef DALI_TOOLKIT_INTERNAL_BUTTON_H
2 #define DALI_TOOLKIT_INTERNAL_BUTTON_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <dali/public-api/adaptor-framework/timer.h>
23 #include <dali/public-api/animation/animation.h>
26 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
27 #include <dali-toolkit/devel-api/controls/control-devel.h>
28 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
29 #include <dali-toolkit/public-api/controls/control-impl.h>
40 * @copydoc Toolkit::Button
42 * Button is the base class implementation for all buttons.
46 * All Foreground/Icon visuals expected to be the same size.
47 * Background visuals will take the size of the control.
48 * Padding and struts take size precedence over visuals when available space is limited.
49 * Icon/Foreground visuals take size precedence over Labels when available space is limited.
51 class Button : public Control
55 * Enum describing the position the text label can be in relation to the control (and foreground/icon)
59 BEGIN, // At the start of the control before the foreground/icon
60 END, // At the end of the control after the foreground/icon
61 TOP, // At the top of the control above the foreground/icon
62 BOTTOM // At the bottom of the control below the foreground/icon
67 * @brief Sets the button as \e disabled.
68 * @param[in] disabled Disabled property
70 void SetDisabled(bool disabled);
73 * @brief Returns if the button is disabled.
74 * @return \e true if the button is \e disabled
76 bool IsDisabled() const;
79 * @brief Sets the \e autorepeating property.
80 * @param[in] autoRepeating \e autorepeating property
82 void SetAutoRepeating(bool autoRepeating);
85 * @brief Sets the initial autorepeating delay.
86 * @param[in] initialAutoRepeatingDelay in seconds
88 void SetInitialAutoRepeatingDelay(float initialAutoRepeatingDelay);
91 * @brief Sets the next autorepeating delay.
92 * @param[in] nextAutoRepeatingDelay in seconds
94 void SetNextAutoRepeatingDelay(float nextAutoRepeatingDelay);
97 * @brief Sets the \e togglable property.
98 * @param[in] togglable Togglable property
100 void SetTogglableButton(bool togglable);
103 * @brief Sets the button as selected or unselected.
104 * @param[in] selected Selected property
106 void SetSelected(bool selected);
109 * @brief Returns if the selected property is set and the button is togglable.
110 * @return \e true if the button is \e selected
112 bool IsSelected() const;
115 * @brief Produces a Property::Map of Text properties to create a Text Visual, merging existing properties with supplied map
116 * If the label does not exist yet, it is created.
117 * The derived buttons are notified if any properties are changed.
118 * @param[in] properties A Property::Map of key-value pairs of properties to set.
119 * @param[out] properties A Property::Map of text visual properties to set after merging inMap with existing maps
121 void MergeWithExistingLabelProperties(const Property::Map& inMap, Property::Map& outMap);
124 * Performs actions as requested using the action name.
125 * @param[in] object The object on which to perform the action.
126 * @param[in] actionName The action to perform.
127 * @param[in] attributes The attributes with which to perfrom this action.
128 * @return true if action has been accepted by this control
130 static bool DoAction(BaseObject* object, const std::string& actionName, const Property::Map& attributes);
138 UNSELECTED_STATE, ///< The button is unselected.
139 SELECTED_STATE, ///< The button is selected.
140 DISABLED_UNSELECTED_STATE, ///< The button is disabled and unselected.
141 DISABLED_SELECTED_STATE, ///< The button is disabled and selected.
142 STATE_COUNT, ///< Number of States
146 * Enum to distinguish the different style-able components of the button
150 UNSELECTED_FOREGROUND = 0,
152 DISABLED_SELECTED_FOREGROUND,
153 DISABLED_UNSELECTED_FOREGROUND,
154 UNSELECTED_BACKGROUND,
156 DISABLED_UNSELECTED_BACKGROUND,
157 DISABLED_SELECTED_BACKGROUND,
162 * Enum to list types of visual a state can have.
173 * Button press state which is not the same as the actual button's state.
174 * For example An UNSELECTED button can be DEPRESSED, but until released, the actual button state doesn't change to SELECTED
178 DEPRESSED, ///< The button is up.
179 UNPRESSED, ///< The button is down.
180 TOGGLE_DEPRESSED, ///< The button has been pressed down and will stay depressed when released.
184 * Construct a new Button.
189 * A reference counted object may only be deleted by calling Unreference()
193 * @return A reference to the label actor.
195 Actor& GetLabelActor();
198 * @return A reference to the unselected button image.
200 Actor GetUnselectedImage();
203 * @return A reference to the selected image.
205 Actor GetSelectedImage();
209 * Perform the click action to click the button.
210 * @param[in] attributes The attributes to perfrom this action.
211 * @return true if this control can perform action.
213 bool DoClickAction(const Property::Map& attributes);
216 * This method is called when the button is a Toggle button and released
217 * Could be reimplemented in subclasses to provide specific behaviour.
218 * @return bool returns true if state changed.
220 virtual bool OnToggleReleased();
223 * This method is called when touch leaves the boundary of the button or several touch points are received.
224 * Could be reimplemented in subclasses to provide specific behaviour.
226 virtual void OnTouchPointLeave();
229 * This method is called when the touch is interrupted.
230 * Could be reimplemented in subclasses to provide specific behaviour.
232 virtual void OnTouchPointInterrupted();
235 * This method is called when the \e selected property is changed.
237 virtual void OnStateChange(State newState)
242 * This method is called when the \e disabled property is changed.
244 virtual void OnDisabled()
249 * This method is called when the button is pressed.
251 virtual void OnPressed()
256 * This method is called when the button is released.
258 virtual void OnReleased()
264 * @copydoc Dali::Toolkit::PushButton::PressedSignal()
266 Toolkit::Button::ButtonSignalType& PressedSignal();
269 * @copydoc Dali::Toolkit::PushButton::ReleasedSignal()
271 Toolkit::Button::ButtonSignalType& ReleasedSignal();
274 * @copydoc Dali::Toolkit::Button::ClickedSignal()
276 Toolkit::Button::ButtonSignalType& ClickedSignal();
279 * @copydoc Dali::Toolkit::Button::StateChangedSignal()
281 Toolkit::Button::ButtonSignalType& StateChangedSignal();
284 * Connects a callback function with the object's signals.
285 * @param[in] object The object providing the signal.
286 * @param[in] tracker Used to disconnect the signal.
287 * @param[in] signalName The signal to connect to.
288 * @param[in] functor A newly allocated FunctorDelegate.
289 * @return True if the signal was connected.
290 * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
292 static bool DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
297 * Called when a property of an object of this type is set.
298 * @param[in] object The object whose property is set.
299 * @param[in] index The property index.
300 * @param[in] value The new property value.
302 static void SetProperty(BaseObject* object, Property::Index index, const Property::Value& value);
305 * Called to retrieve a property of an object of this type.
306 * @param[in] object The object whose property is to be retrieved.
307 * @param[in] index The property index.
308 * @return The current value of the property.
310 static Property::Value GetProperty(BaseObject* object, Property::Index propertyIndex);
312 protected: // From Control
314 * @copydoc Toolkit::Control::OnInitialize()
315 * @note If overridden by deriving button classes, then an up-call to Button::OnInitialize MUST be made at the start.
317 void OnInitialize() override;
320 * @copydoc Toolkit::Control::OnAccessibilityActivated()
322 bool OnAccessibilityActivated() override;
325 * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
327 DevelControl::ControlAccessible* CreateAccessibleObject() override;
330 * @copydoc Toolkit::Control::OnKeyboardEnter()
332 bool OnKeyboardEnter() override;
335 * @copydoc Toolkit::Control::OnSceneDisconnection()
336 * @note If overridden by deriving button classes, then an up-call to Button::OnSceneDisconnection MUST be made at the end.
338 void OnSceneDisconnection() override;
341 * @copydoc Toolkit::Control::OnSceneConnection()
343 void OnSceneConnection(int depth) override;
346 * @copydoc Toolkit::Control::GetNaturalSize
348 Vector3 GetNaturalSize() override;
351 * @copydoc Toolkit::Control::OnSetResizePolicy
353 void OnSetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension) override;
356 * @copydoc Toolkit::Control::OnRelayout
358 void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
362 * @brief Handler for touch data
363 * @param[in] actor The touched actor.
364 * @param[in] touch The touch info.
365 * @return true, if consumed, false otherwise.
367 bool OnTouch(Actor actor, const TouchEvent& touch);
370 * Handler for tap events.
371 * We do not actually do anything when we receive a tap as the button handles tap event through
372 * the touch event system itself as it requires more than just tap handling (e.g. leave events).
373 * This stops any of our parents receiving a tap gesture when it occurs within our area.
374 * @param[in] actor The tapped actor.
375 * @param[in] tap The tap gesture.
377 void OnTap(Actor actor, const TapGesture& tap);
380 * @copydoc Control::OnTap
382 using Control::OnTap;
385 * Sets up the autorepeating timer.
386 * @param[in] delay The delay time in seconds.
388 void SetUpTimer(float delay);
391 * Button has been pressed
396 * This method is called the button is down.
401 * This method is called when the button is up.
406 * Slot called when Dali::Timer::SignalTick signal. Resets the autorepeating timer.
408 bool AutoRepeatingSlot();
411 * Check the requested state is an allowed transition.
412 * Some states can not be transitioned to from certain states.
413 * @param[in] requestedState check if can transition to this state
414 * @return bool true if state change valid
416 bool ValidateState(State requestedState);
419 * Changes the button state when an action occurs on it
420 * @param[in] requestedState the state to change to
422 void ChangeState(State requestedState);
425 * This method is called when the button is released.
431 * Set Text Label Padding
432 * @param[in] padding BEGIN END BOTTOM TOP
434 void SetLabelPadding(const Padding& padding);
437 * Get Text Label padding
440 Padding GetLabelPadding();
443 * Set Foreground/icon Padding
444 * @param[in] padding BEGIN END BOTTOM TOP
446 void SetForegroundPadding(const Padding& padding);
449 * Get Foreground padding
452 Padding GetForegroundPadding();
455 * @brief Setup the button components for example foregrounds and background
456 * @param[in] index the index of the visual to set
457 * @param[in] value the value to set on the component
458 * @param[in] visualDepth the depth of the visual if overlapping another
460 void CreateVisualsForComponent(Property::Index index, const Property::Value& value, const int visualDepth);
463 * @brief Get the Property map for the given Visual
464 * @param[in] visualIndex visual index of the required visual
465 * @param[out] retreivedMap the property map used to construct the required visual
466 * @return bool success flag, true if visual found
468 bool GetPropertyMapForVisual(Property::Index visualIndex, Property::Map& retreivedMap) const;
470 * Returns the animation to be used for transition, creating the animation if needed.
471 * @return The initialised transition animation.
473 Dali::Animation GetTransitionAnimation();
476 * @brief Set the position of the label relative to foreground/icon, if both present
477 * @param[in] labelAlignment given alignment setting
479 void SetLabelAlignment(Align labelAlignment);
482 * @brief Get set alignment of label in relation to foreground/icon
483 * @return Set alignment value
485 Align GetLabelAlignment();
488 * Removes the visual from the button (un-staged)
489 * If the derived button does not want the visual removed then use this virtual function to
490 * define the required behaviour.
491 * Can decide to only remove specified visuals via index
493 virtual void OnButtonVisualRemoval(Property::Index visualIndex);
497 * Removes the visual from the button and prepares it to be transitioned out
498 * @param[in] visualIndex the visual to remove
500 void RemoveVisual(Property::Index visualIndex);
503 * Adds the required visual to the button.
504 * @param[in] visualIndex The Property index of the visual required
506 void SelectRequiredVisual(Property::Index visualIndex);
509 Button(const Button&);
512 Button& operator=(const Button&);
516 Toolkit::Button::ButtonSignalType mPressedSignal; ///< Signal emitted when the button is pressed.
517 Toolkit::Button::ButtonSignalType mReleasedSignal; ///< Signal emitted when the button is released.
518 Toolkit::Button::ButtonSignalType mClickedSignal; ///< Signal emitted when the button is clicked.
519 Toolkit::Button::ButtonSignalType mStateChangedSignal; ///< Signal emitted when the button's state is changed.
521 Timer mAutoRepeatingTimer;
523 Actor mLabel; ///< Stores the button text label.
524 Padding mLabelPadding; ///< The padding around the label (if present).
525 Padding mForegroundPadding; ///< The padding around the foreground/icon visual (if present).
527 Align mTextLabelAlignment; ///< Position of text label in relation to foreground/icon when both are present.
529 TapGestureDetector mTapDetector;
531 bool mAutoRepeating; ///< Stores the autorepeating property.
532 bool mTogglableButton; ///< Stores the togglable property as a flag.
533 bool mTextStringSetFlag; ///< Stores if text has been set. Required in relayout but don't want to calculate there.
535 float mInitialAutoRepeatingDelay; ///< Stores the initial autorepeating delay in seconds.
536 float mNextAutoRepeatingDelay; ///< Stores the next autorepeating delay in seconds.
538 float mAnimationTime;
540 PressState mButtonPressedState; ///< In relation to the button being pressed/released
542 State mPreviousButtonState; ///< During a transition between two states, this stores the previous state so Visuals can be removed.
545 bool mClickActionPerforming; ///< Used to manage signal emissions during action
548 class ButtonAccessible : public DevelControl::ControlAccessible
551 using DevelControl::ControlAccessible::ControlAccessible;
554 * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::CalculateStates()
556 Dali::Accessibility::States CalculateStates() override;
559 * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNameRaw()
561 std::string GetNameRaw() const override;
564 * @copydoc Dali::Toolkit::DevelControl::ControlAccessible::GetNamePropertyIndex()
566 Property::Index GetNamePropertyIndex() override;
570 } // namespace Internal
572 // Helpers for public-api forwarding methods
574 inline Toolkit::Internal::Button& GetImplementation(Toolkit::Button& button)
576 DALI_ASSERT_ALWAYS(button);
578 Dali::RefObject& handle = button.GetImplementation();
580 return static_cast<Toolkit::Internal::Button&>(handle);
583 inline const Toolkit::Internal::Button& GetImplementation(const Toolkit::Button& button)
585 DALI_ASSERT_ALWAYS(button);
587 const Dali::RefObject& handle = button.GetImplementation();
589 return static_cast<const Toolkit::Internal::Button&>(handle);
592 } // namespace Toolkit
596 #endif // DALI_TOOLKIT_INTERNAL_BUTTON_H