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/devel-visual-properties.h>
34 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
38 * Button states and contents
39 * (3) mSelectedContent
40 * (2) mUnselectedContent (2) mSelectedBackgroundContent
41 * (1) mBackgroundContent (1) mBackgroundContent
42 * < unselected > ----------------------- < selected >
44 * | OnDisabled() | OnDisabled()
46 * < disabled > < disabled-selected >
47 * (2) mDisabledContent (2) mDisabledSelectedContent
48 * (1) mDisabledBackgroundContent (1) mDisabledBackgroundContent
50 * The drawing order of child actors is as follows.
53 * | mUnselectedContent / mSelectedContent / mDisabledContent / mDisabledSelectedContent
54 * | mSelectedBackgroundContent
55 * Bottom mBackgroundContent / mDisabledBackgroundContent
57 * Some of contents may be missed.
58 * 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.
75 // empty handle as we cannot create button (but type registered for clicked signal)
79 // Setup properties, signals and actions using the type-registry.
80 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create );
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
85 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
86 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
87 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
88 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", STRING, UNSELECTED_STATE_IMAGE )
89 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", STRING, SELECTED_STATE_IMAGE )
90 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", STRING, DISABLED_STATE_IMAGE )
91 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR )
92 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR )
93 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
95 // Deprecated properties:
96 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
100 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
101 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
102 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
105 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
107 DALI_TYPE_REGISTRATION_END()
109 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
110 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
112 } // unnamed namespace
115 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
116 mAutoRepeatingTimer(),
117 mUnselectedColor( Color::WHITE ), // The natural colors of the specified images will be used by default.
118 mSelectedColor( Color::WHITE ),
120 mAutoRepeating( false ),
121 mTogglableButton( false ),
123 mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
124 mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
125 mAnimationTime( 0.0f ),
126 mClickActionPerforming( false ),
128 mPaintState( UnselectedState )
136 void Button::SetDisabled( bool disabled )
138 if( disabled == mDisabled )
143 StopTransitionAnimation();
145 mDisabled = disabled;
147 // Notifies the derived class the button has been disabled.
150 switch( mPaintState )
152 case UnselectedState:
155 //(3) mDisabledContent (Inserted)
156 //(4) mUnselectedContent
157 //(2) mDisabledBackgroundContent (Inserted)
158 //(1) mBackgroundContent
160 AddButtonImage( mBackgroundContent );
161 TransitionButtonImage( mDisabledBackgroundContent );
162 AddButtonImage( mUnselectedContent );
163 TransitionButtonImage( mDisabledContent );
165 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
168 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
169 TransitionOut( mUnselectedContent );
170 TransitionOut( mSelectedContent );
171 TransitionOut( mBackgroundContent );
172 TransitionOut( mSelectedBackgroundContent );
173 TransitionOut( mDisabledSelectedContent );
175 mPaintState = DisabledUnselectedState;
181 //(5) mDisabledSelectedContent (Inserted)
182 //(4) mSelectedContent
183 //(3) mDisabledBackgroundContent (Inserted)
184 //(2) mSelectedBackgroundContent
185 //(1) mBackgroundContent
187 AddButtonImage( mBackgroundContent );
188 AddButtonImage( mSelectedBackgroundContent );
189 TransitionButtonImage( mDisabledBackgroundContent );
190 AddButtonImage( mSelectedContent );
191 TransitionButtonImage( mDisabledSelectedContent );
193 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
196 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
197 TransitionOut( mUnselectedContent );
198 TransitionOut( mSelectedContent );
199 TransitionOut( mBackgroundContent );
200 TransitionOut( mSelectedBackgroundContent );
201 TransitionOut( mDisabledContent );
203 mPaintState = DisabledSelectedState;
206 case DisabledUnselectedState:
209 //(3) mUnselectedContent (Inserted)
210 //(4) mDisabledContent
211 //(2) mBackgroundContent (Inserted)
212 //(1) mDisabledBackgroundContent
214 AddButtonImage( mDisabledBackgroundContent );
215 TransitionButtonImage( mBackgroundContent );
216 AddButtonImage( mDisabledContent );
217 TransitionButtonImage( mUnselectedContent );
219 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
222 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
223 TransitionOut( mSelectedContent );
224 TransitionOut( mSelectedBackgroundContent );
225 TransitionOut( mDisabledContent );
226 TransitionOut( mDisabledSelectedContent );
227 TransitionOut( mDisabledBackgroundContent );
229 mPaintState = UnselectedState;
232 case DisabledSelectedState:
235 //(4) mSelectedContent (Inserted)
236 //(5) mDisabledSelectedContent
237 //(3) mSelectedBackgroundContent (Inserted)
238 //(2) mBackgroundContent (Inserted)
239 //(1) mDisabledBackgroundContent
241 AddButtonImage( mDisabledBackgroundContent );
242 TransitionButtonImage( mBackgroundContent );
243 TransitionButtonImage( mSelectedBackgroundContent );
244 AddButtonImage( mDisabledSelectedContent );
245 TransitionButtonImage( mSelectedContent );
247 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
250 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
251 TransitionOut( mUnselectedContent );
252 TransitionOut( mDisabledContent );
253 TransitionOut( mDisabledSelectedContent );
254 TransitionOut( mDisabledBackgroundContent );
256 mPaintState = SelectedState;
261 StartTransitionAnimation();
264 bool Button::IsDisabled() const
269 void Button::SetAutoRepeating( bool autoRepeating )
271 mAutoRepeating = autoRepeating;
273 // An autorepeating button can't be a togglable button.
276 mTogglableButton = false;
280 // Emit a signal is not wanted, only change the appearance.
281 SetSelected( false, false );
286 bool Button::IsAutoRepeating() const
288 return mAutoRepeating;
291 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
293 DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
294 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
297 float Button::GetInitialAutoRepeatingDelay() const
299 return mInitialAutoRepeatingDelay;
302 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
304 DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
305 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
308 float Button::GetNextAutoRepeatingDelay() const
310 return mNextAutoRepeatingDelay;
313 void Button::SetTogglableButton( bool togglable )
315 mTogglableButton = togglable;
317 // A togglable button can't be an autorepeating button.
320 mAutoRepeating = false;
324 bool Button::IsTogglableButton() const
326 return mTogglableButton;
329 void Button::SetSelected( bool selected )
331 if( !mDisabled && mTogglableButton && ( selected != mSelected ) )
333 SetSelected( selected, true );
337 void Button::SetSelected( bool selected, bool emitSignal )
339 StopTransitionAnimation();
341 mSelected = selected;
343 // Notifies the derived class the button has been selected.
346 switch( mPaintState )
348 case UnselectedState:
351 //(3) mSelectedContent (Inserted)
352 //(4) mUnselectedContent
353 //(2) mSelectedBackgroundContent (Inserted)
354 //(1) mBackgroundContent
356 AddButtonImage( mBackgroundContent );
357 TransitionButtonImage( mSelectedBackgroundContent );
358 AddButtonImage( mUnselectedContent );
359 TransitionButtonImage( mSelectedContent );
361 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
362 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
365 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
366 TransitionOut( mUnselectedContent );
367 TransitionOut( mDisabledContent );
368 TransitionOut( mDisabledSelectedContent );
369 TransitionOut( mDisabledBackgroundContent );
371 mPaintState = SelectedState;
377 //(3) mUnselectedContent (Inserted)
378 //(2) mSelectedContent
379 //(1) mBackgroundContent
381 AddButtonImage( mBackgroundContent );
382 AddButtonImage( mSelectedContent );
383 TransitionButtonImage( mUnselectedContent );
385 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
386 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
389 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
390 TransitionOut( mSelectedContent );
391 TransitionOut( mSelectedBackgroundContent );
392 TransitionOut( mDisabledContent );
393 TransitionOut( mDisabledSelectedContent );
394 TransitionOut( mDisabledBackgroundContent );
396 mPaintState = UnselectedState;
399 case DisabledUnselectedState:
400 case DisabledSelectedState:
402 DALI_ASSERT_DEBUG( 0 && "Shouldn't be able to change paint state if the button is disabled." );
407 StartTransitionAnimation();
411 Toolkit::Button handle( GetOwner() );
414 mStateChangedSignal.Emit( handle );
420 bool Button::IsSelected() const
422 return mTogglableButton && mSelected;
425 void Button::SetAnimationTime( float animationTime )
427 mAnimationTime = animationTime;
430 float Button::GetAnimationTime() const
432 return mAnimationTime;
435 void Button::SetLabelText( const std::string& label )
437 Property::Map labelProperty;
438 labelProperty.Insert( "text", label );
439 ModifyLabel( labelProperty );
442 std::string Button::GetLabelText() const
444 Toolkit::TextLabel label = Dali::Toolkit::TextLabel::DownCast( mLabel );
447 return label.GetProperty<std::string>( Dali::Toolkit::TextLabel::Property::TEXT );
449 return std::string();
452 void Button::ModifyLabel( const Property::Map& properties )
454 // If we don't have a label yet, create one.
457 // If we don't have a label, create one and set it up.
458 // Note: The label text is set from the passed in property map after creation.
459 mLabel = Toolkit::TextLabel::New();
460 mLabel.SetPosition( 0.0f, 0.0f );
461 // label should be the top of the button
462 Self().Add( mLabel );
465 // Set any properties specified for the label by iterating through all property key-value pairs.
466 for( unsigned int i = 0, mapCount = properties.Count(); i < mapCount; ++i )
468 const StringValuePair& propertyPair( properties.GetPair( i ) );
470 // Convert the property string to a property index.
471 Property::Index setPropertyIndex = mLabel.GetPropertyIndex( propertyPair.first );
472 if( setPropertyIndex != Property::INVALID_INDEX )
474 // If the conversion worked, we have a valid property index,
475 // Set the property to the new value.
476 mLabel.SetProperty( setPropertyIndex, propertyPair.second );
480 // Notify derived button classes of the change.
486 Actor& Button::GetLabelActor()
491 void Button::SetDecoration( DecorationState state, Actor actor )
493 if( mDecoration[ state ] && mDecoration[ state ].GetParent() )
495 mDecoration[ state ].Unparent();
498 mDecoration[ state ] = actor;
499 mDecoration[ state ].SetColorMode( USE_OWN_COLOR );
505 Actor& Button::GetDecoration( DecorationState state )
507 return mDecoration[ state ];
510 void Button::SetupContent( Actor& actorToModify, Actor newActor )
514 StopTransitionAnimation();
516 if( actorToModify && actorToModify.GetParent() )
518 actorToModify.Unparent();
521 actorToModify = newActor;
525 actorToModify.SetAnchorPoint( AnchorPoint::TOP_LEFT );
526 actorToModify.SetParentOrigin( ParentOrigin::TOP_LEFT );
527 actorToModify.SetPosition( 0.f, 0.f );
534 const Vector4 Button::GetUnselectedColor() const
536 return mUnselectedColor;
539 void Button::SetColor( const Vector4& color, Button::PaintState selectedState )
541 Actor* contentActor = NULL; // Using a pointer as SetupContent assigns the new Actor to this.
542 bool imageFileExists = false;
543 Property::Index visualIndex = Toolkit::Button::Property::SELECTED_STATE_IMAGE;
545 if ( selectedState == SelectedState || selectedState == DisabledSelectedState )
547 mSelectedColor = color;
548 contentActor = &mSelectedContent;
549 imageFileExists = !GetSelectedImageFilename().empty();
553 mUnselectedColor = color;
554 contentActor = &mUnselectedContent;
555 imageFileExists = !GetUnselectedImageFilename().empty();
556 visualIndex = Toolkit::Button::Property::UNSELECTED_STATE_IMAGE;
561 if( imageFileExists )
563 // If there is existing unselected content, change the color on it directly.
564 contentActor->SetColor( color );
568 // If there is no existing content, create a new actor to use for flat color.
569 Actor placementActor = Actor::New();
570 Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get();
571 Toolkit::Visual::Base visual;
574 map[ Toolkit::VisualProperty::TYPE ] = Toolkit::Visual::COLOR;
575 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
577 visual = visualFactory.CreateVisual( map );
579 RegisterVisual( visualIndex, placementActor, visual );
581 SetupContent( *contentActor, placementActor ); //
582 contentActor->SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
587 const Vector4 Button::GetSelectedColor() const
589 return mSelectedColor;
592 void Button::SetUnselectedImage( const std::string& filename )
594 Toolkit::ImageView newContent;
595 if( !filename.empty() )
597 newContent = Toolkit::ImageView::New( filename );
601 newContent = Toolkit::ImageView::New();
606 SetupContent( mUnselectedContent, newContent );
608 mUnselectedContent.SetColor( mUnselectedColor );
610 OnUnselectedImageSet();
615 Actor& Button::GetUnselectedImage()
617 return mUnselectedContent;
620 void Button::SetSelectedImage( const std::string& filename )
622 Toolkit::ImageView newContent;
623 if( !filename.empty() )
625 newContent = Toolkit::ImageView::New( filename );
629 newContent = Toolkit::ImageView::New();
634 SetupContent( mSelectedContent, newContent );
636 mSelectedContent.SetColor( mSelectedColor );
638 OnSelectedImageSet();
643 Actor& Button::GetSelectedImage()
645 return mSelectedContent;
648 void Button::SetBackgroundImage( const std::string& filename )
650 SetupContent( mBackgroundContent, Toolkit::ImageView::New( filename ) );
652 OnBackgroundImageSet();
656 Actor& Button::GetBackgroundImage()
658 return mBackgroundContent;
661 void Button::SetSelectedBackgroundImage( const std::string& filename )
663 SetupContent( mSelectedBackgroundContent, Toolkit::ImageView::New( filename ) );
665 OnSelectedBackgroundImageSet();
669 Actor& Button::GetSelectedBackgroundImage()
671 return mSelectedBackgroundContent;
674 void Button::SetDisabledImage( const std::string& filename )
676 SetupContent( mDisabledContent, Toolkit::ImageView::New( filename ) );
678 OnDisabledImageSet();
682 Actor& Button::GetDisabledImage()
684 return mDisabledContent;
687 void Button::SetDisabledSelectedImage( const std::string& filename )
689 SetupContent( mDisabledSelectedContent, Toolkit::ImageView::New( filename ) );
691 OnDisabledSelectedImageSet();
695 Actor& Button::GetDisabledSelectedImage()
697 return mDisabledSelectedContent;
700 void Button::SetDisabledBackgroundImage( const std::string& filename )
702 SetupContent( mDisabledBackgroundContent, Toolkit::ImageView::New( filename ) );
704 OnDisabledBackgroundImageSet();
708 Actor& Button::GetDisabledBackgroundImage()
710 return mDisabledBackgroundContent;
713 std::string Button::GetUnselectedImageFilename() const
715 if( mUnselectedContent )
717 ResourceImage image = ResourceImage::DownCast( mUnselectedContent );
720 return image.GetUrl();
723 return std::string();
726 std::string Button::GetSelectedImageFilename() const
728 if( mSelectedContent )
730 ResourceImage image = ResourceImage::DownCast( mSelectedContent );
733 return image.GetUrl();
736 return std::string();
739 std::string Button::GetDisabledImageFilename() const
741 if( mDisabledContent )
743 ResourceImage image = ResourceImage::DownCast( mDisabledContent );
746 return image.GetUrl();
749 return std::string();
752 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
756 Dali::BaseHandle handle( object );
758 Toolkit::Button button = Toolkit::Button::DownCast( handle );
760 DALI_ASSERT_ALWAYS( button );
762 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
764 ret = GetImplementation( button ).DoClickAction( attributes );
770 bool Button::DoClickAction( const Property::Map& attributes )
772 // Prevents the button signals from doing a recursive loop by sending an action
773 // and re-emitting the signals.
774 if( !mClickActionPerforming )
776 mClickActionPerforming = true;
780 mClickActionPerforming = false;
788 void Button::OnButtonDown()
790 if( !mTogglableButton )
796 SetUpTimer( mInitialAutoRepeatingDelay );
800 // The pressed signal should be emitted regardless of toggle mode.
801 Toolkit::Button handle( GetOwner() );
802 mPressedSignal.Emit( handle );
805 void Button::OnButtonUp()
807 if( ButtonDown == mState )
809 if( mTogglableButton )
811 SetSelected( !mSelected );
819 mAutoRepeatingTimer.Reset();
823 // The clicked and released signals should be emitted regardless of toggle mode.
824 Toolkit::Button handle( GetOwner() );
825 mReleasedSignal.Emit( handle );
826 mClickedSignal.Emit( handle );
830 void Button::OnTouchPointLeave()
832 if( ButtonDown == mState )
834 if( !mTogglableButton )
840 mAutoRepeatingTimer.Reset();
844 // The released signal should be emitted regardless of toggle mode.
845 Toolkit::Button handle( GetOwner() );
846 mReleasedSignal.Emit( handle );
850 void Button::OnTouchPointInterrupted()
855 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
857 return mPressedSignal;
860 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
862 return mReleasedSignal;
865 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
867 return mClickedSignal;
870 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
872 return mStateChangedSignal;
875 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
877 Dali::BaseHandle handle( object );
879 bool connected( true );
880 Toolkit::Button button = Toolkit::Button::DownCast( handle );
882 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
884 button.PressedSignal().Connect( tracker, functor );
886 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
888 button.ReleasedSignal().Connect( tracker, functor );
890 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
892 button.ClickedSignal().Connect( tracker, functor );
894 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
896 button.StateChangedSignal().Connect( tracker, functor );
900 // signalName does not match any signal
907 void Button::OnInitialize()
911 mTapDetector = TapGestureDetector::New();
912 mTapDetector.Attach( self );
913 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
915 self.SetKeyboardFocusable( true );
917 self.TouchSignal().Connect( this, &Button::OnTouch );
920 bool Button::OnAccessibilityActivated()
922 return OnKeyboardEnter();
925 bool Button::OnKeyboardEnter()
927 // When the enter key is pressed, or button is activated, the click action is performed.
928 Property::Map attributes;
929 bool ret = DoClickAction( attributes );
934 void Button::OnStageDisconnection()
936 if( ButtonDown == mState )
938 if( !mTogglableButton )
944 mAutoRepeatingTimer.Reset();
951 Control::OnStageDisconnection();
954 bool Button::OnTouch( Actor actor, const TouchData& touch )
956 // Only events are processed when the button is not disabled and the touch event has only
958 if( ( !mDisabled ) && ( 1 == touch.GetPointCount() ) )
960 switch( touch.GetState( 0 ) )
962 case PointState::DOWN:
964 OnButtonDown(); // Notification for derived classes.
966 // Sets the button state to ButtonDown.
972 OnButtonUp(); // Notification for derived classes.
974 // Sets the button state to ButtonUp.
978 case PointState::INTERRUPTED:
980 OnTouchPointInterrupted(); // Notification for derived classes.
982 // Sets the button state to the default (ButtonUp).
986 case PointState::LEAVE:
988 OnTouchPointLeave(); // Notification for derived classes.
990 // Sets the button state to the default (ButtonUp).
994 case PointState::MOTION:
995 case PointState::STATIONARY: // FALLTHROUGH
1002 else if( 1 < touch.GetPointCount() )
1004 OnTouchPointLeave(); // Notification for derived classes.
1006 // Sets the button state to the default (ButtonUp).
1013 void Button::OnTap(Actor actor, const TapGesture& tap)
1018 void Button::SetUpTimer( float delay )
1020 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1021 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1022 mAutoRepeatingTimer.Start();
1025 bool Button::AutoRepeatingSlot()
1027 bool consumed = false;
1030 // Restart the autorepeat timer.
1031 SetUpTimer( mNextAutoRepeatingDelay );
1035 Toolkit::Button handle( GetOwner() );
1038 consumed = mReleasedSignal.Emit( handle );
1039 consumed |= mClickedSignal.Emit( handle );
1040 consumed |= mPressedSignal.Emit( handle );
1046 void Button::Pressed()
1048 if( mPaintState == UnselectedState )
1050 StopTransitionAnimation();
1052 // Notifies the derived class the button has been pressed.
1056 //(4) mSelectedContent (Inserted)
1057 //(3) mUnselectedContent
1058 //(2) mSelectedBackgroundContent (Inserted)
1059 //(1) mBackgroundContent
1061 AddButtonImage( mBackgroundContent );
1062 TransitionButtonImage( mSelectedBackgroundContent );
1063 AddButtonImage( mUnselectedContent );
1064 TransitionButtonImage( mSelectedContent );
1066 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1067 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
1070 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
1071 TransitionOut( mUnselectedContent );
1072 TransitionOut( mDisabledContent );
1073 TransitionOut( mDisabledSelectedContent );
1074 TransitionOut( mDisabledBackgroundContent );
1076 mPaintState = SelectedState;
1078 StartTransitionAnimation();
1082 void Button::Released()
1084 if( mPaintState == SelectedState )
1086 StopTransitionAnimation();
1088 // Notifies the derived class the button has been released.
1092 //(3) mUnselectedContent (Inserted)
1093 //(2) mSelectedContent
1094 //(1) mBackgroundContent
1096 AddButtonImage( mBackgroundContent );
1097 AddButtonImage( mSelectedContent );
1098 TransitionButtonImage( mUnselectedContent );
1100 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1101 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1104 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
1105 TransitionOut( mSelectedContent );
1106 TransitionOut( mSelectedBackgroundContent );
1107 TransitionOut( mDisabledContent );
1108 TransitionOut( mDisabledSelectedContent );
1109 TransitionOut( mDisabledBackgroundContent );
1111 mPaintState = UnselectedState;
1113 StartTransitionAnimation();
1117 Button::ButtonState Button::GetState()
1122 Button::PaintState Button::GetPaintState()
1127 void Button::PrepareAddButtonImage( Actor& actor )
1131 Self().Add( actor );
1132 PrepareForTranstionOut( actor );
1136 void Button::TransitionButtonImage( Actor& actor )
1140 if( !actor.GetParent() )
1142 Self().Add( actor );
1145 OnTransitionIn( actor );
1149 void Button::AddButtonImage( Actor& actor )
1153 Self().Add( actor );
1157 void Button::ReAddLabel()
1162 Self().Add( mLabel );
1166 void Button::RemoveButtonImage( Actor& actor )
1170 if( actor.GetParent() )
1172 Self().Remove( actor );
1174 PrepareForTranstionIn( actor );
1178 unsigned int Button::FindChildIndex( Actor& actor )
1180 Actor self = Self();
1181 unsigned int childrenNum = self.GetChildCount();
1183 for( unsigned int i = 0; i < childrenNum; i++ )
1185 Actor child = self.GetChildAt( i );
1186 if( child == actor )
1195 void Button::TransitionOut( Actor actor )
1197 OnTransitionOut( actor );
1200 void Button::ResetImageLayers()
1202 // Ensure that all layers are in the correct order and state according to the paint state
1204 switch( mPaintState )
1206 case UnselectedState:
1209 //(2) mUnselectedContent
1210 //(1) mBackgroundContent
1212 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1213 RemoveButtonImage( mSelectedContent );
1214 RemoveButtonImage( mSelectedBackgroundContent );
1215 RemoveButtonImage( mDisabledContent );
1216 RemoveButtonImage( mDisabledSelectedContent );
1217 RemoveButtonImage( mDisabledBackgroundContent );
1219 PrepareAddButtonImage( mBackgroundContent );
1220 PrepareAddButtonImage( mUnselectedContent );
1222 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1229 //(3) mSelectedContent
1230 //(2) mSelectedBackgroundContent
1231 //(1) mBackgroundContent
1233 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1234 RemoveButtonImage( mUnselectedContent );
1235 RemoveButtonImage( mDisabledContent );
1236 RemoveButtonImage( mDisabledSelectedContent );
1237 RemoveButtonImage( mDisabledBackgroundContent );
1239 PrepareAddButtonImage( mBackgroundContent );
1240 PrepareAddButtonImage( mSelectedBackgroundContent );
1241 PrepareAddButtonImage( mSelectedContent );
1243 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1247 case DisabledUnselectedState:
1250 //(2) mDisabledContent
1251 //(1) mDisabledBackgroundContent
1253 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1254 RemoveButtonImage( mUnselectedContent );
1255 RemoveButtonImage( mBackgroundContent );
1256 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1257 RemoveButtonImage( mSelectedContent );
1258 RemoveButtonImage( mDisabledSelectedContent );
1259 RemoveButtonImage( mSelectedBackgroundContent );
1261 PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
1262 PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
1264 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1268 case DisabledSelectedState:
1271 // (2) mDisabledSelectedContent
1272 // (1) mDisabledBackgroundContent
1274 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1275 RemoveButtonImage( mUnselectedContent );
1276 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1277 RemoveButtonImage( mSelectedContent );
1278 RemoveButtonImage( mBackgroundContent );
1279 RemoveButtonImage( mSelectedBackgroundContent );
1280 RemoveButtonImage( mDisabledContent );
1282 if( mDisabledBackgroundContent )
1284 PrepareAddButtonImage( mDisabledBackgroundContent );
1288 PrepareAddButtonImage( mBackgroundContent );
1289 PrepareAddButtonImage( mSelectedBackgroundContent );
1292 PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
1294 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1301 void Button::StartTransitionAnimation()
1303 if( mTransitionAnimation )
1305 mTransitionAnimation.Play();
1313 void Button::StopTransitionAnimation()
1315 if( mTransitionAnimation )
1317 mTransitionAnimation.Clear();
1318 mTransitionAnimation.Reset();
1322 Dali::Animation Button::GetTransitionAnimation()
1324 if( !mTransitionAnimation )
1326 mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1327 mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1330 return mTransitionAnimation;
1333 void Button::TransitionAnimationFinished( Dali::Animation& source )
1335 StopTransitionAnimation();
1339 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1341 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1347 case Toolkit::Button::Property::DISABLED:
1349 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1353 case Toolkit::Button::Property::AUTO_REPEATING:
1355 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1359 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1361 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1365 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1367 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1371 case Toolkit::Button::Property::TOGGLABLE:
1373 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1377 case Toolkit::Button::Property::SELECTED:
1379 GetImplementation( button ).SetSelected( value.Get< bool >() );
1383 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1385 GetImplementation( button ).SetUnselectedImage( value.Get< std::string >() );
1389 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1391 GetImplementation( button ).SetSelectedImage( value.Get< std::string >() );
1395 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1397 GetImplementation( button ).SetDisabledImage( value.Get< std::string >() );
1401 case Toolkit::Button::Property::UNSELECTED_COLOR:
1403 GetImplementation( button ).SetColor( value.Get< Vector4 >(), UnselectedState );
1407 case Toolkit::Button::Property::SELECTED_COLOR:
1409 GetImplementation( button ).SetColor( value.Get< Vector4 >(), SelectedState );
1413 case Toolkit::Button::Property::LABEL_TEXT:
1415 GetImplementation( button ).SetLabelText( value.Get< std::string >() );
1419 case Toolkit::Button::Property::LABEL:
1421 // Get a Property::Map from the property if possible.
1422 Property::Map setPropertyMap;
1423 if( value.Get( setPropertyMap ) )
1425 GetImplementation( button ).ModifyLabel( setPropertyMap );
1433 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1435 Property::Value value;
1437 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1441 switch ( propertyIndex )
1443 case Toolkit::Button::Property::DISABLED:
1445 value = GetImplementation( button ).mDisabled;
1449 case Toolkit::Button::Property::AUTO_REPEATING:
1451 value = GetImplementation( button ).mAutoRepeating;
1455 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1457 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1461 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1463 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1467 case Toolkit::Button::Property::TOGGLABLE:
1469 value = GetImplementation( button ).mTogglableButton;
1473 case Toolkit::Button::Property::SELECTED:
1475 value = GetImplementation( button ).mSelected;
1479 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1481 value = GetImplementation( button ).GetUnselectedImageFilename();
1485 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1487 value = GetImplementation( button ).GetSelectedImageFilename();
1491 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1493 value = GetImplementation( button ).GetDisabledImageFilename();
1497 case Toolkit::Button::Property::UNSELECTED_COLOR:
1499 value = GetImplementation( button ).GetUnselectedColor();
1503 case Toolkit::Button::Property::SELECTED_COLOR:
1505 value = GetImplementation( button ).GetSelectedColor();
1509 case Toolkit::Button::Property::LABEL_TEXT:
1511 value = GetImplementation( button ).GetLabelText();
1515 case Toolkit::Button::Property::LABEL:
1517 Property::Map emptyMap;
1529 void Button::SetLabel( Actor label )
1531 if( mLabel != label )
1533 if( mLabel && mLabel.GetParent() )
1535 mLabel.GetParent().Remove( mLabel );
1539 mLabel.SetPosition( 0.0f, 0.0f );
1541 // label should be the top of the button
1542 Self().Add( mLabel );
1551 void Button::SetButtonImage( Actor image )
1555 StopTransitionAnimation();
1557 SetupContent( mUnselectedContent, image );
1559 OnUnselectedImageSet();
1564 void Button::SetSelectedImage( Actor image )
1568 StopTransitionAnimation();
1570 SetupContent( mSelectedContent, image );
1572 OnSelectedImageSet();
1577 void Button::SetBackgroundImage( Actor image )
1581 StopTransitionAnimation();
1583 SetupContent( mBackgroundContent, image );
1585 OnBackgroundImageSet();
1590 void Button::SetSelectedBackgroundImage( Actor image )
1594 StopTransitionAnimation();
1596 SetupContent( mSelectedBackgroundContent, image );
1598 OnSelectedBackgroundImageSet();
1603 void Button::SetDisabledImage( Actor image )
1607 StopTransitionAnimation();
1609 SetupContent( mDisabledContent, image );
1611 OnDisabledImageSet();
1616 void Button::SetDisabledSelectedImage( Actor image )
1620 StopTransitionAnimation();
1622 SetupContent( mDisabledSelectedContent, image );
1624 OnDisabledSelectedImageSet();
1629 void Button::SetDisabledBackgroundImage( Actor image )
1633 StopTransitionAnimation();
1635 SetupContent( mDisabledBackgroundContent, image );
1637 OnDisabledBackgroundImageSet();
1642 Actor Button::GetButtonImage() const
1644 return mUnselectedContent;
1647 Actor Button::GetSelectedImage() const
1649 return mSelectedContent;
1653 } // namespace Internal
1655 } // namespace Toolkit