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( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
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 );
579 visual.SetOnStage( placementActor );
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