2 * Copyright (c) 2016 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-data.h>
24 #include <dali/public-api/images/resource-image.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/public-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>
32 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
33 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
37 * Button states and contents
38 * (3) mSelectedContent
39 * (2) mUnselectedContent (2) mSelectedBackgroundContent
40 * (1) mBackgroundContent (1) mBackgroundContent
41 * < unselected > ----------------------- < selected >
43 * | OnDisabled() | OnDisabled()
45 * < disabled > < disabled-selected >
46 * (2) mDisabledContent (2) mDisabledSelectedContent
47 * (1) mDisabledBackgroundContent (1) mDisabledBackgroundContent
49 * The drawing order of child actors is as follows.
52 * | mUnselectedContent / mSelectedContent / mDisabledContent / mDisabledSelectedContent
53 * | mSelectedBackgroundContent
54 * Bottom mBackgroundContent / mDisabledBackgroundContent
56 * Some of contents may be missed.
57 * 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.
74 // empty handle as we cannot create button (but type registered for clicked signal)
78 // Setup properties, signals and actions using the type-registry.
79 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create );
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
85 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
86 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
87 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", STRING, UNSELECTED_STATE_IMAGE )
88 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", STRING, SELECTED_STATE_IMAGE )
89 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", STRING, DISABLED_STATE_IMAGE )
90 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR )
91 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR )
92 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
94 // Deprecated properties:
95 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
100 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
101 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
104 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
106 DALI_TYPE_REGISTRATION_END()
108 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
109 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
111 } // unnamed namespace
114 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
115 mAutoRepeatingTimer(),
116 mUnselectedColor( Color::WHITE ), // The natural colors of the specified images will be used by default.
117 mSelectedColor( Color::WHITE ),
119 mAutoRepeating( false ),
120 mTogglableButton( false ),
122 mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
123 mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
124 mAnimationTime( 0.0f ),
125 mClickActionPerforming( false ),
127 mPaintState( UnselectedState )
135 void Button::SetDisabled( bool disabled )
137 if( disabled == mDisabled )
142 StopTransitionAnimation();
144 mDisabled = disabled;
146 // Notifies the derived class the button has been disabled.
149 switch( mPaintState )
151 case UnselectedState:
154 //(3) mDisabledContent (Inserted)
155 //(4) mUnselectedContent
156 //(2) mDisabledBackgroundContent (Inserted)
157 //(1) mBackgroundContent
159 AddButtonImage( mBackgroundContent );
160 TransitionButtonImage( mDisabledBackgroundContent );
161 AddButtonImage( mUnselectedContent );
162 TransitionButtonImage( mDisabledContent );
164 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
167 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
168 TransitionOut( mUnselectedContent );
169 TransitionOut( mSelectedContent );
170 TransitionOut( mBackgroundContent );
171 TransitionOut( mSelectedBackgroundContent );
172 TransitionOut( mDisabledSelectedContent );
174 mPaintState = DisabledUnselectedState;
180 //(5) mDisabledSelectedContent (Inserted)
181 //(4) mSelectedContent
182 //(3) mDisabledBackgroundContent (Inserted)
183 //(2) mSelectedBackgroundContent
184 //(1) mBackgroundContent
186 AddButtonImage( mBackgroundContent );
187 AddButtonImage( mSelectedBackgroundContent );
188 TransitionButtonImage( mDisabledBackgroundContent );
189 AddButtonImage( mSelectedContent );
190 TransitionButtonImage( mDisabledSelectedContent );
192 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
195 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
196 TransitionOut( mUnselectedContent );
197 TransitionOut( mSelectedContent );
198 TransitionOut( mBackgroundContent );
199 TransitionOut( mSelectedBackgroundContent );
200 TransitionOut( mDisabledContent );
202 mPaintState = DisabledSelectedState;
205 case DisabledUnselectedState:
208 //(3) mUnselectedContent (Inserted)
209 //(4) mDisabledContent
210 //(2) mBackgroundContent (Inserted)
211 //(1) mDisabledBackgroundContent
213 AddButtonImage( mDisabledBackgroundContent );
214 TransitionButtonImage( mBackgroundContent );
215 AddButtonImage( mDisabledContent );
216 TransitionButtonImage( mUnselectedContent );
218 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
221 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
222 TransitionOut( mSelectedContent );
223 TransitionOut( mSelectedBackgroundContent );
224 TransitionOut( mDisabledContent );
225 TransitionOut( mDisabledSelectedContent );
226 TransitionOut( mDisabledBackgroundContent );
228 mPaintState = UnselectedState;
231 case DisabledSelectedState:
234 //(4) mSelectedContent (Inserted)
235 //(5) mDisabledSelectedContent
236 //(3) mSelectedBackgroundContent (Inserted)
237 //(2) mBackgroundContent (Inserted)
238 //(1) mDisabledBackgroundContent
240 AddButtonImage( mDisabledBackgroundContent );
241 TransitionButtonImage( mBackgroundContent );
242 TransitionButtonImage( mSelectedBackgroundContent );
243 AddButtonImage( mDisabledSelectedContent );
244 TransitionButtonImage( mSelectedContent );
246 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
249 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
250 TransitionOut( mUnselectedContent );
251 TransitionOut( mDisabledContent );
252 TransitionOut( mDisabledSelectedContent );
253 TransitionOut( mDisabledBackgroundContent );
255 mPaintState = SelectedState;
260 StartTransitionAnimation();
263 bool Button::IsDisabled() const
268 void Button::SetAutoRepeating( bool autoRepeating )
270 mAutoRepeating = autoRepeating;
272 // An autorepeating button can't be a togglable button.
275 mTogglableButton = false;
279 // Emit a signal is not wanted, only change the appearance.
280 SetSelected( false, false );
285 bool Button::IsAutoRepeating() const
287 return mAutoRepeating;
290 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
292 DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
293 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
296 float Button::GetInitialAutoRepeatingDelay() const
298 return mInitialAutoRepeatingDelay;
301 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
303 DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
304 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
307 float Button::GetNextAutoRepeatingDelay() const
309 return mNextAutoRepeatingDelay;
312 void Button::SetTogglableButton( bool togglable )
314 mTogglableButton = togglable;
316 // A togglable button can't be an autorepeating button.
319 mAutoRepeating = false;
323 bool Button::IsTogglableButton() const
325 return mTogglableButton;
328 void Button::SetSelected( bool selected )
330 if( !mDisabled && mTogglableButton && ( selected != mSelected ) )
332 SetSelected( selected, true );
336 void Button::SetSelected( bool selected, bool emitSignal )
338 StopTransitionAnimation();
340 mSelected = selected;
342 // Notifies the derived class the button has been selected.
345 switch( mPaintState )
347 case UnselectedState:
350 //(3) mSelectedContent (Inserted)
351 //(4) mUnselectedContent
352 //(2) mSelectedBackgroundContent (Inserted)
353 //(1) mBackgroundContent
355 AddButtonImage( mBackgroundContent );
356 TransitionButtonImage( mSelectedBackgroundContent );
357 AddButtonImage( mUnselectedContent );
358 TransitionButtonImage( mSelectedContent );
360 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
361 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
364 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
365 TransitionOut( mUnselectedContent );
366 TransitionOut( mDisabledContent );
367 TransitionOut( mDisabledSelectedContent );
368 TransitionOut( mDisabledBackgroundContent );
370 mPaintState = SelectedState;
376 //(3) mUnselectedContent (Inserted)
377 //(2) mSelectedContent
378 //(1) mBackgroundContent
380 AddButtonImage( mBackgroundContent );
381 AddButtonImage( mSelectedContent );
382 TransitionButtonImage( mUnselectedContent );
384 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
385 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
388 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
389 TransitionOut( mSelectedContent );
390 TransitionOut( mSelectedBackgroundContent );
391 TransitionOut( mDisabledContent );
392 TransitionOut( mDisabledSelectedContent );
393 TransitionOut( mDisabledBackgroundContent );
395 mPaintState = UnselectedState;
398 case DisabledUnselectedState:
399 case DisabledSelectedState:
401 DALI_ASSERT_DEBUG( 0 && "Shouldn't be able to change paint state if the button is disabled." );
406 StartTransitionAnimation();
410 Toolkit::Button handle( GetOwner() );
413 mStateChangedSignal.Emit( handle );
419 bool Button::IsSelected() const
421 return mTogglableButton && mSelected;
424 void Button::SetAnimationTime( float animationTime )
426 mAnimationTime = animationTime;
429 float Button::GetAnimationTime() const
431 return mAnimationTime;
434 void Button::SetLabelText( const std::string& label )
436 Property::Map labelProperty;
437 labelProperty.Insert( "text", label );
438 ModifyLabel( labelProperty );
441 std::string Button::GetLabelText() const
443 Toolkit::TextLabel label = Dali::Toolkit::TextLabel::DownCast( mLabel );
446 return label.GetProperty<std::string>( Dali::Toolkit::TextLabel::Property::TEXT );
448 return std::string();
451 void Button::ModifyLabel( const Property::Map& properties )
453 // If we don't have a label yet, create one.
456 // If we don't have a label, create one and set it up.
457 // Note: The label text is set from the passed in property map after creation.
458 mLabel = Toolkit::TextLabel::New();
459 mLabel.SetPosition( 0.0f, 0.0f );
460 // label should be the top of the button
461 Self().Add( mLabel );
464 // Set any properties specified for the label by iterating through all property key-value pairs.
465 for( unsigned int i = 0, mapCount = properties.Count(); i < mapCount; ++i )
467 const StringValuePair& propertyPair( properties.GetPair( i ) );
469 // Convert the property string to a property index.
470 Property::Index setPropertyIndex = mLabel.GetPropertyIndex( propertyPair.first );
471 if( setPropertyIndex != Property::INVALID_INDEX )
473 // If the conversion worked, we have a valid property index,
474 // Set the property to the new value.
475 mLabel.SetProperty( setPropertyIndex, propertyPair.second );
479 // Notify derived button classes of the change.
485 Actor& Button::GetLabelActor()
490 void Button::SetDecoration( DecorationState state, Actor actor )
492 if( mDecoration[ state ] && mDecoration[ state ].GetParent() )
494 mDecoration[ state ].Unparent();
497 mDecoration[ state ] = actor;
498 mDecoration[ state ].SetColorMode( USE_OWN_COLOR );
504 Actor& Button::GetDecoration( DecorationState state )
506 return mDecoration[ state ];
509 void Button::SetupContent( Actor& actorToModify, Actor newActor )
513 StopTransitionAnimation();
515 if( actorToModify && actorToModify.GetParent() )
517 actorToModify.Unparent();
520 actorToModify = newActor;
524 actorToModify.SetAnchorPoint( AnchorPoint::TOP_LEFT );
525 actorToModify.SetParentOrigin( ParentOrigin::TOP_LEFT );
526 actorToModify.SetPosition( 0.f, 0.f );
533 const Vector4 Button::GetUnselectedColor() const
535 return mUnselectedColor;
538 void Button::SetColor( const Vector4& color, Button::PaintState selectedState )
540 Actor* contentActor = NULL; // Using a pointer as SetupContent assigns the new Actor to this.
541 bool imageFileExists = false;
542 Property::Index visualIndex = Toolkit::Button::Property::SELECTED_STATE_IMAGE;
544 if ( selectedState == SelectedState || selectedState == DisabledSelectedState )
546 mSelectedColor = color;
547 contentActor = &mSelectedContent;
548 imageFileExists = !GetSelectedImageFilename().empty();
552 mUnselectedColor = color;
553 contentActor = &mUnselectedContent;
554 imageFileExists = !GetUnselectedImageFilename().empty();
555 visualIndex = Toolkit::Button::Property::UNSELECTED_STATE_IMAGE;
560 if( imageFileExists )
562 // If there is existing unselected content, change the color on it directly.
563 contentActor->SetColor( color );
567 // If there is no existing content, create a new actor to use for flat color.
568 Actor placementActor = Actor::New();
569 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
570 Toolkit::Visual::Base visual;
573 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
574 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
576 visual = visualFactory.CreateVisual( map );
578 RegisterVisual( visualIndex, placementActor, visual );
580 SetupContent( *contentActor, placementActor ); //
581 contentActor->SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
586 const Vector4 Button::GetSelectedColor() const
588 return mSelectedColor;
591 void Button::SetUnselectedImage( const std::string& filename )
593 Toolkit::ImageView newContent;
594 if( !filename.empty() )
596 newContent = Toolkit::ImageView::New( filename );
600 newContent = Toolkit::ImageView::New();
605 SetupContent( mUnselectedContent, newContent );
607 mUnselectedContent.SetColor( mUnselectedColor );
609 OnUnselectedImageSet();
614 Actor& Button::GetUnselectedImage()
616 return mUnselectedContent;
619 void Button::SetSelectedImage( const std::string& filename )
621 Toolkit::ImageView newContent;
622 if( !filename.empty() )
624 newContent = Toolkit::ImageView::New( filename );
628 newContent = Toolkit::ImageView::New();
633 SetupContent( mSelectedContent, newContent );
635 mSelectedContent.SetColor( mSelectedColor );
637 OnSelectedImageSet();
642 Actor& Button::GetSelectedImage()
644 return mSelectedContent;
647 void Button::SetBackgroundImage( const std::string& filename )
649 SetupContent( mBackgroundContent, Toolkit::ImageView::New( filename ) );
651 OnBackgroundImageSet();
655 Actor& Button::GetBackgroundImage()
657 return mBackgroundContent;
660 void Button::SetSelectedBackgroundImage( const std::string& filename )
662 SetupContent( mSelectedBackgroundContent, Toolkit::ImageView::New( filename ) );
664 OnSelectedBackgroundImageSet();
668 Actor& Button::GetSelectedBackgroundImage()
670 return mSelectedBackgroundContent;
673 void Button::SetDisabledImage( const std::string& filename )
675 SetupContent( mDisabledContent, Toolkit::ImageView::New( filename ) );
677 OnDisabledImageSet();
681 Actor& Button::GetDisabledImage()
683 return mDisabledContent;
686 void Button::SetDisabledSelectedImage( const std::string& filename )
688 SetupContent( mDisabledSelectedContent, Toolkit::ImageView::New( filename ) );
690 OnDisabledSelectedImageSet();
694 Actor& Button::GetDisabledSelectedImage()
696 return mDisabledSelectedContent;
699 void Button::SetDisabledBackgroundImage( const std::string& filename )
701 SetupContent( mDisabledBackgroundContent, Toolkit::ImageView::New( filename ) );
703 OnDisabledBackgroundImageSet();
707 Actor& Button::GetDisabledBackgroundImage()
709 return mDisabledBackgroundContent;
712 std::string Button::GetUnselectedImageFilename() const
714 if( mUnselectedContent )
716 ResourceImage image = ResourceImage::DownCast( mUnselectedContent );
719 return image.GetUrl();
722 return std::string();
725 std::string Button::GetSelectedImageFilename() const
727 if( mSelectedContent )
729 ResourceImage image = ResourceImage::DownCast( mSelectedContent );
732 return image.GetUrl();
735 return std::string();
738 std::string Button::GetDisabledImageFilename() const
740 if( mDisabledContent )
742 ResourceImage image = ResourceImage::DownCast( mDisabledContent );
745 return image.GetUrl();
748 return std::string();
751 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
755 Dali::BaseHandle handle( object );
757 Toolkit::Button button = Toolkit::Button::DownCast( handle );
759 DALI_ASSERT_ALWAYS( button );
761 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
763 ret = GetImplementation( button ).DoClickAction( attributes );
769 bool Button::DoClickAction( const Property::Map& attributes )
771 // Prevents the button signals from doing a recursive loop by sending an action
772 // and re-emitting the signals.
773 if( !mClickActionPerforming )
775 mClickActionPerforming = true;
779 mClickActionPerforming = false;
787 void Button::OnButtonDown()
789 if( !mTogglableButton )
795 SetUpTimer( mInitialAutoRepeatingDelay );
799 // The pressed signal should be emitted regardless of toggle mode.
800 Toolkit::Button handle( GetOwner() );
801 mPressedSignal.Emit( handle );
804 void Button::OnButtonUp()
806 if( ButtonDown == mState )
808 if( mTogglableButton )
810 SetSelected( !mSelected );
818 mAutoRepeatingTimer.Reset();
822 // The clicked and released signals should be emitted regardless of toggle mode.
823 Toolkit::Button handle( GetOwner() );
824 mReleasedSignal.Emit( handle );
825 mClickedSignal.Emit( handle );
829 void Button::OnTouchPointLeave()
831 if( ButtonDown == mState )
833 if( !mTogglableButton )
839 mAutoRepeatingTimer.Reset();
843 // The released signal should be emitted regardless of toggle mode.
844 Toolkit::Button handle( GetOwner() );
845 mReleasedSignal.Emit( handle );
849 void Button::OnTouchPointInterrupted()
854 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
856 return mPressedSignal;
859 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
861 return mReleasedSignal;
864 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
866 return mClickedSignal;
869 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
871 return mStateChangedSignal;
874 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
876 Dali::BaseHandle handle( object );
878 bool connected( true );
879 Toolkit::Button button = Toolkit::Button::DownCast( handle );
881 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
883 button.PressedSignal().Connect( tracker, functor );
885 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
887 button.ReleasedSignal().Connect( tracker, functor );
889 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
891 button.ClickedSignal().Connect( tracker, functor );
893 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
895 button.StateChangedSignal().Connect( tracker, functor );
899 // signalName does not match any signal
906 void Button::OnInitialize()
910 mTapDetector = TapGestureDetector::New();
911 mTapDetector.Attach( self );
912 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
914 self.SetKeyboardFocusable( true );
916 self.TouchSignal().Connect( this, &Button::OnTouch );
919 bool Button::OnAccessibilityActivated()
921 return OnKeyboardEnter();
924 bool Button::OnKeyboardEnter()
926 // When the enter key is pressed, or button is activated, the click action is performed.
927 Property::Map attributes;
928 bool ret = DoClickAction( attributes );
933 void Button::OnStageDisconnection()
935 if( ButtonDown == mState )
937 if( !mTogglableButton )
943 mAutoRepeatingTimer.Reset();
950 Control::OnStageDisconnection();
953 bool Button::OnTouch( Actor actor, const TouchData& touch )
955 // Only events are processed when the button is not disabled and the touch event has only
957 if( ( !mDisabled ) && ( 1 == touch.GetPointCount() ) )
959 switch( touch.GetState( 0 ) )
961 case PointState::DOWN:
963 OnButtonDown(); // Notification for derived classes.
965 // Sets the button state to ButtonDown.
971 OnButtonUp(); // Notification for derived classes.
973 // Sets the button state to ButtonUp.
977 case PointState::INTERRUPTED:
979 OnTouchPointInterrupted(); // Notification for derived classes.
981 // Sets the button state to the default (ButtonUp).
985 case PointState::LEAVE:
987 OnTouchPointLeave(); // Notification for derived classes.
989 // Sets the button state to the default (ButtonUp).
993 case PointState::MOTION:
994 case PointState::STATIONARY: // FALLTHROUGH
1001 else if( 1 < touch.GetPointCount() )
1003 OnTouchPointLeave(); // Notification for derived classes.
1005 // Sets the button state to the default (ButtonUp).
1012 void Button::OnTap(Actor actor, const TapGesture& tap)
1017 void Button::SetUpTimer( float delay )
1019 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1020 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1021 mAutoRepeatingTimer.Start();
1024 bool Button::AutoRepeatingSlot()
1026 bool consumed = false;
1029 // Restart the autorepeat timer.
1030 SetUpTimer( mNextAutoRepeatingDelay );
1034 Toolkit::Button handle( GetOwner() );
1037 consumed = mReleasedSignal.Emit( handle );
1038 consumed |= mClickedSignal.Emit( handle );
1039 consumed |= mPressedSignal.Emit( handle );
1045 void Button::Pressed()
1047 if( mPaintState == UnselectedState )
1049 StopTransitionAnimation();
1051 // Notifies the derived class the button has been pressed.
1055 //(4) mSelectedContent (Inserted)
1056 //(3) mUnselectedContent
1057 //(2) mSelectedBackgroundContent (Inserted)
1058 //(1) mBackgroundContent
1060 AddButtonImage( mBackgroundContent );
1061 TransitionButtonImage( mSelectedBackgroundContent );
1062 AddButtonImage( mUnselectedContent );
1063 TransitionButtonImage( mSelectedContent );
1065 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1066 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
1069 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
1070 TransitionOut( mUnselectedContent );
1071 TransitionOut( mDisabledContent );
1072 TransitionOut( mDisabledSelectedContent );
1073 TransitionOut( mDisabledBackgroundContent );
1075 mPaintState = SelectedState;
1077 StartTransitionAnimation();
1081 void Button::Released()
1083 if( mPaintState == SelectedState )
1085 StopTransitionAnimation();
1087 // Notifies the derived class the button has been released.
1091 //(3) mUnselectedContent (Inserted)
1092 //(2) mSelectedContent
1093 //(1) mBackgroundContent
1095 AddButtonImage( mBackgroundContent );
1096 AddButtonImage( mSelectedContent );
1097 TransitionButtonImage( mUnselectedContent );
1099 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1100 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1103 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
1104 TransitionOut( mSelectedContent );
1105 TransitionOut( mSelectedBackgroundContent );
1106 TransitionOut( mDisabledContent );
1107 TransitionOut( mDisabledSelectedContent );
1108 TransitionOut( mDisabledBackgroundContent );
1110 mPaintState = UnselectedState;
1112 StartTransitionAnimation();
1116 Button::ButtonState Button::GetState()
1121 Button::PaintState Button::GetPaintState()
1126 void Button::PrepareAddButtonImage( Actor& actor )
1130 Self().Add( actor );
1131 PrepareForTranstionOut( actor );
1135 void Button::TransitionButtonImage( Actor& actor )
1139 if( !actor.GetParent() )
1141 Self().Add( actor );
1144 OnTransitionIn( actor );
1148 void Button::AddButtonImage( Actor& actor )
1152 Self().Add( actor );
1156 void Button::ReAddLabel()
1161 Self().Add( mLabel );
1165 void Button::RemoveButtonImage( Actor& actor )
1169 if( actor.GetParent() )
1171 Self().Remove( actor );
1173 PrepareForTranstionIn( actor );
1177 unsigned int Button::FindChildIndex( Actor& actor )
1179 Actor self = Self();
1180 unsigned int childrenNum = self.GetChildCount();
1182 for( unsigned int i = 0; i < childrenNum; i++ )
1184 Actor child = self.GetChildAt( i );
1185 if( child == actor )
1194 void Button::TransitionOut( Actor actor )
1196 OnTransitionOut( actor );
1199 void Button::ResetImageLayers()
1201 // Ensure that all layers are in the correct order and state according to the paint state
1203 switch( mPaintState )
1205 case UnselectedState:
1208 //(2) mUnselectedContent
1209 //(1) mBackgroundContent
1211 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1212 RemoveButtonImage( mSelectedContent );
1213 RemoveButtonImage( mSelectedBackgroundContent );
1214 RemoveButtonImage( mDisabledContent );
1215 RemoveButtonImage( mDisabledSelectedContent );
1216 RemoveButtonImage( mDisabledBackgroundContent );
1218 PrepareAddButtonImage( mBackgroundContent );
1219 PrepareAddButtonImage( mUnselectedContent );
1221 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1228 //(3) mSelectedContent
1229 //(2) mSelectedBackgroundContent
1230 //(1) mBackgroundContent
1232 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1233 RemoveButtonImage( mUnselectedContent );
1234 RemoveButtonImage( mDisabledContent );
1235 RemoveButtonImage( mDisabledSelectedContent );
1236 RemoveButtonImage( mDisabledBackgroundContent );
1238 PrepareAddButtonImage( mBackgroundContent );
1239 PrepareAddButtonImage( mSelectedBackgroundContent );
1240 PrepareAddButtonImage( mSelectedContent );
1242 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1246 case DisabledUnselectedState:
1249 //(2) mDisabledContent
1250 //(1) mDisabledBackgroundContent
1252 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1253 RemoveButtonImage( mUnselectedContent );
1254 RemoveButtonImage( mBackgroundContent );
1255 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1256 RemoveButtonImage( mSelectedContent );
1257 RemoveButtonImage( mDisabledSelectedContent );
1258 RemoveButtonImage( mSelectedBackgroundContent );
1260 PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
1261 PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
1263 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1267 case DisabledSelectedState:
1270 // (2) mDisabledSelectedContent
1271 // (1) mDisabledBackgroundContent
1273 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1274 RemoveButtonImage( mUnselectedContent );
1275 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1276 RemoveButtonImage( mSelectedContent );
1277 RemoveButtonImage( mBackgroundContent );
1278 RemoveButtonImage( mSelectedBackgroundContent );
1279 RemoveButtonImage( mDisabledContent );
1281 if( mDisabledBackgroundContent )
1283 PrepareAddButtonImage( mDisabledBackgroundContent );
1287 PrepareAddButtonImage( mBackgroundContent );
1288 PrepareAddButtonImage( mSelectedBackgroundContent );
1291 PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
1293 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1300 void Button::StartTransitionAnimation()
1302 if( mTransitionAnimation )
1304 mTransitionAnimation.Play();
1312 void Button::StopTransitionAnimation()
1314 if( mTransitionAnimation )
1316 mTransitionAnimation.Clear();
1317 mTransitionAnimation.Reset();
1321 Dali::Animation Button::GetTransitionAnimation()
1323 if( !mTransitionAnimation )
1325 mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1326 mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1329 return mTransitionAnimation;
1332 void Button::TransitionAnimationFinished( Dali::Animation& source )
1334 StopTransitionAnimation();
1338 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1340 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1346 case Toolkit::Button::Property::DISABLED:
1348 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1352 case Toolkit::Button::Property::AUTO_REPEATING:
1354 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1358 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1360 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1364 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1366 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1370 case Toolkit::Button::Property::TOGGLABLE:
1372 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1376 case Toolkit::Button::Property::SELECTED:
1378 GetImplementation( button ).SetSelected( value.Get< bool >() );
1382 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1384 GetImplementation( button ).SetUnselectedImage( value.Get< std::string >() );
1388 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1390 GetImplementation( button ).SetSelectedImage( value.Get< std::string >() );
1394 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1396 GetImplementation( button ).SetDisabledImage( value.Get< std::string >() );
1400 case Toolkit::Button::Property::UNSELECTED_COLOR:
1402 GetImplementation( button ).SetColor( value.Get< Vector4 >(), UnselectedState );
1406 case Toolkit::Button::Property::SELECTED_COLOR:
1408 GetImplementation( button ).SetColor( value.Get< Vector4 >(), SelectedState );
1412 case Toolkit::Button::Property::LABEL_TEXT:
1414 GetImplementation( button ).SetLabelText( value.Get< std::string >() );
1418 case Toolkit::Button::Property::LABEL:
1420 // Get a Property::Map from the property if possible.
1421 Property::Map setPropertyMap;
1422 if( value.Get( setPropertyMap ) )
1424 GetImplementation( button ).ModifyLabel( setPropertyMap );
1432 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1434 Property::Value value;
1436 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1440 switch ( propertyIndex )
1442 case Toolkit::Button::Property::DISABLED:
1444 value = GetImplementation( button ).mDisabled;
1448 case Toolkit::Button::Property::AUTO_REPEATING:
1450 value = GetImplementation( button ).mAutoRepeating;
1454 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1456 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1460 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1462 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1466 case Toolkit::Button::Property::TOGGLABLE:
1468 value = GetImplementation( button ).mTogglableButton;
1472 case Toolkit::Button::Property::SELECTED:
1474 value = GetImplementation( button ).mSelected;
1478 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1480 value = GetImplementation( button ).GetUnselectedImageFilename();
1484 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1486 value = GetImplementation( button ).GetSelectedImageFilename();
1490 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1492 value = GetImplementation( button ).GetDisabledImageFilename();
1496 case Toolkit::Button::Property::UNSELECTED_COLOR:
1498 value = GetImplementation( button ).GetUnselectedColor();
1502 case Toolkit::Button::Property::SELECTED_COLOR:
1504 value = GetImplementation( button ).GetSelectedColor();
1508 case Toolkit::Button::Property::LABEL_TEXT:
1510 value = GetImplementation( button ).GetLabelText();
1514 case Toolkit::Button::Property::LABEL:
1516 Property::Map emptyMap;
1528 void Button::SetLabel( Actor label )
1530 if( mLabel != label )
1532 if( mLabel && mLabel.GetParent() )
1534 mLabel.GetParent().Remove( mLabel );
1538 mLabel.SetPosition( 0.0f, 0.0f );
1540 // label should be the top of the button
1541 Self().Add( mLabel );
1550 void Button::SetButtonImage( Actor image )
1554 StopTransitionAnimation();
1556 SetupContent( mUnselectedContent, image );
1558 OnUnselectedImageSet();
1563 void Button::SetSelectedImage( Actor image )
1567 StopTransitionAnimation();
1569 SetupContent( mSelectedContent, image );
1571 OnSelectedImageSet();
1576 void Button::SetBackgroundImage( Actor image )
1580 StopTransitionAnimation();
1582 SetupContent( mBackgroundContent, image );
1584 OnBackgroundImageSet();
1589 void Button::SetSelectedBackgroundImage( Actor image )
1593 StopTransitionAnimation();
1595 SetupContent( mSelectedBackgroundContent, image );
1597 OnSelectedBackgroundImageSet();
1602 void Button::SetDisabledImage( Actor image )
1606 StopTransitionAnimation();
1608 SetupContent( mDisabledContent, image );
1610 OnDisabledImageSet();
1615 void Button::SetDisabledSelectedImage( Actor image )
1619 StopTransitionAnimation();
1621 SetupContent( mDisabledSelectedContent, image );
1623 OnDisabledSelectedImageSet();
1628 void Button::SetDisabledBackgroundImage( Actor image )
1632 StopTransitionAnimation();
1634 SetupContent( mDisabledBackgroundContent, image );
1636 OnDisabledBackgroundImageSet();
1641 Actor Button::GetButtonImage() const
1643 return mUnselectedContent;
1646 Actor Button::GetSelectedImage() const
1648 return mSelectedContent;
1652 } // namespace Internal
1654 } // namespace Toolkit