2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "button-impl.h"
22 #include <cstring> // for strcmp
23 #include <dali/public-api/events/touch-event.h>
24 #include <dali/public-api/images/resource-image.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/devel-api/object/type-registry-helper.h>
27 #include <dali/public-api/actors/image-actor.h>
28 #include <dali/devel-api/scripting/scripting.h>
31 #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
32 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
35 * Button states and contents
36 * (3) mSelectedContent
37 * (2) mUnselectedContent (2) mSelectedBackgroundContent
38 * (1) mBackgroundContent (1) mBackgroundContent
39 * < unselected > ----------------------- < selected >
41 * | OnDisabled() | OnDisabled()
43 * < disabled > < disabled-selected >
44 * (2) mDisabledContent (2) mDisabledSelectedContent
45 * (1) mDisabledBackgroundContent (1) mDisabledBackgroundContent
47 * The drawing order of child actors is as follows.
50 * | mUnselectedContent / mSelectedContent / mDisabledContent / mDisabledSelectedContent
51 * | mSelectedBackgroundContent
52 * Bottom mBackgroundContent / mDisabledBackgroundContent
54 * Some of contents may be missed.
55 * 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.
72 // empty handle as we cannot create button (but type registered for clicked signal)
76 // Setup properties, signals and actions using the type-registry.
77 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Button, Toolkit::Control, Create );
79 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabled", BOOLEAN, DISABLED )
80 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "autoRepeating", BOOLEAN, AUTO_REPEATING )
81 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "initialAutoRepeatingDelay", FLOAT, INITIAL_AUTO_REPEATING_DELAY )
82 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "nextAutoRepeatingDelay", FLOAT, NEXT_AUTO_REPEATING_DELAY )
83 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "togglable", BOOLEAN, TOGGLABLE )
84 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selected", BOOLEAN, SELECTED )
85 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedStateImage", STRING, UNSELECTED_STATE_IMAGE )
86 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedStateImage", STRING, SELECTED_STATE_IMAGE )
87 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "disabledStateImage", STRING, DISABLED_STATE_IMAGE )
88 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "unselectedColor", VECTOR4, UNSELECTED_COLOR )
89 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "selectedColor", VECTOR4, SELECTED_COLOR )
90 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "label", MAP, LABEL )
92 // Deprecated properties:
93 DALI_PROPERTY_REGISTRATION( Toolkit, Button, "labelText", STRING, LABEL_TEXT )
96 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "pressed", SIGNAL_PRESSED )
97 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "released", SIGNAL_RELEASED )
98 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "clicked", SIGNAL_CLICKED )
99 DALI_SIGNAL_REGISTRATION( Toolkit, Button, "stateChanged", SIGNAL_STATE_CHANGED )
102 DALI_ACTION_REGISTRATION( Toolkit, Button, "buttonClick", ACTION_BUTTON_CLICK )
104 DALI_TYPE_REGISTRATION_END()
106 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
107 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
109 } // unnamed namespace
112 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
113 mAutoRepeatingTimer(),
114 mUnselectedColor( Color::WHITE ), // The natural colors of the specified images will be used by default.
115 mSelectedColor( Color::WHITE ),
117 mAutoRepeating( false ),
118 mTogglableButton( false ),
120 mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
121 mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
122 mAnimationTime( 0.0f ),
123 mClickActionPerforming( false ),
125 mPaintState( UnselectedState )
133 void Button::SetDisabled( bool disabled )
135 if( disabled == mDisabled )
140 StopTransitionAnimation();
142 mDisabled = disabled;
144 // Notifies the derived class the button has been disabled.
147 switch( mPaintState )
149 case UnselectedState:
152 //(3) mDisabledContent (Inserted)
153 //(4) mUnselectedContent
154 //(2) mDisabledBackgroundContent (Inserted)
155 //(1) mBackgroundContent
157 AddButtonImage( mBackgroundContent );
158 TransitionButtonImage( mDisabledBackgroundContent );
159 AddButtonImage( mUnselectedContent );
160 TransitionButtonImage( mDisabledContent );
162 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
165 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
166 TransitionOut( mUnselectedContent );
167 TransitionOut( mSelectedContent );
168 TransitionOut( mBackgroundContent );
169 TransitionOut( mSelectedBackgroundContent );
170 TransitionOut( mDisabledSelectedContent );
172 mPaintState = DisabledUnselectedState;
178 //(5) mDisabledSelectedContent (Inserted)
179 //(4) mSelectedContent
180 //(3) mDisabledBackgroundContent (Inserted)
181 //(2) mSelectedBackgroundContent
182 //(1) mBackgroundContent
184 AddButtonImage( mBackgroundContent );
185 AddButtonImage( mSelectedBackgroundContent );
186 TransitionButtonImage( mDisabledBackgroundContent );
187 AddButtonImage( mSelectedContent );
188 TransitionButtonImage( mDisabledSelectedContent );
190 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
193 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
194 TransitionOut( mUnselectedContent );
195 TransitionOut( mSelectedContent );
196 TransitionOut( mBackgroundContent );
197 TransitionOut( mSelectedBackgroundContent );
198 TransitionOut( mDisabledContent );
200 mPaintState = DisabledSelectedState;
203 case DisabledUnselectedState:
206 //(3) mUnselectedContent (Inserted)
207 //(4) mDisabledContent
208 //(2) mBackgroundContent (Inserted)
209 //(1) mDisabledBackgroundContent
211 AddButtonImage( mDisabledBackgroundContent );
212 TransitionButtonImage( mBackgroundContent );
213 AddButtonImage( mDisabledContent );
214 TransitionButtonImage( mUnselectedContent );
216 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
219 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
220 TransitionOut( mSelectedContent );
221 TransitionOut( mSelectedBackgroundContent );
222 TransitionOut( mDisabledContent );
223 TransitionOut( mDisabledSelectedContent );
224 TransitionOut( mDisabledBackgroundContent );
226 mPaintState = UnselectedState;
229 case DisabledSelectedState:
232 //(4) mSelectedContent (Inserted)
233 //(5) mDisabledSelectedContent
234 //(3) mSelectedBackgroundContent (Inserted)
235 //(2) mBackgroundContent (Inserted)
236 //(1) mDisabledBackgroundContent
238 AddButtonImage( mDisabledBackgroundContent );
239 TransitionButtonImage( mBackgroundContent );
240 TransitionButtonImage( mSelectedBackgroundContent );
241 AddButtonImage( mDisabledSelectedContent );
242 TransitionButtonImage( mSelectedContent );
244 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
247 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
248 TransitionOut( mUnselectedContent );
249 TransitionOut( mDisabledContent );
250 TransitionOut( mDisabledSelectedContent );
251 TransitionOut( mDisabledBackgroundContent );
253 mPaintState = SelectedState;
258 StartTransitionAnimation();
261 bool Button::IsDisabled() const
266 void Button::SetAutoRepeating( bool autoRepeating )
268 mAutoRepeating = autoRepeating;
270 // An autorepeating button can't be a togglable button.
273 mTogglableButton = false;
277 // Emit a signal is not wanted, only change the appearance.
278 SetSelected( false, false );
283 bool Button::IsAutoRepeating() const
285 return mAutoRepeating;
288 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
290 DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
291 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
294 float Button::GetInitialAutoRepeatingDelay() const
296 return mInitialAutoRepeatingDelay;
299 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
301 DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
302 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
305 float Button::GetNextAutoRepeatingDelay() const
307 return mNextAutoRepeatingDelay;
310 void Button::SetTogglableButton( bool togglable )
312 mTogglableButton = togglable;
314 // A togglable button can't be an autorepeating button.
317 mAutoRepeating = false;
321 bool Button::IsTogglableButton() const
323 return mTogglableButton;
326 void Button::SetSelected( bool selected )
328 if( !mDisabled && mTogglableButton && ( selected != mSelected ) )
330 SetSelected( selected, true );
334 void Button::SetSelected( bool selected, bool emitSignal )
336 StopTransitionAnimation();
338 mSelected = selected;
340 // Notifies the derived class the button has been selected.
343 switch( mPaintState )
345 case UnselectedState:
348 //(3) mSelectedContent (Inserted)
349 //(4) mUnselectedContent
350 //(2) mSelectedBackgroundContent (Inserted)
351 //(1) mBackgroundContent
353 AddButtonImage( mBackgroundContent );
354 TransitionButtonImage( mSelectedBackgroundContent );
355 AddButtonImage( mUnselectedContent );
356 TransitionButtonImage( mSelectedContent );
358 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
359 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
362 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
363 TransitionOut( mUnselectedContent );
364 TransitionOut( mDisabledContent );
365 TransitionOut( mDisabledSelectedContent );
366 TransitionOut( mDisabledBackgroundContent );
368 mPaintState = SelectedState;
374 //(3) mUnselectedContent (Inserted)
375 //(2) mSelectedContent
376 //(1) mBackgroundContent
378 AddButtonImage( mBackgroundContent );
379 AddButtonImage( mSelectedContent );
380 TransitionButtonImage( mUnselectedContent );
382 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
383 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
386 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
387 TransitionOut( mSelectedContent );
388 TransitionOut( mSelectedBackgroundContent );
389 TransitionOut( mDisabledContent );
390 TransitionOut( mDisabledSelectedContent );
391 TransitionOut( mDisabledBackgroundContent );
393 mPaintState = UnselectedState;
396 case DisabledUnselectedState:
397 case DisabledSelectedState:
399 DALI_ASSERT_DEBUG( 0 && "Shouldn't be able to change paint state if the button is disabled." );
404 StartTransitionAnimation();
408 Toolkit::Button handle( GetOwner() );
411 mStateChangedSignal.Emit( handle );
417 bool Button::IsSelected() const
419 return mTogglableButton && mSelected;
422 void Button::SetAnimationTime( float animationTime )
424 mAnimationTime = animationTime;
427 float Button::GetAnimationTime() const
429 return mAnimationTime;
432 void Button::SetLabelText( const std::string& label )
434 Property::Map labelProperty;
435 labelProperty.Insert( "text", label );
436 ModifyLabel( labelProperty );
439 std::string Button::GetLabelText() const
441 Toolkit::TextLabel label = Dali::Toolkit::TextLabel::DownCast( mLabel );
444 return label.GetProperty<std::string>( Dali::Toolkit::TextLabel::Property::TEXT );
446 return std::string();
449 void Button::ModifyLabel( const Property::Map& properties )
451 // If we don't have a label yet, create one.
454 // If we don't have a label, create one and set it up.
455 // Note: The label text is set from the passed in property map after creation.
456 mLabel = Toolkit::TextLabel::New();
457 mLabel.SetPosition( 0.0f, 0.0f );
458 // label should be the top of the button
459 Self().Add( mLabel );
462 // Set any properties specified for the label by iterating through all property key-value pairs.
463 for( unsigned int i = 0, mapCount = properties.Count(); i < mapCount; ++i )
465 const StringValuePair& propertyPair( properties.GetPair( i ) );
467 // Convert the property string to a property index.
468 Property::Index setPropertyIndex = mLabel.GetPropertyIndex( propertyPair.first );
469 if( setPropertyIndex != Property::INVALID_INDEX )
471 // If the conversion worked, we have a valid property index,
472 // Set the property to the new value.
473 mLabel.SetProperty( setPropertyIndex, propertyPair.second );
477 // Notify derived button classes of the change.
483 Actor& Button::GetLabelActor()
488 void Button::SetDecoration( DecorationState state, Actor actor )
490 if( mDecoration[ state ] && mDecoration[ state ].GetParent() )
492 mDecoration[ state ].Unparent();
495 mDecoration[ state ] = actor;
496 mDecoration[ state ].SetColorMode( USE_OWN_COLOR );
502 Actor& Button::GetDecoration( DecorationState state )
504 return mDecoration[ state ];
507 void Button::SetupContent( Actor& actorToModify, Actor newActor )
511 StopTransitionAnimation();
513 if( actorToModify && actorToModify.GetParent() )
515 actorToModify.Unparent();
518 actorToModify = newActor;
522 actorToModify.SetAnchorPoint( AnchorPoint::TOP_LEFT );
523 actorToModify.SetParentOrigin( ParentOrigin::TOP_LEFT );
524 actorToModify.SetPosition( 0.f, 0.f );
531 void Button::SetUnselectedColor( const Vector4& color )
533 mUnselectedColor = color;
535 if( mUnselectedContent && !GetUnselectedImageFilename().empty() )
537 // If there is existing unselected content, change the color on it directly.
538 mUnselectedContent.SetColor( mUnselectedColor );
542 // If there is no existing content, create a new actor to use for flat color.
543 SetupContent( mUnselectedContent, CreateSolidColorActor( mUnselectedColor ) );
544 mUnselectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
548 const Vector4 Button::GetUnselectedColor() const
550 return mUnselectedColor;
553 void Button::SetSelectedColor( const Vector4& color )
555 mSelectedColor = color;
557 if( mSelectedContent && !GetSelectedImageFilename().empty() )
559 // If there is existing unselected content, change the color on it directly.
560 mSelectedContent.SetColor( mSelectedColor );
564 // If there is no existing content, create a new actor to use for flat color.
565 SetupContent( mSelectedContent, CreateSolidColorActor( mSelectedColor ) );
566 mSelectedContent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
570 const Vector4 Button::GetSelectedColor() const
572 return mSelectedColor;
575 void Button::SetUnselectedImage( const std::string& filename )
577 ImageActor newContent;
578 if( !filename.empty() )
580 Image resourceimage = Dali::ResourceImage::New( filename );
583 newContent = ImageActor::New( resourceimage );
588 newContent = ImageActor::New();
593 SetupContent( mUnselectedContent, newContent );
595 mUnselectedContent.SetColor( mUnselectedColor );
597 OnUnselectedImageSet();
602 Actor& Button::GetUnselectedImage()
604 return mUnselectedContent;
607 void Button::SetSelectedImage( const std::string& filename )
609 ImageActor newContent;
610 if( !filename.empty() )
612 Image resourceimage = Dali::ResourceImage::New( filename );
615 newContent = ImageActor::New( resourceimage );
620 newContent = ImageActor::New();
625 SetupContent( mSelectedContent, newContent );
627 mSelectedContent.SetColor( mSelectedColor );
629 OnSelectedImageSet();
634 Actor& Button::GetSelectedImage()
636 return mSelectedContent;
639 void Button::SetBackgroundImage( const std::string& filename )
641 Image resourceimage = Dali::ResourceImage::New( filename );
644 SetupContent( mBackgroundContent, ImageActor::New( resourceimage ) );
646 OnBackgroundImageSet();
651 Actor& Button::GetBackgroundImage()
653 return mBackgroundContent;
656 void Button::SetSelectedBackgroundImage( const std::string& filename )
658 Image resourceimage = Dali::ResourceImage::New( filename );
661 SetupContent( mSelectedBackgroundContent, ImageActor::New( resourceimage ) );
663 OnSelectedBackgroundImageSet();
668 Actor& Button::GetSelectedBackgroundImage()
670 return mSelectedBackgroundContent;
673 void Button::SetDisabledImage( const std::string& filename )
675 Image resourceimage = Dali::ResourceImage::New( filename );
678 SetupContent( mDisabledContent, ImageActor::New( resourceimage ) );
680 OnDisabledImageSet();
685 Actor& Button::GetDisabledImage()
687 return mDisabledContent;
690 void Button::SetDisabledSelectedImage( const std::string& filename )
692 Image resourceimage = Dali::ResourceImage::New( filename );
695 SetupContent( mDisabledSelectedContent, ImageActor::New( resourceimage ) );
697 OnDisabledSelectedImageSet();
702 Actor& Button::GetDisabledSelectedImage()
704 return mDisabledSelectedContent;
707 void Button::SetDisabledBackgroundImage( const std::string& filename )
709 Image resourceimage = Dali::ResourceImage::New( filename );
712 SetupContent( mDisabledBackgroundContent, ImageActor::New( resourceimage ) );
714 OnDisabledBackgroundImageSet();
719 Actor& Button::GetDisabledBackgroundImage()
721 return mDisabledBackgroundContent;
724 std::string Button::GetUnselectedImageFilename() const
726 if( mUnselectedContent )
728 ResourceImage image = ResourceImage::DownCast( mUnselectedContent );
731 return image.GetUrl();
734 return std::string();
737 std::string Button::GetSelectedImageFilename() const
739 if( mSelectedContent )
741 ResourceImage image = ResourceImage::DownCast( mSelectedContent );
744 return image.GetUrl();
747 return std::string();
750 std::string Button::GetBackgroundImageFilename() const
752 if( mBackgroundContent )
754 ResourceImage image = ResourceImage::DownCast( mBackgroundContent );
757 return image.GetUrl();
760 return std::string();
763 std::string Button::GetSelectedBackgroundImageFilename() const
765 if( mSelectedBackgroundContent )
767 ResourceImage image = ResourceImage::DownCast( mSelectedBackgroundContent );
770 return image.GetUrl();
773 return std::string();
776 std::string Button::GetDisabledImageFilename() const
778 if( mDisabledContent )
780 ResourceImage image = ResourceImage::DownCast( mDisabledContent );
783 return image.GetUrl();
786 return std::string();
789 std::string Button::GetDisabledSelectedImageFilename() const
791 if( mDisabledSelectedContent )
793 ResourceImage image = ResourceImage::DownCast( mDisabledSelectedContent );
796 return image.GetUrl();
799 return std::string();
802 std::string Button::GetDisabledBackgroundImageFilename() const
804 if( mDisabledBackgroundContent )
806 ResourceImage image = ResourceImage::DownCast( mDisabledBackgroundContent );
809 return image.GetUrl();
812 return std::string();
815 bool Button::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
819 Dali::BaseHandle handle( object );
821 Toolkit::Button button = Toolkit::Button::DownCast( handle );
823 DALI_ASSERT_ALWAYS( button );
825 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
827 ret = GetImplementation( button ).DoClickAction( attributes );
833 bool Button::DoClickAction( const Property::Map& attributes )
835 // Prevents the button signals from doing a recursive loop by sending an action
836 // and re-emitting the signals.
837 if( !mClickActionPerforming )
839 mClickActionPerforming = true;
843 mClickActionPerforming = false;
851 void Button::OnButtonStageDisconnection()
853 if( ButtonDown == mState )
855 if( !mTogglableButton )
861 mAutoRepeatingTimer.Reset();
867 void Button::OnButtonDown()
869 if( !mTogglableButton )
875 SetUpTimer( mInitialAutoRepeatingDelay );
879 // The pressed signal should be emitted regardless of toggle mode.
880 Toolkit::Button handle( GetOwner() );
881 mPressedSignal.Emit( handle );
884 void Button::OnButtonUp()
886 if( ButtonDown == mState )
888 if( mTogglableButton )
890 SetSelected( !mSelected );
898 mAutoRepeatingTimer.Reset();
902 // The clicked and released signals should be emitted regardless of toggle mode.
903 Toolkit::Button handle( GetOwner() );
904 mReleasedSignal.Emit( handle );
905 mClickedSignal.Emit( handle );
909 void Button::OnTouchPointLeave()
911 if( ButtonDown == mState )
913 if( !mTogglableButton )
919 mAutoRepeatingTimer.Reset();
923 // The released signal should be emitted regardless of toggle mode.
924 Toolkit::Button handle( GetOwner() );
925 mReleasedSignal.Emit( handle );
929 void Button::OnTouchPointInterrupted()
934 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
936 return mPressedSignal;
939 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
941 return mReleasedSignal;
944 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
946 return mClickedSignal;
949 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
951 return mStateChangedSignal;
954 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
956 Dali::BaseHandle handle( object );
958 bool connected( true );
959 Toolkit::Button button = Toolkit::Button::DownCast( handle );
961 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
963 button.PressedSignal().Connect( tracker, functor );
965 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
967 button.ReleasedSignal().Connect( tracker, functor );
969 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
971 button.ClickedSignal().Connect( tracker, functor );
973 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
975 button.StateChangedSignal().Connect( tracker, functor );
979 // signalName does not match any signal
986 bool Button::OnTouchEvent(const TouchEvent& event)
988 // Only events are processed when the button is not disabled and the touch event has only
990 if( ( !mDisabled ) && ( 1 == event.GetPointCount() ) )
992 switch( event.GetPoint(0).state )
994 case TouchPoint::Down:
996 OnButtonDown(); // Notification for derived classes.
998 // Sets the button state to ButtonDown.
1002 case TouchPoint::Up:
1004 OnButtonUp(); // Notification for derived classes.
1006 // Sets the button state to ButtonUp.
1010 case TouchPoint::Interrupted:
1012 OnTouchPointInterrupted(); // Notification for derived classes.
1014 // Sets the button state to the default (ButtonUp).
1018 case TouchPoint::Leave:
1020 OnTouchPointLeave(); // Notification for derived classes.
1022 // Sets the button state to the default (ButtonUp).
1026 case TouchPoint::Motion:
1027 case TouchPoint::Stationary: // FALLTHROUGH
1034 DALI_ASSERT_ALWAYS( !"Point status unhandled." );
1039 else if( 1 < event.GetPointCount() )
1041 OnTouchPointLeave(); // Notification for derived classes.
1043 // Sets the button state to the default (ButtonUp).
1050 void Button::OnInitialize()
1052 Actor self = Self();
1054 mTapDetector = TapGestureDetector::New();
1055 mTapDetector.Attach( self );
1056 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
1058 OnButtonInitialize();
1060 self.SetKeyboardFocusable( true );
1063 bool Button::OnAccessibilityActivated()
1065 return OnKeyboardEnter();
1068 bool Button::OnKeyboardEnter()
1070 // When the enter key is pressed, or button is activated, the click action is performed.
1071 Property::Map attributes;
1072 bool ret = DoClickAction( attributes );
1077 void Button::OnControlStageDisconnection()
1079 OnButtonStageDisconnection(); // Notification for derived classes.
1083 void Button::OnTap(Actor actor, const TapGesture& tap)
1088 void Button::SetUpTimer( float delay )
1090 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
1091 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
1092 mAutoRepeatingTimer.Start();
1095 bool Button::AutoRepeatingSlot()
1097 bool consumed = false;
1100 // Restart the autorepeat timer.
1101 SetUpTimer( mNextAutoRepeatingDelay );
1105 Toolkit::Button handle( GetOwner() );
1108 consumed = mReleasedSignal.Emit( handle );
1109 consumed |= mClickedSignal.Emit( handle );
1110 consumed |= mPressedSignal.Emit( handle );
1116 void Button::Pressed()
1118 if( mPaintState == UnselectedState )
1120 StopTransitionAnimation();
1122 // Notifies the derived class the button has been pressed.
1126 //(4) mSelectedContent (Inserted)
1127 //(3) mUnselectedContent
1128 //(2) mSelectedBackgroundContent (Inserted)
1129 //(1) mBackgroundContent
1131 AddButtonImage( mBackgroundContent );
1132 TransitionButtonImage( mSelectedBackgroundContent );
1133 AddButtonImage( mUnselectedContent );
1134 TransitionButtonImage( mSelectedContent );
1136 AddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1137 TransitionButtonImage( mDecoration[ SELECTED_DECORATION ] );
1140 TransitionOut( mDecoration[ UNSELECTED_DECORATION ] );
1141 TransitionOut( mUnselectedContent );
1142 TransitionOut( mDisabledContent );
1143 TransitionOut( mDisabledSelectedContent );
1144 TransitionOut( mDisabledBackgroundContent );
1146 mPaintState = SelectedState;
1148 StartTransitionAnimation();
1152 void Button::Released()
1154 if( mPaintState == SelectedState )
1156 StopTransitionAnimation();
1158 // Notifies the derived class the button has been released.
1162 //(3) mUnselectedContent (Inserted)
1163 //(2) mSelectedContent
1164 //(1) mBackgroundContent
1166 AddButtonImage( mBackgroundContent );
1167 AddButtonImage( mSelectedContent );
1168 TransitionButtonImage( mUnselectedContent );
1170 AddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1171 TransitionButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1174 TransitionOut( mDecoration[ SELECTED_DECORATION ] );
1175 TransitionOut( mSelectedContent );
1176 TransitionOut( mSelectedBackgroundContent );
1177 TransitionOut( mDisabledContent );
1178 TransitionOut( mDisabledSelectedContent );
1179 TransitionOut( mDisabledBackgroundContent );
1181 mPaintState = UnselectedState;
1183 StartTransitionAnimation();
1187 Button::ButtonState Button::GetState()
1192 Button::PaintState Button::GetPaintState()
1197 void Button::PrepareAddButtonImage( Actor& actor )
1202 Self().Add( actor );
1203 PrepareForTranstionOut( actor );
1207 void Button::TransitionButtonImage( Actor& actor )
1211 if( !actor.GetParent() )
1213 Self().Add( actor );
1216 OnTransitionIn( actor );
1220 void Button::AddButtonImage( Actor& actor )
1225 Self().Add( actor );
1229 void Button::ReAddLabel()
1234 Self().Add( mLabel );
1238 void Button::RemoveButtonImage( Actor& actor )
1242 if( actor.GetParent() )
1244 Self().Remove( actor );
1246 PrepareForTranstionIn( actor );
1250 unsigned int Button::FindChildIndex( Actor& actor )
1252 Actor self = Self();
1253 unsigned int childrenNum = self.GetChildCount();
1255 for( unsigned int i = 0; i < childrenNum; i++ )
1257 Actor child = self.GetChildAt( i );
1258 if( child == actor )
1267 void Button::TransitionOut( Actor actor )
1269 OnTransitionOut( actor );
1272 void Button::ResetImageLayers()
1274 // Ensure that all layers are in the correct order and state according to the paint state
1276 switch( mPaintState )
1278 case UnselectedState:
1281 //(2) mUnselectedContent
1282 //(1) mBackgroundContent
1284 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1285 RemoveButtonImage( mSelectedContent );
1286 RemoveButtonImage( mSelectedBackgroundContent );
1287 RemoveButtonImage( mDisabledContent );
1288 RemoveButtonImage( mDisabledSelectedContent );
1289 RemoveButtonImage( mDisabledBackgroundContent );
1291 PrepareAddButtonImage( mBackgroundContent );
1292 PrepareAddButtonImage( mUnselectedContent );
1294 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1301 //(3) mSelectedContent
1302 //(2) mSelectedBackgroundContent
1303 //(1) mBackgroundContent
1305 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1306 RemoveButtonImage( mUnselectedContent );
1307 RemoveButtonImage( mDisabledContent );
1308 RemoveButtonImage( mDisabledSelectedContent );
1309 RemoveButtonImage( mDisabledBackgroundContent );
1311 PrepareAddButtonImage( mBackgroundContent );
1312 PrepareAddButtonImage( mSelectedBackgroundContent );
1313 PrepareAddButtonImage( mSelectedContent );
1315 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1319 case DisabledUnselectedState:
1322 //(2) mDisabledContent
1323 //(1) mDisabledBackgroundContent
1325 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1326 RemoveButtonImage( mUnselectedContent );
1327 RemoveButtonImage( mBackgroundContent );
1328 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1329 RemoveButtonImage( mSelectedContent );
1330 RemoveButtonImage( mDisabledSelectedContent );
1331 RemoveButtonImage( mSelectedBackgroundContent );
1333 PrepareAddButtonImage( mDisabledBackgroundContent ? mDisabledBackgroundContent : mBackgroundContent );
1334 PrepareAddButtonImage( mDisabledContent ? mDisabledContent : mUnselectedContent );
1336 PrepareAddButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1340 case DisabledSelectedState:
1343 // (2) mDisabledSelectedContent
1344 // (1) mDisabledBackgroundContent
1346 RemoveButtonImage( mDecoration[ UNSELECTED_DECORATION ] );
1347 RemoveButtonImage( mUnselectedContent );
1348 RemoveButtonImage( mDecoration[ SELECTED_DECORATION ] );
1349 RemoveButtonImage( mSelectedContent );
1350 RemoveButtonImage( mBackgroundContent );
1351 RemoveButtonImage( mSelectedBackgroundContent );
1352 RemoveButtonImage( mDisabledContent );
1354 if( mDisabledBackgroundContent )
1356 PrepareAddButtonImage( mDisabledBackgroundContent );
1360 PrepareAddButtonImage( mBackgroundContent );
1361 PrepareAddButtonImage( mSelectedBackgroundContent );
1364 PrepareAddButtonImage( mDisabledSelectedContent ? mDisabledSelectedContent : mSelectedContent );
1366 PrepareAddButtonImage( mDecoration[ SELECTED_DECORATION ] );
1373 void Button::StartTransitionAnimation()
1375 if( mTransitionAnimation )
1377 mTransitionAnimation.Play();
1385 void Button::StopTransitionAnimation()
1387 if( mTransitionAnimation )
1389 mTransitionAnimation.Clear();
1390 mTransitionAnimation.Reset();
1394 Dali::Animation Button::GetTransitionAnimation()
1396 if( !mTransitionAnimation )
1398 mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
1399 mTransitionAnimation.FinishedSignal().Connect( this, &Button::TransitionAnimationFinished );
1402 return mTransitionAnimation;
1405 void Button::TransitionAnimationFinished( Dali::Animation& source )
1407 StopTransitionAnimation();
1411 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
1413 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1419 case Toolkit::Button::Property::DISABLED:
1421 GetImplementation( button ).SetDisabled( value.Get< bool >() );
1425 case Toolkit::Button::Property::AUTO_REPEATING:
1427 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
1431 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1433 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
1437 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1439 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
1443 case Toolkit::Button::Property::TOGGLABLE:
1445 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
1449 case Toolkit::Button::Property::SELECTED:
1451 GetImplementation( button ).SetSelected( value.Get< bool >() );
1455 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1457 GetImplementation( button ).SetUnselectedImage( value.Get< std::string >() );
1461 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1463 GetImplementation( button ).SetSelectedImage( value.Get< std::string >() );
1467 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1469 GetImplementation( button ).SetDisabledImage( value.Get< std::string >() );
1473 case Toolkit::Button::Property::UNSELECTED_COLOR:
1475 GetImplementation( button ).SetUnselectedColor( value.Get< Vector4 >() );
1479 case Toolkit::Button::Property::SELECTED_COLOR:
1481 GetImplementation( button ).SetSelectedColor( value.Get< Vector4 >() );
1485 case Toolkit::Button::Property::LABEL_TEXT:
1487 GetImplementation( button ).SetLabelText( value.Get< std::string >() );
1491 case Toolkit::Button::Property::LABEL:
1493 // Get a Property::Map from the property if possible.
1494 Property::Map setPropertyMap;
1495 if( value.Get( setPropertyMap ) )
1497 GetImplementation( button ).ModifyLabel( setPropertyMap );
1505 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
1507 Property::Value value;
1509 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
1513 switch ( propertyIndex )
1515 case Toolkit::Button::Property::DISABLED:
1517 value = GetImplementation( button ).mDisabled;
1521 case Toolkit::Button::Property::AUTO_REPEATING:
1523 value = GetImplementation( button ).mAutoRepeating;
1527 case Toolkit::Button::Property::INITIAL_AUTO_REPEATING_DELAY:
1529 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
1533 case Toolkit::Button::Property::NEXT_AUTO_REPEATING_DELAY:
1535 value = GetImplementation( button ).mNextAutoRepeatingDelay;
1539 case Toolkit::Button::Property::TOGGLABLE:
1541 value = GetImplementation( button ).mTogglableButton;
1545 case Toolkit::Button::Property::SELECTED:
1547 value = GetImplementation( button ).mSelected;
1551 case Toolkit::Button::Property::UNSELECTED_STATE_IMAGE:
1553 value = GetImplementation( button ).GetUnselectedImageFilename();
1557 case Toolkit::Button::Property::SELECTED_STATE_IMAGE:
1559 value = GetImplementation( button ).GetSelectedImageFilename();
1563 case Toolkit::Button::Property::DISABLED_STATE_IMAGE:
1565 value = GetImplementation( button ).GetDisabledImageFilename();
1569 case Toolkit::Button::Property::UNSELECTED_COLOR:
1571 value = GetImplementation( button ).GetUnselectedColor();
1575 case Toolkit::Button::Property::SELECTED_COLOR:
1577 value = GetImplementation( button ).GetSelectedColor();
1581 case Toolkit::Button::Property::LABEL_TEXT:
1583 value = GetImplementation( button ).GetLabelText();
1587 case Toolkit::Button::Property::LABEL:
1589 Property::Map emptyMap;
1601 void Button::SetLabel( Actor label )
1603 if( mLabel != label )
1605 if( mLabel && mLabel.GetParent() )
1607 mLabel.GetParent().Remove( mLabel );
1611 mLabel.SetPosition( 0.0f, 0.0f );
1613 // label should be the top of the button
1614 Self().Add( mLabel );
1623 void Button::SetButtonImage( Actor image )
1627 StopTransitionAnimation();
1629 SetupContent( mUnselectedContent, image );
1631 OnUnselectedImageSet();
1636 void Button::SetSelectedImage( Actor image )
1640 StopTransitionAnimation();
1642 SetupContent( mSelectedContent, image );
1644 OnSelectedImageSet();
1649 void Button::SetBackgroundImage( Actor image )
1653 StopTransitionAnimation();
1655 SetupContent( mBackgroundContent, image );
1657 OnBackgroundImageSet();
1662 void Button::SetSelectedBackgroundImage( Actor image )
1666 StopTransitionAnimation();
1668 SetupContent( mSelectedBackgroundContent, image );
1670 OnSelectedBackgroundImageSet();
1675 void Button::SetDisabledImage( Actor image )
1679 StopTransitionAnimation();
1681 SetupContent( mDisabledContent, image );
1683 OnDisabledImageSet();
1688 void Button::SetDisabledSelectedImage( Actor image )
1692 StopTransitionAnimation();
1694 SetupContent( mDisabledSelectedContent, image );
1696 OnDisabledSelectedImageSet();
1701 void Button::SetDisabledBackgroundImage( Actor image )
1705 StopTransitionAnimation();
1707 SetupContent( mDisabledBackgroundContent, image );
1709 OnDisabledBackgroundImageSet();
1714 Actor Button::GetButtonImage() const
1716 return mUnselectedContent;
1719 Actor Button::GetSelectedImage() const
1721 return mSelectedContent;
1725 } // namespace Internal
1727 } // namespace Toolkit