+Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
+{
+ return mStateChangedSignal;
+}
+
+bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+{
+ Dali::BaseHandle handle( object );
+
+ bool connected( true );
+ Toolkit::Button button = Toolkit::Button::DownCast( handle );
+
+ if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
+ {
+ button.PressedSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
+ {
+ button.ReleasedSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
+ {
+ button.ClickedSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
+ {
+ button.StateChangedSignal().Connect( tracker, functor );
+ }
+ else
+ {
+ // signalName does not match any signal
+ connected = false;
+ }
+
+ return connected;
+}
+
+void Button::OnInitialize()
+{
+ DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnInitialize\n" );
+
+ Actor self = Self();
+
+ mTapDetector = TapGestureDetector::New();
+ mTapDetector.Attach( self );
+ mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
+
+ self.SetKeyboardFocusable( true );
+
+ self.TouchSignal().Connect( this, &Button::OnTouch );
+}
+
+bool Button::OnAccessibilityActivated()
+{
+ return OnKeyboardEnter();
+}
+
+bool Button::OnTouch( Actor actor, const TouchData& touch )
+{
+
+ // Only events are processed when the button is not disabled and the touch event has only
+ // one touch point.
+
+ if( !IsDisabled() && ( 1 == touch.GetPointCount() ) )
+ {
+ switch( touch.GetState( 0 ) )
+ {
+ case PointState::DOWN:
+ {
+ OnButtonDown();
+ break;
+ }
+ case PointState::UP:
+ {
+ OnButtonUp();
+ break;
+ }
+ case PointState::INTERRUPTED:
+ {
+ OnTouchPointInterrupted();
+ break;
+ }
+ case PointState::LEAVE:
+ {
+ OnTouchPointLeave();
+ break;
+ }
+ case PointState::MOTION:
+ case PointState::STATIONARY: // FALLTHROUGH
+ {
+ // Nothing to do
+ break;
+ }
+ }
+ }
+ else if( 1 < touch.GetPointCount() )
+ {
+ OnTouchPointLeave(); // Notification for derived classes.
+
+ // Sets the button state to the default
+ mButtonPressedState = UNPRESSED;
+ }
+
+ return false;
+}
+
+bool Button::OnKeyboardEnter()
+{
+ // When the enter key is pressed, or button is activated, the click action is performed.
+ Property::Map attributes;
+ bool ret = DoClickAction( attributes );
+
+ return ret;
+}
+
+void Button::OnStageDisconnection()
+{
+ if( DEPRESSED == mButtonPressedState )
+ {
+ if( !mTogglableButton )
+ {
+ Released();
+
+ if( mAutoRepeating )
+ {
+ mAutoRepeatingTimer.Reset();
+ }
+ }
+ }
+
+ mButtonPressedState = UNPRESSED;
+
+ Control::OnStageDisconnection(); // Visuals will be set off stage
+}
+
+void Button::OnStageConnection( int depth )
+{
+ DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::OnStageConnection ptr(%p) \n", this );
+ PerformFunctionOnVisualsInState( &Button::SelectRequiredVisual, mButtonState );
+ Control::OnStageConnection( depth ); // Enabled visuals will be put on stage
+
+}
+
+Vector3 Button::GetNaturalSize()
+{
+ Vector3 size = Vector3::ZERO;
+
+ bool horizontalAlignment = mTextLabelAlignment == BEGIN || mTextLabelAlignment == END; // label and visual side by side
+
+ // Get natural size of foreground ( largest of the possible visuals )
+ Size largestForegroundVisual;
+ Size labelSize;
+
+ for ( int state = Button::UNSELECTED_STATE; state < Button::STATE_COUNT; state++)
+ {
+ Toolkit::Visual::Base visual = GetVisual( GET_VISUAL_INDEX_FOR_STATE[state][FOREGROUND] );
+ Size visualSize;
+ if ( visual )
+ {
+ visual.GetNaturalSize( visualSize );
+ largestForegroundVisual.width = std::max(largestForegroundVisual.width, visualSize.width );
+ largestForegroundVisual.height = std::max(largestForegroundVisual.height, visualSize.height );
+ }
+ }
+
+ // Get horizontal padding total
+ if ( largestForegroundVisual.width > 0 ) // if visual exists
+ {
+ size.width += largestForegroundVisual.width + mForegroundPadding.left + mForegroundPadding.right;
+ }
+ // Get vertical padding total
+ if ( largestForegroundVisual.height > 0 )
+ {
+ size.height += largestForegroundVisual.height + mForegroundPadding.top + mForegroundPadding.bottom;
+ }
+
+ DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize visual Size(%f,%f)\n",
+ largestForegroundVisual.width, largestForegroundVisual.height );
+
+ // Get natural size of label
+ if ( mLabel )
+ {
+ labelSize = Vector2( mLabel.GetNaturalSize());
+
+ DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize labelSize(%f,%f) padding(%f,%f)\n",
+ labelSize.width, labelSize.height, mLabelPadding.left + mLabelPadding.right, mLabelPadding.top + mLabelPadding.bottom);
+
+ labelSize.width += mLabelPadding.left + mLabelPadding.right;
+ labelSize.height += mLabelPadding.top + mLabelPadding.bottom;
+
+ // Add label size to height or width depending on alignment position
+ if ( horizontalAlignment )
+ {
+ size.width += labelSize.width;
+ size.height = std::max(size.height, labelSize.height );
+ }
+ else
+ {
+ size.height += labelSize.height;
+ size.width = std::max(size.width, labelSize.width );
+ }
+ }
+
+ if( size.width < 1 && size.height < 1 )
+ {
+ // if no image or label then use Control's natural size
+ DALI_LOG_INFO( gLogButtonFilter, Debug::General, "GetNaturalSize Using control natural size\n");
+ size = Control::GetNaturalSize();
+ }
+
+ DALI_LOG_INFO( gLogButtonFilter, Debug::General, "Button GetNaturalSize (%f,%f)\n", size.width, size.height );
+
+ return size;
+}
+
+void Button::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )