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;
543 if ( selectedState == SelectedState || selectedState == DisabledSelectedState )
545 mSelectedColor = color;
546 contentActor = &mSelectedContent;
547 imageFileExists = !GetSelectedImageFilename().empty();
551 mUnselectedColor = color;
552 contentActor = &mUnselectedContent;
553 imageFileExists = !GetUnselectedImageFilename().empty();
558 if( imageFileExists )
560 // If there is existing unselected content, change the color on it directly.
561 contentActor->SetColor( color );
565 // If there is no existing content, create a new actor to use for flat color.
566 Actor placementActor = Actor::New();
567 Toolkit::VisualFactory rendererFactory = Toolkit::VisualFactory::Get();
568 Toolkit::Visual::Base colorRenderer;
571 map[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::COLOR;
572 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
574 colorRenderer = rendererFactory.CreateVisual( map );
575 colorRenderer.SetOnStage( placementActor );
577 SetupContent( *contentActor, placementActor ); //
578 contentActor->SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
583 const Vector4 Button::GetSelectedColor() const
585 return mSelectedColor;
588 void Button::SetUnselectedImage( const std::string& filename )
590 Toolkit::ImageView newContent;
591 if( !filename.empty() )
593 newContent = Toolkit::ImageView::New( filename );
597 newContent = Toolkit::ImageView::New();
602 SetupContent( mUnselectedContent, newContent );
604 mUnselectedContent.SetColor( mUnselectedColor );
606 OnUnselectedImageSet();
611 Actor& Button::GetUnselectedImage()
613 return mUnselectedContent;
616 void Button::SetSelectedImage( const std::string& filename )
618 Toolkit::ImageView newContent;
619 if( !filename.empty() )
621 newContent = Toolkit::ImageView::New( filename );
625 newContent = Toolkit::ImageView::New();
630 SetupContent( mSelectedContent, newContent );
632 mSelectedContent.SetColor( mSelectedColor );
634 OnSelectedImageSet();
639 Actor& Button::GetSelectedImage()
641 return mSelectedContent;
644 void Button::SetBackgroundImage( const std::string& filename )
646 SetupContent( mBackgroundContent, Toolkit::ImageView::New( filename ) );
648 OnBackgroundImageSet();
652 Actor& Button::GetBackgroundImage()
654 return mBackgroundContent;
657 void Button::SetSelectedBackgroundImage( const std::string& filename )
659 SetupContent( mSelectedBackgroundContent, Toolkit::ImageView::New( filename ) );
661 OnSelectedBackgroundImageSet();
665 Actor& Button::GetSelectedBackgroundImage()
667 return mSelectedBackgroundContent;
670 void Button::SetDisabledImage( const std::string& filename )
672 SetupContent( mDisabledContent, Toolkit::ImageView::New( filename ) );
674 OnDisabledImageSet();
678 Actor& Button::GetDisabledImage()
680 return mDisabledContent;
683 void Button::SetDisabledSelectedImage( const std::string& filename )
685 SetupContent( mDisabledSelectedContent, Toolkit::ImageView::New( filename ) );
687 OnDisabledSelectedImageSet();
691 Actor& Button::GetDisabledSelectedImage()
693 return mDisabledSelectedContent;
696 void Button::SetDisabledBackgroundImage( const std::string& filename )
698 SetupContent( mDisabledBackgroundContent, Toolkit::ImageView::New( filename ) );
700 OnDisabledBackgroundImageSet();
704 Actor& Button::GetDisabledBackgroundImage()
706 return mDisabledBackgroundContent;
709 std::string Button::GetUnselectedImageFilename() const
711 if( mUnselectedContent )
713 ResourceImage image = ResourceImage::DownCast( mUnselectedContent );
716 return image.GetUrl();
719 return std::string();
722 std::string Button::GetSelectedImageFilename() const
724 if( mSelectedContent )
726 ResourceImage image = ResourceImage::DownCast( mSelectedContent );
729 return image.GetUrl();
732 return std::string();
735 std::string Button::GetDisabledImageFilename() const
737 if( mDisabledContent )
739 ResourceImage image = ResourceImage::DownCast( mDisabledContent );
742 return image.GetUrl();
745 return std::string();
748 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
752 Dali::BaseHandle handle( object );
754 Toolkit::Button button = Toolkit::Button::DownCast( handle );
756 DALI_ASSERT_ALWAYS( button );
758 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
760 ret = GetImplementation( button ).DoClickAction( attributes );
766 bool Button::DoClickAction( const Property::Map& attributes )
768 // Prevents the button signals from doing a recursive loop by sending an action
769 // and re-emitting the signals.
770 if( !mClickActionPerforming )
772 mClickActionPerforming = true;
776 mClickActionPerforming = false;
784 void Button::OnButtonDown()
786 if( !mTogglableButton )
792 SetUpTimer( mInitialAutoRepeatingDelay );
796 // The pressed signal should be emitted regardless of toggle mode.
797 Toolkit::Button handle( GetOwner() );
798 mPressedSignal.Emit( handle );
801 void Button::OnButtonUp()
803 if( ButtonDown == mState )
805 if( mTogglableButton )
807 SetSelected( !mSelected );
815 mAutoRepeatingTimer.Reset();
819 // The clicked and released signals should be emitted regardless of toggle mode.
820 Toolkit::Button handle( GetOwner() );
821 mReleasedSignal.Emit( handle );
822 mClickedSignal.Emit( handle );
826 void Button::OnTouchPointLeave()
828 if( ButtonDown == mState )
830 if( !mTogglableButton )
836 mAutoRepeatingTimer.Reset();
840 // The released signal should be emitted regardless of toggle mode.
841 Toolkit::Button handle( GetOwner() );
842 mReleasedSignal.Emit( handle );
846 void Button::OnTouchPointInterrupted()
851 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
853 return mPressedSignal;
856 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
858 return mReleasedSignal;
861 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
863 return mClickedSignal;
866 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
868 return mStateChangedSignal;
871 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
873 Dali::BaseHandle handle( object );
875 bool connected( true );
876 Toolkit::Button button = Toolkit::Button::DownCast( handle );
878 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
880 button.PressedSignal().Connect( tracker, functor );
882 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
884 button.ReleasedSignal().Connect( tracker, functor );
886 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
888 button.ClickedSignal().Connect( tracker, functor );
890 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
892 button.StateChangedSignal().Connect( tracker, functor );
896 // signalName does not match any signal
903 void Button::OnInitialize()
907 mTapDetector = TapGestureDetector::New();
908 mTapDetector.Attach( self );
909 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
911 self.SetKeyboardFocusable( true );
913 self.TouchSignal().Connect( this, &Button::OnTouch );
916 bool Button::OnAccessibilityActivated()
918 return OnKeyboardEnter();
921 bool Button::OnKeyboardEnter()
923 // When the enter key is pressed, or button is activated, the click action is performed.
924 Property::Map attributes;
925 bool ret = DoClickAction( attributes );
930 void Button::OnStageDisconnection()
932 if( ButtonDown == mState )
934 if( !mTogglableButton )
940 mAutoRepeatingTimer.Reset();
947 Control::OnStageDisconnection();
950 bool Button::OnTouch( Actor actor, const TouchData& touch )
952 // Only events are processed when the button is not disabled and the touch event has only
954 if( ( !mDisabled ) && ( 1 == touch.GetPointCount() ) )
956 switch( touch.GetState( 0 ) )
958 case PointState::DOWN:
960 OnButtonDown(); // Notification for derived classes.
962 // Sets the button state to ButtonDown.
968 OnButtonUp(); // Notification for derived classes.
970 // Sets the button state to ButtonUp.
974 case PointState::INTERRUPTED:
976 OnTouchPointInterrupted(); // Notification for derived classes.
978 // Sets the button state to the default (ButtonUp).
982 case PointState::LEAVE:
984 OnTouchPointLeave(); // Notification for derived classes.
986 // Sets the button state to the default (ButtonUp).
990 case PointState::MOTION:
991 case PointState::STATIONARY: // FALLTHROUGH
998 else if( 1 < touch.GetPointCount() )
1000 OnTouchPointLeave(); // Notification for derived classes.
1002 // Sets the button state to the default (ButtonUp).
1009 void Button::OnTap(Actor actor, const TapGesture& tap)
1014 void Button::SetUpTimer( float delay )
1016 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1017 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1018 mAutoRepeatingTimer.Start();
1021 bool Button::AutoRepeatingSlot()
1023 bool consumed = false;
1026 // Restart the autorepeat timer.
1027 SetUpTimer( mNextAutoRepeatingDelay );
1031 Toolkit::Button handle( GetOwner() );
1034 consumed = mReleasedSignal.Emit( handle );
1035 consumed |= mClickedSignal.Emit( handle );
1036 consumed |= mPressedSignal.Emit( handle );
1042 void Button::Pressed()
1044 if( mPaintState == UnselectedState )
1046 StopTransitionAnimation();
1048 // Notifies the derived class the button has been pressed.
1052 //(4) mSelectedContent (Inserted)
1053 //(3) mUnselectedContent
1054 //(2) mSelectedBackgroundContent (Inserted)
1055 //(1) mBackgroundContent
1057 AddButtonImage( mBackgroundContent );
1058 TransitionButtonImage( mSelectedBackgroundContent );
1059 AddButtonImage( mUnselectedContent );
1060 TransitionButtonImage( mSelectedContent );
1062 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1063 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
1066 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
1067 TransitionOut( mUnselectedContent );
1068 TransitionOut( mDisabledContent );
1069 TransitionOut( mDisabledSelectedContent );
1070 TransitionOut( mDisabledBackgroundContent );
1072 mPaintState = SelectedState;
1074 StartTransitionAnimation();
1078 void Button::Released()
1080 if( mPaintState == SelectedState )
1082 StopTransitionAnimation();
1084 // Notifies the derived class the button has been released.
1088 //(3) mUnselectedContent (Inserted)
1089 //(2) mSelectedContent
1090 //(1) mBackgroundContent
1092 AddButtonImage( mBackgroundContent );
1093 AddButtonImage( mSelectedContent );
1094 TransitionButtonImage( mUnselectedContent );
1096 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1097 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1100 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
1101 TransitionOut( mSelectedContent );
1102 TransitionOut( mSelectedBackgroundContent );
1103 TransitionOut( mDisabledContent );
1104 TransitionOut( mDisabledSelectedContent );
1105 TransitionOut( mDisabledBackgroundContent );
1107 mPaintState = UnselectedState;
1109 StartTransitionAnimation();
1113 Button::ButtonState Button::GetState()
1118 Button::PaintState Button::GetPaintState()
1123 void Button::PrepareAddButtonImage( Actor& actor )
1127 Self().Add( actor );
1128 PrepareForTranstionOut( actor );
1132 void Button::TransitionButtonImage( Actor& actor )
1136 if( !actor.GetParent() )
1138 Self().Add( actor );
1141 OnTransitionIn( actor );
1145 void Button::AddButtonImage( Actor& actor )
1149 Self().Add( actor );
1153 void Button::ReAddLabel()
1158 Self().Add( mLabel );
1162 void Button::RemoveButtonImage( Actor& actor )
1166 if( actor.GetParent() )
1168 Self().Remove( actor );
1170 PrepareForTranstionIn( actor );
1174 unsigned int Button::FindChildIndex( Actor& actor )
1176 Actor self = Self();
1177 unsigned int childrenNum = self.GetChildCount();
1179 for( unsigned int i = 0; i < childrenNum; i++ )
1181 Actor child = self.GetChildAt( i );
1182 if( child == actor )
1191 void Button::TransitionOut( Actor actor )
1193 OnTransitionOut( actor );
1196 void Button::ResetImageLayers()
1198 // Ensure that all layers are in the correct order and state according to the paint state
1200 switch( mPaintState )
1202 case UnselectedState:
1205 //(2) mUnselectedContent
1206 //(1) mBackgroundContent
1208 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1209 RemoveButtonImage( mSelectedContent );
1210 RemoveButtonImage( mSelectedBackgroundContent );
1211 RemoveButtonImage( mDisabledContent );
1212 RemoveButtonImage( mDisabledSelectedContent );
1213 RemoveButtonImage( mDisabledBackgroundContent );
1215 PrepareAddButtonImage( mBackgroundContent );
1216 PrepareAddButtonImage( mUnselectedContent );
1218 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1225 //(3) mSelectedContent
1226 //(2) mSelectedBackgroundContent
1227 //(1) mBackgroundContent
1229 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1230 RemoveButtonImage( mUnselectedContent );
1231 RemoveButtonImage( mDisabledContent );
1232 RemoveButtonImage( mDisabledSelectedContent );
1233 RemoveButtonImage( mDisabledBackgroundContent );
1235 PrepareAddButtonImage( mBackgroundContent );
1236 PrepareAddButtonImage( mSelectedBackgroundContent );
1237 PrepareAddButtonImage( mSelectedContent );
1239 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1243 case DisabledUnselectedState:
1246 //(2) mDisabledContent
1247 //(1) mDisabledBackgroundContent
1249 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1250 RemoveButtonImage( mUnselectedContent );
1251 RemoveButtonImage( mBackgroundContent );
1252 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1253 RemoveButtonImage( mSelectedContent );
1254 RemoveButtonImage( mDisabledSelectedContent );
1255 RemoveButtonImage( mSelectedBackgroundContent );
1257 PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
1258 PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
1260 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1264 case DisabledSelectedState:
1267 // (2) mDisabledSelectedContent
1268 // (1) mDisabledBackgroundContent
1270 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1271 RemoveButtonImage( mUnselectedContent );
1272 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1273 RemoveButtonImage( mSelectedContent );
1274 RemoveButtonImage( mBackgroundContent );
1275 RemoveButtonImage( mSelectedBackgroundContent );
1276 RemoveButtonImage( mDisabledContent );
1278 if( mDisabledBackgroundContent )
1280 PrepareAddButtonImage( mDisabledBackgroundContent );
1284 PrepareAddButtonImage( mBackgroundContent );
1285 PrepareAddButtonImage( mSelectedBackgroundContent );
1288 PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
1290 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1297 void Button::StartTransitionAnimation()
1299 if( mTransitionAnimation )
1301 mTransitionAnimation.Play();
1309 void Button::StopTransitionAnimation()
1311 if( mTransitionAnimation )
1313 mTransitionAnimation.Clear();
1314 mTransitionAnimation.Reset();
1318 Dali::Animation Button::GetTransitionAnimation()
1320 if( !mTransitionAnimation )
1322 mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1323 mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1326 return mTransitionAnimation;
1329 void Button::TransitionAnimationFinished( Dali::Animation& source )
1331 StopTransitionAnimation();
1335 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1337 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1343 case Toolkit::Button::Property::DISABLED:
1345 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1349 case Toolkit::Button::Property::AUTO_REPEATING:
1351 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1355 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1357 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1361 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1363 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1367 case Toolkit::Button::Property::TOGGLABLE:
1369 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1373 case Toolkit::Button::Property::SELECTED:
1375 GetImplementation( button ).SetSelected( value.Get< bool >() );
1379 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1381 GetImplementation( button ).SetUnselectedImage( value.Get< std::string >() );
1385 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1387 GetImplementation( button ).SetSelectedImage( value.Get< std::string >() );
1391 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1393 GetImplementation( button ).SetDisabledImage( value.Get< std::string >() );
1397 case Toolkit::Button::Property::UNSELECTED_COLOR:
1399 GetImplementation( button ).SetColor( value.Get< Vector4 >(), UnselectedState );
1403 case Toolkit::Button::Property::SELECTED_COLOR:
1405 GetImplementation( button ).SetColor( value.Get< Vector4 >(), SelectedState );
1409 case Toolkit::Button::Property::LABEL_TEXT:
1411 GetImplementation( button ).SetLabelText( value.Get< std::string >() );
1415 case Toolkit::Button::Property::LABEL:
1417 // Get a Property::Map from the property if possible.
1418 Property::Map setPropertyMap;
1419 if( value.Get( setPropertyMap ) )
1421 GetImplementation( button ).ModifyLabel( setPropertyMap );
1429 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1431 Property::Value value;
1433 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1437 switch ( propertyIndex )
1439 case Toolkit::Button::Property::DISABLED:
1441 value = GetImplementation( button ).mDisabled;
1445 case Toolkit::Button::Property::AUTO_REPEATING:
1447 value = GetImplementation( button ).mAutoRepeating;
1451 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1453 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1457 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1459 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1463 case Toolkit::Button::Property::TOGGLABLE:
1465 value = GetImplementation( button ).mTogglableButton;
1469 case Toolkit::Button::Property::SELECTED:
1471 value = GetImplementation( button ).mSelected;
1475 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1477 value = GetImplementation( button ).GetUnselectedImageFilename();
1481 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1483 value = GetImplementation( button ).GetSelectedImageFilename();
1487 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1489 value = GetImplementation( button ).GetDisabledImageFilename();
1493 case Toolkit::Button::Property::UNSELECTED_COLOR:
1495 value = GetImplementation( button ).GetUnselectedColor();
1499 case Toolkit::Button::Property::SELECTED_COLOR:
1501 value = GetImplementation( button ).GetSelectedColor();
1505 case Toolkit::Button::Property::LABEL_TEXT:
1507 value = GetImplementation( button ).GetLabelText();
1511 case Toolkit::Button::Property::LABEL:
1513 Property::Map emptyMap;
1525 void Button::SetLabel( Actor label )
1527 if( mLabel != label )
1529 if( mLabel && mLabel.GetParent() )
1531 mLabel.GetParent().Remove( mLabel );
1535 mLabel.SetPosition( 0.0f, 0.0f );
1537 // label should be the top of the button
1538 Self().Add( mLabel );
1547 void Button::SetButtonImage( Actor image )
1551 StopTransitionAnimation();
1553 SetupContent( mUnselectedContent, image );
1555 OnUnselectedImageSet();
1560 void Button::SetSelectedImage( Actor image )
1564 StopTransitionAnimation();
1566 SetupContent( mSelectedContent, image );
1568 OnSelectedImageSet();
1573 void Button::SetBackgroundImage( Actor image )
1577 StopTransitionAnimation();
1579 SetupContent( mBackgroundContent, image );
1581 OnBackgroundImageSet();
1586 void Button::SetSelectedBackgroundImage( Actor image )
1590 StopTransitionAnimation();
1592 SetupContent( mSelectedBackgroundContent, image );
1594 OnSelectedBackgroundImageSet();
1599 void Button::SetDisabledImage( Actor image )
1603 StopTransitionAnimation();
1605 SetupContent( mDisabledContent, image );
1607 OnDisabledImageSet();
1612 void Button::SetDisabledSelectedImage( Actor image )
1616 StopTransitionAnimation();
1618 SetupContent( mDisabledSelectedContent, image );
1620 OnDisabledSelectedImageSet();
1625 void Button::SetDisabledBackgroundImage( Actor image )
1629 StopTransitionAnimation();
1631 SetupContent( mDisabledBackgroundContent, image );
1633 OnDisabledBackgroundImageSet();
1638 Actor Button::GetButtonImage() const
1640 return mUnselectedContent;
1643 Actor Button::GetSelectedImage() const
1645 return mSelectedContent;
1649 } // namespace Internal
1651 } // namespace Toolkit