2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "button-impl.h"
22 #include <cstring> // for strcmp
23 #include <dali/public-api/events/touch-event.h>
24 #include <dali/public-api/images/resource-image.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/devel-api/object/type-registry-helper.h>
27 #include <dali/devel-api/scripting/scripting.h>
30 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
31 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
34 * Button states and contents
35 * (3) mSelectedContent
36 * (2) mUnselectedContent (2) mSelectedBackgroundContent
37 * (1) mBackgroundContent (1) mBackgroundContent
38 * < unselected > ----------------------- < selected >
40 * | OnDisabled() | OnDisabled()
42 * < disabled > < disabled-selected >
43 * (2) mDisabledContent (2) mDisabledSelectedContent
44 * (1) mDisabledBackgroundContent (1) mDisabledBackgroundContent
46 * The drawing order of child actors is as follows.
49 * | mUnselectedContent / mSelectedContent / mDisabledContent / mDisabledSelectedContent
50 * | mSelectedBackgroundContent
51 * Bottom mBackgroundContent / mDisabledBackgroundContent
53 * Some of contents may be missed.
54 * And 2 images - fade-in image and fade-out image - in the same layer can be shown during the transition animation. Fade-in image should be above fade-out image.
71 // empty handle as we cannot create button (but type registered for clicked signal)
75 // Setup properties, signals and actions using the type-registry.
76 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create );
78 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", STRING, UNSELECTED_STATE_IMAGE )
85 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", STRING, SELECTED_STATE_IMAGE )
86 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", STRING, DISABLED_STATE_IMAGE )
87 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR )
88 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR )
89 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
91 // Deprecated properties:
92 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT )
95 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
96 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
97 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
101 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
103 DALI_TYPE_REGISTRATION_END()
105 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
106 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
108 } // unnamed namespace
111 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
112 mAutoRepeatingTimer(),
113 mUnselectedColor( Color::WHITE ), // The natural colors of the specified images will be used by default.
114 mSelectedColor( Color::WHITE ),
116 mAutoRepeating( false ),
117 mTogglableButton( false ),
119 mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
120 mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
121 mAnimationTime( 0.0f ),
122 mClickActionPerforming( false ),
124 mPaintState( UnselectedState )
132 void Button::SetDisabled( bool disabled )
134 if( disabled == mDisabled )
139 StopTransitionAnimation();
141 mDisabled = disabled;
143 // Notifies the derived class the button has been disabled.
146 switch( mPaintState )
148 case UnselectedState:
151 //(3) mDisabledContent (Inserted)
152 //(4) mUnselectedContent
153 //(2) mDisabledBackgroundContent (Inserted)
154 //(1) mBackgroundContent
156 AddButtonImage( mBackgroundContent );
157 TransitionButtonImage( mDisabledBackgroundContent );
158 AddButtonImage( mUnselectedContent );
159 TransitionButtonImage( mDisabledContent );
161 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
164 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
165 TransitionOut( mUnselectedContent );
166 TransitionOut( mSelectedContent );
167 TransitionOut( mBackgroundContent );
168 TransitionOut( mSelectedBackgroundContent );
169 TransitionOut( mDisabledSelectedContent );
171 mPaintState = DisabledUnselectedState;
177 //(5) mDisabledSelectedContent (Inserted)
178 //(4) mSelectedContent
179 //(3) mDisabledBackgroundContent (Inserted)
180 //(2) mSelectedBackgroundContent
181 //(1) mBackgroundContent
183 AddButtonImage( mBackgroundContent );
184 AddButtonImage( mSelectedBackgroundContent );
185 TransitionButtonImage( mDisabledBackgroundContent );
186 AddButtonImage( mSelectedContent );
187 TransitionButtonImage( mDisabledSelectedContent );
189 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
192 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
193 TransitionOut( mUnselectedContent );
194 TransitionOut( mSelectedContent );
195 TransitionOut( mBackgroundContent );
196 TransitionOut( mSelectedBackgroundContent );
197 TransitionOut( mDisabledContent );
199 mPaintState = DisabledSelectedState;
202 case DisabledUnselectedState:
205 //(3) mUnselectedContent (Inserted)
206 //(4) mDisabledContent
207 //(2) mBackgroundContent (Inserted)
208 //(1) mDisabledBackgroundContent
210 AddButtonImage( mDisabledBackgroundContent );
211 TransitionButtonImage( mBackgroundContent );
212 AddButtonImage( mDisabledContent );
213 TransitionButtonImage( mUnselectedContent );
215 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
218 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
219 TransitionOut( mSelectedContent );
220 TransitionOut( mSelectedBackgroundContent );
221 TransitionOut( mDisabledContent );
222 TransitionOut( mDisabledSelectedContent );
223 TransitionOut( mDisabledBackgroundContent );
225 mPaintState = UnselectedState;
228 case DisabledSelectedState:
231 //(4) mSelectedContent (Inserted)
232 //(5) mDisabledSelectedContent
233 //(3) mSelectedBackgroundContent (Inserted)
234 //(2) mBackgroundContent (Inserted)
235 //(1) mDisabledBackgroundContent
237 AddButtonImage( mDisabledBackgroundContent );
238 TransitionButtonImage( mBackgroundContent );
239 TransitionButtonImage( mSelectedBackgroundContent );
240 AddButtonImage( mDisabledSelectedContent );
241 TransitionButtonImage( mSelectedContent );
243 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
246 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
247 TransitionOut( mUnselectedContent );
248 TransitionOut( mDisabledContent );
249 TransitionOut( mDisabledSelectedContent );
250 TransitionOut( mDisabledBackgroundContent );
252 mPaintState = SelectedState;
257 StartTransitionAnimation();
260 bool Button::IsDisabled() const
265 void Button::SetAutoRepeating( bool autoRepeating )
267 mAutoRepeating = autoRepeating;
269 // An autorepeating button can't be a togglable button.
272 mTogglableButton = false;
276 // Emit a signal is not wanted, only change the appearance.
277 SetSelected( false, false );
282 bool Button::IsAutoRepeating() const
284 return mAutoRepeating;
287 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
289 DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
290 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
293 float Button::GetInitialAutoRepeatingDelay() const
295 return mInitialAutoRepeatingDelay;
298 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
300 DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
301 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
304 float Button::GetNextAutoRepeatingDelay() const
306 return mNextAutoRepeatingDelay;
309 void Button::SetTogglableButton( bool togglable )
311 mTogglableButton = togglable;
313 // A togglable button can't be an autorepeating button.
316 mAutoRepeating = false;
320 bool Button::IsTogglableButton() const
322 return mTogglableButton;
325 void Button::SetSelected( bool selected )
327 if( !mDisabled && mTogglableButton && ( selected != mSelected ) )
329 SetSelected( selected, true );
333 void Button::SetSelected( bool selected, bool emitSignal )
335 StopTransitionAnimation();
337 mSelected = selected;
339 // Notifies the derived class the button has been selected.
342 switch( mPaintState )
344 case UnselectedState:
347 //(3) mSelectedContent (Inserted)
348 //(4) mUnselectedContent
349 //(2) mSelectedBackgroundContent (Inserted)
350 //(1) mBackgroundContent
352 AddButtonImage( mBackgroundContent );
353 TransitionButtonImage( mSelectedBackgroundContent );
354 AddButtonImage( mUnselectedContent );
355 TransitionButtonImage( mSelectedContent );
357 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
358 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
361 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
362 TransitionOut( mUnselectedContent );
363 TransitionOut( mDisabledContent );
364 TransitionOut( mDisabledSelectedContent );
365 TransitionOut( mDisabledBackgroundContent );
367 mPaintState = SelectedState;
373 //(3) mUnselectedContent (Inserted)
374 //(2) mSelectedContent
375 //(1) mBackgroundContent
377 AddButtonImage( mBackgroundContent );
378 AddButtonImage( mSelectedContent );
379 TransitionButtonImage( mUnselectedContent );
381 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
382 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
385 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
386 TransitionOut( mSelectedContent );
387 TransitionOut( mSelectedBackgroundContent );
388 TransitionOut( mDisabledContent );
389 TransitionOut( mDisabledSelectedContent );
390 TransitionOut( mDisabledBackgroundContent );
392 mPaintState = UnselectedState;
395 case DisabledUnselectedState:
396 case DisabledSelectedState:
398 DALI_ASSERT_DEBUG( 0 && "Shouldn't be able to change paint state if the button is disabled." );
403 StartTransitionAnimation();
407 Toolkit::Button handle( GetOwner() );
410 mStateChangedSignal.Emit( handle );
416 bool Button::IsSelected() const
418 return mTogglableButton && mSelected;
421 void Button::SetAnimationTime( float animationTime )
423 mAnimationTime = animationTime;
426 float Button::GetAnimationTime() const
428 return mAnimationTime;
431 void Button::SetLabelText( const std::string& label )
433 Property::Map labelProperty;
434 labelProperty.Insert( "text", label );
435 ModifyLabel( labelProperty );
438 std::string Button::GetLabelText() const
440 Toolkit::TextLabel label = Dali::Toolkit::TextLabel::DownCast( mLabel );
443 return label.GetProperty<std::string>( Dali::Toolkit::TextLabel::Property::TEXT );
445 return std::string();
448 void Button::ModifyLabel( const Property::Map& properties )
450 // If we don't have a label yet, create one.
453 // If we don't have a label, create one and set it up.
454 // Note: The label text is set from the passed in property map after creation.
455 mLabel = Toolkit::TextLabel::New();
456 mLabel.SetPosition( 0.0f, 0.0f );
457 // label should be the top of the button
458 Self().Add( mLabel );
461 // Set any properties specified for the label by iterating through all property key-value pairs.
462 for( unsigned int i = 0, mapCount = properties.Count(); i < mapCount; ++i )
464 const StringValuePair& propertyPair( properties.GetPair( i ) );
466 // Convert the property string to a property index.
467 Property::Index setPropertyIndex = mLabel.GetPropertyIndex( propertyPair.first );
468 if( setPropertyIndex != Property::INVALID_INDEX )
470 // If the conversion worked, we have a valid property index,
471 // Set the property to the new value.
472 mLabel.SetProperty( setPropertyIndex, propertyPair.second );
476 // Notify derived button classes of the change.
482 Actor& Button::GetLabelActor()
487 void Button::SetDecoration( DecorationState state, Actor actor )
489 if( mDecoration[ state ] && mDecoration[ state ].GetParent() )
491 mDecoration[ state ].Unparent();
494 mDecoration[ state ] = actor;
495 mDecoration[ state ].SetColorMode( USE_OWN_COLOR );
501 Actor& Button::GetDecoration( DecorationState state )
503 return mDecoration[ state ];
506 void Button::SetupContent( Actor& actorToModify, Actor newActor )
510 StopTransitionAnimation();
512 if( actorToModify && actorToModify.GetParent() )
514 actorToModify.Unparent();
517 actorToModify = newActor;
521 actorToModify.SetAnchorPoint( AnchorPoint::TOP_LEFT );
522 actorToModify.SetParentOrigin( ParentOrigin::TOP_LEFT );
523 actorToModify.SetPosition( 0.f, 0.f );
530 void Button::SetUnselectedColor( const Vector4& color )
532 mUnselectedColor = color;
534 if( mUnselectedContent && !GetUnselectedImageFilename().empty() )
536 // If there is existing unselected content, change the color on it directly.
537 mUnselectedContent.SetColor( mUnselectedColor );
541 // If there is no existing content, create a new actor to use for flat color.
542 Toolkit::Control unselectedContentActor = Toolkit::Control::New();
543 unselectedContentActor.SetBackgroundColor( mUnselectedColor );
544 SetupContent( mUnselectedContent, unselectedContentActor );
545 mUnselectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
549 const Vector4 Button::GetUnselectedColor() const
551 return mUnselectedColor;
554 void Button::SetSelectedColor( const Vector4& color )
556 mSelectedColor = color;
558 if( mSelectedContent && !GetSelectedImageFilename().empty() )
560 // If there is existing unselected content, change the color on it directly.
561 mSelectedContent.SetColor( mSelectedColor );
565 // If there is no existing content, create a new actor to use for flat color.
566 Toolkit::Control selectedContentActor = Toolkit::Control::New();
567 selectedContentActor.SetBackgroundColor( mSelectedColor );
568 SetupContent( mSelectedContent, selectedContentActor );
569 mSelectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
573 const Vector4 Button::GetSelectedColor() const
575 return mSelectedColor;
578 void Button::SetUnselectedImage( const std::string& filename )
580 Toolkit::ImageView newContent;
581 if( !filename.empty() )
583 newContent = Toolkit::ImageView::New( filename );
587 newContent = Toolkit::ImageView::New();
592 SetupContent( mUnselectedContent, newContent );
594 mUnselectedContent.SetColor( mUnselectedColor );
596 OnUnselectedImageSet();
601 Actor& Button::GetUnselectedImage()
603 return mUnselectedContent;
606 void Button::SetSelectedImage( const std::string& filename )
608 Toolkit::ImageView newContent;
609 if( !filename.empty() )
611 newContent = Toolkit::ImageView::New( filename );
615 newContent = Toolkit::ImageView::New();
620 SetupContent( mSelectedContent, newContent );
622 mSelectedContent.SetColor( mSelectedColor );
624 OnSelectedImageSet();
629 Actor& Button::GetSelectedImage()
631 return mSelectedContent;
634 void Button::SetBackgroundImage( const std::string& filename )
636 SetupContent( mBackgroundContent, Toolkit::ImageView::New( filename ) );
638 OnBackgroundImageSet();
642 Actor& Button::GetBackgroundImage()
644 return mBackgroundContent;
647 void Button::SetSelectedBackgroundImage( const std::string& filename )
649 SetupContent( mSelectedBackgroundContent, Toolkit::ImageView::New( filename ) );
651 OnSelectedBackgroundImageSet();
655 Actor& Button::GetSelectedBackgroundImage()
657 return mSelectedBackgroundContent;
660 void Button::SetDisabledImage( const std::string& filename )
662 SetupContent( mDisabledContent, Toolkit::ImageView::New( filename ) );
664 OnDisabledImageSet();
668 Actor& Button::GetDisabledImage()
670 return mDisabledContent;
673 void Button::SetDisabledSelectedImage( const std::string& filename )
675 SetupContent( mDisabledSelectedContent, Toolkit::ImageView::New( filename ) );
677 OnDisabledSelectedImageSet();
681 Actor& Button::GetDisabledSelectedImage()
683 return mDisabledSelectedContent;
686 void Button::SetDisabledBackgroundImage( const std::string& filename )
688 SetupContent( mDisabledBackgroundContent, Toolkit::ImageView::New( filename ) );
690 OnDisabledBackgroundImageSet();
694 Actor& Button::GetDisabledBackgroundImage()
696 return mDisabledBackgroundContent;
699 std::string Button::GetUnselectedImageFilename() const
701 if( mUnselectedContent )
703 ResourceImage image = ResourceImage::DownCast( mUnselectedContent );
706 return image.GetUrl();
709 return std::string();
712 std::string Button::GetSelectedImageFilename() const
714 if( mSelectedContent )
716 ResourceImage image = ResourceImage::DownCast( mSelectedContent );
719 return image.GetUrl();
722 return std::string();
725 std::string Button::GetBackgroundImageFilename() const
727 if( mBackgroundContent )
729 ResourceImage image = ResourceImage::DownCast( mBackgroundContent );
732 return image.GetUrl();
735 return std::string();
738 std::string Button::GetSelectedBackgroundImageFilename() const
740 if( mSelectedBackgroundContent )
742 ResourceImage image = ResourceImage::DownCast( mSelectedBackgroundContent );
745 return image.GetUrl();
748 return std::string();
751 std::string Button::GetDisabledImageFilename() const
753 if( mDisabledContent )
755 ResourceImage image = ResourceImage::DownCast( mDisabledContent );
758 return image.GetUrl();
761 return std::string();
764 std::string Button::GetDisabledSelectedImageFilename() const
766 if( mDisabledSelectedContent )
768 ResourceImage image = ResourceImage::DownCast( mDisabledSelectedContent );
771 return image.GetUrl();
774 return std::string();
777 std::string Button::GetDisabledBackgroundImageFilename() const
779 if( mDisabledBackgroundContent )
781 ResourceImage image = ResourceImage::DownCast( mDisabledBackgroundContent );
784 return image.GetUrl();
787 return std::string();
790 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
794 Dali::BaseHandle handle( object );
796 Toolkit::Button button = Toolkit::Button::DownCast( handle );
798 DALI_ASSERT_ALWAYS( button );
800 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
802 ret = GetImplementation( button ).DoClickAction( attributes );
808 bool Button::DoClickAction( const Property::Map& attributes )
810 // Prevents the button signals from doing a recursive loop by sending an action
811 // and re-emitting the signals.
812 if( !mClickActionPerforming )
814 mClickActionPerforming = true;
818 mClickActionPerforming = false;
826 void Button::OnButtonStageDisconnection()
828 if( ButtonDown == mState )
830 if( !mTogglableButton )
836 mAutoRepeatingTimer.Reset();
842 void Button::OnButtonDown()
844 if( !mTogglableButton )
850 SetUpTimer( mInitialAutoRepeatingDelay );
854 // The pressed signal should be emitted regardless of toggle mode.
855 Toolkit::Button handle( GetOwner() );
856 mPressedSignal.Emit( handle );
859 void Button::OnButtonUp()
861 if( ButtonDown == mState )
863 if( mTogglableButton )
865 SetSelected( !mSelected );
873 mAutoRepeatingTimer.Reset();
877 // The clicked and released signals should be emitted regardless of toggle mode.
878 Toolkit::Button handle( GetOwner() );
879 mReleasedSignal.Emit( handle );
880 mClickedSignal.Emit( handle );
884 void Button::OnTouchPointLeave()
886 if( ButtonDown == mState )
888 if( !mTogglableButton )
894 mAutoRepeatingTimer.Reset();
898 // The released signal should be emitted regardless of toggle mode.
899 Toolkit::Button handle( GetOwner() );
900 mReleasedSignal.Emit( handle );
904 void Button::OnTouchPointInterrupted()
909 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
911 return mPressedSignal;
914 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
916 return mReleasedSignal;
919 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
921 return mClickedSignal;
924 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
926 return mStateChangedSignal;
929 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
931 Dali::BaseHandle handle( object );
933 bool connected( true );
934 Toolkit::Button button = Toolkit::Button::DownCast( handle );
936 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
938 button.PressedSignal().Connect( tracker, functor );
940 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
942 button.ReleasedSignal().Connect( tracker, functor );
944 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
946 button.ClickedSignal().Connect( tracker, functor );
948 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
950 button.StateChangedSignal().Connect( tracker, functor );
954 // signalName does not match any signal
961 bool Button::OnTouchEvent(const TouchEvent& event)
963 // Only events are processed when the button is not disabled and the touch event has only
965 if( ( !mDisabled ) && ( 1 == event.GetPointCount() ) )
967 switch( event.GetPoint(0).state )
969 case TouchPoint::Down:
971 OnButtonDown(); // Notification for derived classes.
973 // Sets the button state to ButtonDown.
979 OnButtonUp(); // Notification for derived classes.
981 // Sets the button state to ButtonUp.
985 case TouchPoint::Interrupted:
987 OnTouchPointInterrupted(); // Notification for derived classes.
989 // Sets the button state to the default (ButtonUp).
993 case TouchPoint::Leave:
995 OnTouchPointLeave(); // Notification for derived classes.
997 // Sets the button state to the default (ButtonUp).
1001 case TouchPoint::Motion:
1002 case TouchPoint::Stationary: // FALLTHROUGH
1009 DALI_ASSERT_ALWAYS( !"Point status unhandled." );
1014 else if( 1 < event.GetPointCount() )
1016 OnTouchPointLeave(); // Notification for derived classes.
1018 // Sets the button state to the default (ButtonUp).
1025 void Button::OnInitialize()
1027 Actor self = Self();
1029 mTapDetector = TapGestureDetector::New();
1030 mTapDetector.Attach( self );
1031 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
1033 OnButtonInitialize();
1035 self.SetKeyboardFocusable( true );
1038 bool Button::OnAccessibilityActivated()
1040 return OnKeyboardEnter();
1043 bool Button::OnKeyboardEnter()
1045 // When the enter key is pressed, or button is activated, the click action is performed.
1046 Property::Map attributes;
1047 bool ret = DoClickAction( attributes );
1052 void Button::OnStageDisconnection()
1054 OnButtonStageDisconnection(); // Notification for derived classes.
1057 Control::OnStageDisconnection();
1060 void Button::OnTap(Actor actor, const TapGesture& tap)
1065 void Button::SetUpTimer( float delay )
1067 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1068 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1069 mAutoRepeatingTimer.Start();
1072 bool Button::AutoRepeatingSlot()
1074 bool consumed = false;
1077 // Restart the autorepeat timer.
1078 SetUpTimer( mNextAutoRepeatingDelay );
1082 Toolkit::Button handle( GetOwner() );
1085 consumed = mReleasedSignal.Emit( handle );
1086 consumed |= mClickedSignal.Emit( handle );
1087 consumed |= mPressedSignal.Emit( handle );
1093 void Button::Pressed()
1095 if( mPaintState == UnselectedState )
1097 StopTransitionAnimation();
1099 // Notifies the derived class the button has been pressed.
1103 //(4) mSelectedContent (Inserted)
1104 //(3) mUnselectedContent
1105 //(2) mSelectedBackgroundContent (Inserted)
1106 //(1) mBackgroundContent
1108 AddButtonImage( mBackgroundContent );
1109 TransitionButtonImage( mSelectedBackgroundContent );
1110 AddButtonImage( mUnselectedContent );
1111 TransitionButtonImage( mSelectedContent );
1113 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1114 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
1117 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
1118 TransitionOut( mUnselectedContent );
1119 TransitionOut( mDisabledContent );
1120 TransitionOut( mDisabledSelectedContent );
1121 TransitionOut( mDisabledBackgroundContent );
1123 mPaintState = SelectedState;
1125 StartTransitionAnimation();
1129 void Button::Released()
1131 if( mPaintState == SelectedState )
1133 StopTransitionAnimation();
1135 // Notifies the derived class the button has been released.
1139 //(3) mUnselectedContent (Inserted)
1140 //(2) mSelectedContent
1141 //(1) mBackgroundContent
1143 AddButtonImage( mBackgroundContent );
1144 AddButtonImage( mSelectedContent );
1145 TransitionButtonImage( mUnselectedContent );
1147 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1148 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1151 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
1152 TransitionOut( mSelectedContent );
1153 TransitionOut( mSelectedBackgroundContent );
1154 TransitionOut( mDisabledContent );
1155 TransitionOut( mDisabledSelectedContent );
1156 TransitionOut( mDisabledBackgroundContent );
1158 mPaintState = UnselectedState;
1160 StartTransitionAnimation();
1164 Button::ButtonState Button::GetState()
1169 Button::PaintState Button::GetPaintState()
1174 void Button::PrepareAddButtonImage( Actor& actor )
1178 Self().Add( actor );
1179 PrepareForTranstionOut( actor );
1183 void Button::TransitionButtonImage( Actor& actor )
1187 if( !actor.GetParent() )
1189 Self().Add( actor );
1192 OnTransitionIn( actor );
1196 void Button::AddButtonImage( Actor& actor )
1200 Self().Add( actor );
1204 void Button::ReAddLabel()
1209 Self().Add( mLabel );
1213 void Button::RemoveButtonImage( Actor& actor )
1217 if( actor.GetParent() )
1219 Self().Remove( actor );
1221 PrepareForTranstionIn( actor );
1225 unsigned int Button::FindChildIndex( Actor& actor )
1227 Actor self = Self();
1228 unsigned int childrenNum = self.GetChildCount();
1230 for( unsigned int i = 0; i < childrenNum; i++ )
1232 Actor child = self.GetChildAt( i );
1233 if( child == actor )
1242 void Button::TransitionOut( Actor actor )
1244 OnTransitionOut( actor );
1247 void Button::ResetImageLayers()
1249 // Ensure that all layers are in the correct order and state according to the paint state
1251 switch( mPaintState )
1253 case UnselectedState:
1256 //(2) mUnselectedContent
1257 //(1) mBackgroundContent
1259 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1260 RemoveButtonImage( mSelectedContent );
1261 RemoveButtonImage( mSelectedBackgroundContent );
1262 RemoveButtonImage( mDisabledContent );
1263 RemoveButtonImage( mDisabledSelectedContent );
1264 RemoveButtonImage( mDisabledBackgroundContent );
1266 PrepareAddButtonImage( mBackgroundContent );
1267 PrepareAddButtonImage( mUnselectedContent );
1269 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1276 //(3) mSelectedContent
1277 //(2) mSelectedBackgroundContent
1278 //(1) mBackgroundContent
1280 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1281 RemoveButtonImage( mUnselectedContent );
1282 RemoveButtonImage( mDisabledContent );
1283 RemoveButtonImage( mDisabledSelectedContent );
1284 RemoveButtonImage( mDisabledBackgroundContent );
1286 PrepareAddButtonImage( mBackgroundContent );
1287 PrepareAddButtonImage( mSelectedBackgroundContent );
1288 PrepareAddButtonImage( mSelectedContent );
1290 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1294 case DisabledUnselectedState:
1297 //(2) mDisabledContent
1298 //(1) mDisabledBackgroundContent
1300 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1301 RemoveButtonImage( mUnselectedContent );
1302 RemoveButtonImage( mBackgroundContent );
1303 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1304 RemoveButtonImage( mSelectedContent );
1305 RemoveButtonImage( mDisabledSelectedContent );
1306 RemoveButtonImage( mSelectedBackgroundContent );
1308 PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
1309 PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
1311 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1315 case DisabledSelectedState:
1318 // (2) mDisabledSelectedContent
1319 // (1) mDisabledBackgroundContent
1321 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1322 RemoveButtonImage( mUnselectedContent );
1323 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1324 RemoveButtonImage( mSelectedContent );
1325 RemoveButtonImage( mBackgroundContent );
1326 RemoveButtonImage( mSelectedBackgroundContent );
1327 RemoveButtonImage( mDisabledContent );
1329 if( mDisabledBackgroundContent )
1331 PrepareAddButtonImage( mDisabledBackgroundContent );
1335 PrepareAddButtonImage( mBackgroundContent );
1336 PrepareAddButtonImage( mSelectedBackgroundContent );
1339 PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
1341 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1348 void Button::StartTransitionAnimation()
1350 if( mTransitionAnimation )
1352 mTransitionAnimation.Play();
1360 void Button::StopTransitionAnimation()
1362 if( mTransitionAnimation )
1364 mTransitionAnimation.Clear();
1365 mTransitionAnimation.Reset();
1369 Dali::Animation Button::GetTransitionAnimation()
1371 if( !mTransitionAnimation )
1373 mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1374 mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1377 return mTransitionAnimation;
1380 void Button::TransitionAnimationFinished( Dali::Animation& source )
1382 StopTransitionAnimation();
1386 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1388 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1394 case Toolkit::Button::Property::DISABLED:
1396 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1400 case Toolkit::Button::Property::AUTO_REPEATING:
1402 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1406 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1408 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1412 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1414 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1418 case Toolkit::Button::Property::TOGGLABLE:
1420 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1424 case Toolkit::Button::Property::SELECTED:
1426 GetImplementation( button ).SetSelected( value.Get< bool >() );
1430 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1432 GetImplementation( button ).SetUnselectedImage( value.Get< std::string >() );
1436 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1438 GetImplementation( button ).SetSelectedImage( value.Get< std::string >() );
1442 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1444 GetImplementation( button ).SetDisabledImage( value.Get< std::string >() );
1448 case Toolkit::Button::Property::UNSELECTED_COLOR:
1450 GetImplementation( button ).SetUnselectedColor( value.Get< Vector4 >() );
1454 case Toolkit::Button::Property::SELECTED_COLOR:
1456 GetImplementation( button ).SetSelectedColor( value.Get< Vector4 >() );
1460 case Toolkit::Button::Property::LABEL_TEXT:
1462 GetImplementation( button ).SetLabelText( value.Get< std::string >() );
1466 case Toolkit::Button::Property::LABEL:
1468 // Get a Property::Map from the property if possible.
1469 Property::Map setPropertyMap;
1470 if( value.Get( setPropertyMap ) )
1472 GetImplementation( button ).ModifyLabel( setPropertyMap );
1480 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1482 Property::Value value;
1484 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1488 switch ( propertyIndex )
1490 case Toolkit::Button::Property::DISABLED:
1492 value = GetImplementation( button ).mDisabled;
1496 case Toolkit::Button::Property::AUTO_REPEATING:
1498 value = GetImplementation( button ).mAutoRepeating;
1502 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1504 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1508 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1510 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1514 case Toolkit::Button::Property::TOGGLABLE:
1516 value = GetImplementation( button ).mTogglableButton;
1520 case Toolkit::Button::Property::SELECTED:
1522 value = GetImplementation( button ).mSelected;
1526 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1528 value = GetImplementation( button ).GetUnselectedImageFilename();
1532 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1534 value = GetImplementation( button ).GetSelectedImageFilename();
1538 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1540 value = GetImplementation( button ).GetDisabledImageFilename();
1544 case Toolkit::Button::Property::UNSELECTED_COLOR:
1546 value = GetImplementation( button ).GetUnselectedColor();
1550 case Toolkit::Button::Property::SELECTED_COLOR:
1552 value = GetImplementation( button ).GetSelectedColor();
1556 case Toolkit::Button::Property::LABEL_TEXT:
1558 value = GetImplementation( button ).GetLabelText();
1562 case Toolkit::Button::Property::LABEL:
1564 Property::Map emptyMap;
1576 void Button::SetLabel( Actor label )
1578 if( mLabel != label )
1580 if( mLabel && mLabel.GetParent() )
1582 mLabel.GetParent().Remove( mLabel );
1586 mLabel.SetPosition( 0.0f, 0.0f );
1588 // label should be the top of the button
1589 Self().Add( mLabel );
1598 void Button::SetButtonImage( Actor image )
1602 StopTransitionAnimation();
1604 SetupContent( mUnselectedContent, image );
1606 OnUnselectedImageSet();
1611 void Button::SetSelectedImage( Actor image )
1615 StopTransitionAnimation();
1617 SetupContent( mSelectedContent, image );
1619 OnSelectedImageSet();
1624 void Button::SetBackgroundImage( Actor image )
1628 StopTransitionAnimation();
1630 SetupContent( mBackgroundContent, image );
1632 OnBackgroundImageSet();
1637 void Button::SetSelectedBackgroundImage( Actor image )
1641 StopTransitionAnimation();
1643 SetupContent( mSelectedBackgroundContent, image );
1645 OnSelectedBackgroundImageSet();
1650 void Button::SetDisabledImage( Actor image )
1654 StopTransitionAnimation();
1656 SetupContent( mDisabledContent, image );
1658 OnDisabledImageSet();
1663 void Button::SetDisabledSelectedImage( Actor image )
1667 StopTransitionAnimation();
1669 SetupContent( mDisabledSelectedContent, image );
1671 OnDisabledSelectedImageSet();
1676 void Button::SetDisabledBackgroundImage( Actor image )
1680 StopTransitionAnimation();
1682 SetupContent( mDisabledBackgroundContent, image );
1684 OnDisabledBackgroundImageSet();
1689 Actor Button::GetButtonImage() const
1691 return mUnselectedContent;
1694 Actor Button::GetSelectedImage() const
1696 return mSelectedContent;
1700 } // namespace Internal
1702 } // namespace Toolkit