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 <dali/public-api/events/touch-event.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/actors/image-actor.h>
25 #include <dali/public-api/scripting/scripting.h>
28 #include <dali-toolkit/public-api/controls/text-view/text-view.h>
36 const Property::Index Button::PROPERTY_DISABLED = Internal::Button::BUTTON_PROPERTY_START_INDEX;
37 const Property::Index Button::PROPERTY_AUTO_REPEATING = Internal::Button::BUTTON_PROPERTY_START_INDEX + 1;
38 const Property::Index Button::PROPERTY_INITIAL_AUTO_REPEATING_DELAY = Internal::Button::BUTTON_PROPERTY_START_INDEX + 2;
39 const Property::Index Button::PROPERTY_NEXT_AUTO_REPEATING_DELAY = Internal::Button::BUTTON_PROPERTY_START_INDEX + 3;
40 const Property::Index Button::PROPERTY_TOGGLABLE = Internal::Button::BUTTON_PROPERTY_START_INDEX + 4;
41 const Property::Index Button::PROPERTY_SELECTED = Internal::Button::BUTTON_PROPERTY_START_INDEX + 5;
42 const Property::Index Button::PROPERTY_NORMAL_STATE_ACTOR = Internal::Button::BUTTON_PROPERTY_START_INDEX + 6;
43 const Property::Index Button::PROPERTY_SELECTED_STATE_ACTOR = Internal::Button::BUTTON_PROPERTY_START_INDEX + 7;
44 const Property::Index Button::PROPERTY_DISABLED_STATE_ACTOR = Internal::Button::BUTTON_PROPERTY_START_INDEX + 8;
45 const Property::Index Button::PROPERTY_LABEL_ACTOR = Internal::Button::BUTTON_PROPERTY_START_INDEX + 9;
53 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
54 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
58 const char* const SIGNAL_PRESSED = "pressed";
59 const char* const SIGNAL_RELEASED = "released";
60 const char* const SIGNAL_CLICKED = "clicked";
61 const char* const SIGNAL_STATE_CHANGED = "state-changed";
65 const char* const ACTION_BUTTON_CLICK = "button-click";
69 // empty handle as we cannot create button (but type registered for clicked signal)
73 TypeRegistration typeRegistration( typeid( Toolkit::Button ), typeid( Toolkit::Control ), Create );
75 SignalConnectorType signalConnector1( typeRegistration, SIGNAL_PRESSED , &Button::DoConnectSignal );
76 SignalConnectorType signalConnector2( typeRegistration, SIGNAL_RELEASED, &Button::DoConnectSignal );
77 SignalConnectorType signalConnector3( typeRegistration, SIGNAL_CLICKED, &Button::DoConnectSignal );
78 SignalConnectorType signalConnector4( typeRegistration, SIGNAL_STATE_CHANGED, &Button::DoConnectSignal );
80 TypeAction action1( typeRegistration, ACTION_BUTTON_CLICK, &Button::DoAction );
82 PropertyRegistration property1( typeRegistration, "disabled", Toolkit::Button::PROPERTY_DISABLED, Property::BOOLEAN, &Button::SetProperty, &Button::GetProperty );
83 PropertyRegistration property2( typeRegistration, "auto-repeating", Toolkit::Button::PROPERTY_AUTO_REPEATING, Property::BOOLEAN, &Button::SetProperty, &Button::GetProperty );
84 PropertyRegistration property3( typeRegistration, "initial-auto-repeating-delay", Toolkit::Button::PROPERTY_INITIAL_AUTO_REPEATING_DELAY, Property::FLOAT, &Button::SetProperty, &Button::GetProperty );
85 PropertyRegistration property4( typeRegistration, "next-auto-repeating-delay", Toolkit::Button::PROPERTY_NEXT_AUTO_REPEATING_DELAY, Property::FLOAT, &Button::SetProperty, &Button::GetProperty );
86 PropertyRegistration property5( typeRegistration, "togglable", Toolkit::Button::PROPERTY_TOGGLABLE, Property::BOOLEAN, &Button::SetProperty, &Button::GetProperty );
87 PropertyRegistration property6( typeRegistration, "selected", Toolkit::Button::PROPERTY_SELECTED, Property::BOOLEAN, &Button::SetProperty, &Button::GetProperty );
88 PropertyRegistration property7( typeRegistration, "normal-state-actor", Toolkit::Button::PROPERTY_NORMAL_STATE_ACTOR, Property::MAP, &Button::SetProperty, &Button::GetProperty );
89 PropertyRegistration property8( typeRegistration, "selected-state-actor", Toolkit::Button::PROPERTY_SELECTED_STATE_ACTOR, Property::MAP, &Button::SetProperty, &Button::GetProperty );
90 PropertyRegistration property9( typeRegistration, "disabled-state-actor", Toolkit::Button::PROPERTY_DISABLED_STATE_ACTOR, Property::MAP, &Button::SetProperty, &Button::GetProperty );
91 PropertyRegistration property10( typeRegistration, "label-actor", Toolkit::Button::PROPERTY_LABEL_ACTOR, Property::MAP, &Button::SetProperty, &Button::GetProperty );
93 } // unnamed namespace
96 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
97 mTogglableButton( false ),
100 mAutoRepeatingTimer(),
102 mAutoRepeating( false ),
103 // mTogglableButton( false ),
104 // mSelected( false ),
105 mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
106 mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
107 mClickActionPerforming( false ),
114 if( mAutoRepeatingTimer )
116 mAutoRepeatingTimer.Reset();
120 void Button::SetDisabled( bool disabled )
122 mDisabled = disabled;
124 // Notifies the painter.
125 Toolkit::Button handle( GetOwner() );
128 mPainter->SetDisabled( handle, mDisabled );
132 bool Button::IsDisabled() const
137 void Button::SetAutoRepeating( bool autoRepeating )
139 mAutoRepeating = autoRepeating;
141 // An autorepeating button can't be a togglable button.
144 mTogglableButton = false;
147 // Emit a signal is not wanted, only change the appearance.
148 Toolkit::Button handle( GetOwner() );
149 mPainter->Selected( handle );
154 // Notifies the painter.
155 mPainter->SetAutoRepeating( mAutoRepeating );
158 bool Button::IsAutoRepeating() const
160 return mAutoRepeating;
163 void Button::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
165 DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
166 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
169 float Button::GetInitialAutoRepeatingDelay() const
171 return mInitialAutoRepeatingDelay;
174 void Button::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
176 DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
177 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
180 float Button::GetNextAutoRepeatingDelay() const
182 return mNextAutoRepeatingDelay;
185 void Button::SetTogglableButton( bool togglable )
187 mTogglableButton = togglable;
189 // A togglable button can't be an autorepeating button.
192 mAutoRepeating = false;
194 // Notifies the painter.
195 mPainter->SetAutoRepeating( mAutoRepeating );
199 bool Button::IsTogglableButton() const
201 return mTogglableButton;
204 void Button::SetSelected( bool selected )
206 if( !mDisabled && mTogglableButton && ( selected != mSelected ) )
208 mSelected = selected;
210 Toolkit::Button handle( GetOwner() );
212 // Notifies the painter the button has been selected.
213 mPainter->Selected( handle );
216 mStateChangedSignal.Emit( handle );
220 bool Button::IsSelected() const
222 return mTogglableButton && mSelected;
225 void Button::SetAnimationTime( float animationTime )
227 OnAnimationTimeSet( animationTime );
230 float Button::GetAnimationTime() const
232 return OnAnimationTimeRequested();
235 void Button::SetLabel( const std::string& label )
237 Toolkit::TextView textView = Toolkit::TextView::New( label );
238 textView.SetWidthExceedPolicy( Toolkit::TextView::ShrinkToFit ); // Make sure our text always fits inside the button
239 SetLabel( textView );
244 void Button::SetLabel( Actor label )
246 Toolkit::Button handle( GetOwner() );
248 mPainter->SetLabel( handle, label );
251 Actor Button::GetLabel() const
256 Actor& Button::GetLabel()
261 void Button::SetButtonImage( Image image )
263 SetButtonImage( ImageActor::New( image ) );
266 void Button::SetButtonImage( Actor image )
268 Toolkit::Button handle( GetOwner() );
269 mPainter->SetButtonImage( handle, image );
272 Actor Button::GetButtonImage() const
277 Actor& Button::GetButtonImage()
282 void Button::SetSelectedImage( Image image )
284 SetSelectedImage( ImageActor::New( image ) );
287 void Button::SetSelectedImage( Actor image )
289 Toolkit::Button handle( GetOwner() );
290 mPainter->SetSelectedImage( handle, image );
293 Actor Button::GetSelectedImage() const
295 return mSelectedImage;
298 Actor& Button::GetSelectedImage()
300 return mSelectedImage;
303 void Button::SetBackgroundImage( Image image )
305 SetBackgroundImage( ImageActor::New( image ) );
308 void Button::SetBackgroundImage( Actor image )
310 Toolkit::Button handle( GetOwner() );
311 mPainter->SetBackgroundImage( handle, image );
314 Actor Button::GetBackgroundImage() const
316 return mBackgroundImage;
319 Actor& Button::GetBackgroundImage()
321 return mBackgroundImage;
324 void Button::SetDisabledImage( Image image )
326 SetDisabledImage( ImageActor::New( image ) );
329 void Button::SetDisabledImage( Actor image )
331 Toolkit::Button handle( GetOwner() );
332 mPainter->SetDisabledImage( handle, image );
335 Actor Button::GetDisabledImage() const
337 return mDisabledImage;
340 Actor& Button::GetDisabledImage()
342 return mDisabledImage;
345 void Button::SetDisabledSelectedImage( Image image )
347 SetDisabledSelectedImage( ImageActor::New( image ) );
350 void Button::SetDisabledSelectedImage( Actor image )
352 Toolkit::Button handle( GetOwner() );
353 mPainter->SetDisabledSelectedImage( handle, image );
356 Actor Button::GetDisabledSelectedImage() const
358 return mDisabledSelectedImage;
361 Actor& Button::GetDisabledSelectedImage()
363 return mDisabledSelectedImage;
366 void Button::SetDisabledBackgroundImage( Image image )
368 SetDisabledBackgroundImage( ImageActor::New( image ) );
371 void Button::SetDisabledBackgroundImage( Actor image )
373 Toolkit::Button handle( GetOwner() );
374 mPainter->SetDisabledBackgroundImage( handle, image );
377 Actor Button::GetDisabledBackgroundImage() const
379 return mDisabledBackgroundImage;
382 Actor& Button::GetDisabledBackgroundImage()
384 return mDisabledBackgroundImage;
387 Actor& Button::GetFadeOutButtonImage()
389 return mFadeOutButtonImage;
392 Actor& Button::GetFadeOutSelectedImage()
394 return mFadeOutSelectedImage;
397 Actor& Button::GetFadeOutBackgroundImage()
399 return mFadeOutBackgroundImage;
402 bool Button::DoAction( BaseObject* object, const std::string& actionName, const PropertyValueContainer& attributes )
406 Dali::BaseHandle handle( object );
408 Toolkit::Button button = Toolkit::Button::DownCast( handle );
410 DALI_ASSERT_ALWAYS( button );
412 if( 0 == strcmp( actionName.c_str(), ACTION_BUTTON_CLICK ) )
414 GetImplementation( button ).DoClickAction( attributes );
421 void Button::DoClickAction( const PropertyValueContainer& attributes )
423 // Prevents the button signals from doing a recursive loop by sending an action
424 // and re-emitting the signals.
425 if( !mClickActionPerforming )
427 mClickActionPerforming = true;
431 mClickActionPerforming = false;
435 void Button::OnAnimationTimeSet( float animationTime )
437 mPainter->SetAnimationTime( animationTime );
440 float Button::OnAnimationTimeRequested() const
442 return mPainter->GetAnimationTime();
445 void Button::OnButtonStageDisconnection()
447 if( ButtonDown == mState )
449 if( !mTogglableButton )
451 Toolkit::Button handle( GetOwner() );
453 // Notifies the painter the button has been released.
454 mPainter->Released( handle );
458 mAutoRepeatingTimer.Reset();
464 void Button::OnButtonDown()
466 if( !mTogglableButton )
468 Toolkit::Button handle( GetOwner() );
470 // Notifies the painter the button has been pressed.
471 mPainter->Pressed( handle );
475 SetUpTimer( mInitialAutoRepeatingDelay );
479 mPressedSignal.Emit( handle );
483 void Button::OnButtonUp()
485 if( ButtonDown == mState )
487 if( mTogglableButton )
489 SetSelected( !mSelected );
493 Toolkit::Button handle( GetOwner() );
495 // Notifies the painter the button has been clicked.
496 mPainter->Released( handle );
497 mPainter->Clicked( handle );
501 mAutoRepeatingTimer.Reset();
505 mReleasedSignal.Emit( handle );
506 mClickedSignal.Emit( handle );
511 void Button::OnTouchPointLeave()
513 if( ButtonDown == mState )
515 if( !mTogglableButton )
517 Toolkit::Button handle( GetOwner() );
519 // Notifies the painter the button has been released.
520 mPainter->Released( handle );
524 mAutoRepeatingTimer.Reset();
528 mReleasedSignal.Emit( handle );
533 void Button::OnTouchPointInterrupted()
538 Toolkit::Button::ButtonSignalType& Button::PressedSignal()
540 return mPressedSignal;
543 Toolkit::Button::ButtonSignalType& Button::ReleasedSignal()
545 return mReleasedSignal;
548 Toolkit::Button::ButtonSignalType& Button::ClickedSignal()
550 return mClickedSignal;
553 Toolkit::Button::ButtonSignalType& Button::StateChangedSignal()
555 return mStateChangedSignal;
558 bool Button::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
560 Dali::BaseHandle handle( object );
562 bool connected( true );
563 Toolkit::Button button = Toolkit::Button::DownCast( handle );
565 if( 0 == strcmp( signalName.c_str(), SIGNAL_PRESSED ) )
567 button.PressedSignal().Connect( tracker, functor );
569 else if( 0 == strcmp( signalName.c_str(), SIGNAL_RELEASED ) )
571 button.ReleasedSignal().Connect( tracker, functor );
573 else if( 0 == strcmp( signalName.c_str(), SIGNAL_CLICKED ) )
575 button.ClickedSignal().Connect( tracker, functor );
577 else if( 0 == strcmp( signalName.c_str(), SIGNAL_STATE_CHANGED ) )
579 button.StateChangedSignal().Connect( tracker, functor );
583 // signalName does not match any signal
590 bool Button::OnTouchEvent(const TouchEvent& event)
592 // Only events are processed when the button is not disabled and the touch event has only
594 if( ( !mDisabled ) && ( 1 == event.GetPointCount() ) )
596 switch( event.GetPoint(0).state )
598 case TouchPoint::Down:
600 OnButtonDown(); // Notification for derived classes.
602 // Sets the button state to ButtonDown.
608 OnButtonUp(); // Notification for derived classes.
610 // Sets the button state to ButtonUp.
614 case TouchPoint::Interrupted:
616 OnTouchPointInterrupted(); // Notification for derived classes.
618 // Sets the button state to the default (ButtonUp).
622 case TouchPoint::Leave:
624 OnTouchPointLeave(); // Notification for derived classes.
626 // Sets the button state to the default (ButtonUp).
630 case TouchPoint::Motion:
631 case TouchPoint::Stationary: // FALLTHROUGH
638 DALI_ASSERT_ALWAYS( !"Point status unhandled." );
643 else if( 1 < event.GetPointCount() )
645 OnTouchPointLeave(); // Notification for derived classes.
647 // Sets the button state to the default (ButtonUp).
654 void Button::OnInitialize()
656 // Initialize the painter and notifies subclasses.
657 Toolkit::Button handle( GetOwner() );
660 mPainter->Initialize( handle );
665 mTapDetector = TapGestureDetector::New();
666 mTapDetector.Attach( self );
667 mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
669 OnButtonInitialize();
671 self.SetKeyboardFocusable( true );
674 void Button::OnActivated()
676 // When the button is activated, it performs the click action
677 PropertyValueContainer attributes;
678 DoClickAction( attributes );
681 void Button::OnControlSizeSet(const Vector3& targetSize)
683 Toolkit::Button handle( GetOwner() );
686 mPainter->SetSize( handle, targetSize );
690 void Button::OnTap(Actor actor, const TapGesture& tap)
695 void Button::SetUpTimer( float delay )
697 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
698 mAutoRepeatingTimer.TickSignal().Connect( this, &Button::AutoRepeatingSlot );
699 mAutoRepeatingTimer.Start();
702 bool Button::AutoRepeatingSlot()
704 bool consumed = false;
707 // Restart the autorepeat timer.
708 SetUpTimer( mNextAutoRepeatingDelay );
710 Toolkit::Button handle( GetOwner() );
712 // Notifies the painter the button has been pressed.
713 mPainter->Pressed( handle );
716 consumed = mReleasedSignal.Emit( handle );
717 consumed |= mClickedSignal.Emit( handle );
718 consumed |= mPressedSignal.Emit( handle );
724 void Button::OnControlStageDisconnection()
726 OnButtonStageDisconnection(); // Notification for derived classes.
730 void Button::SetPainter(ButtonPainterPtr painter)
735 Button::ButtonState Button::GetState()
740 void Button::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
742 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
748 case Toolkit::Button::PROPERTY_DISABLED:
750 GetImplementation( button ).SetDisabled( value.Get<bool>() );
754 case Toolkit::Button::PROPERTY_AUTO_REPEATING:
756 GetImplementation( button ).SetAutoRepeating( value.Get< bool >() );
760 case Toolkit::Button::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
762 GetImplementation( button ).SetInitialAutoRepeatingDelay( value.Get< float >() );
766 case Toolkit::Button::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
768 GetImplementation( button ).SetNextAutoRepeatingDelay( value.Get< float >() );
772 case Toolkit::Button::PROPERTY_TOGGLABLE:
774 GetImplementation( button ).SetTogglableButton( value.Get< bool >() );
778 case Toolkit::Button::PROPERTY_SELECTED:
780 GetImplementation( button ).SetSelected( value.Get< bool >() );
784 case Toolkit::Button::PROPERTY_NORMAL_STATE_ACTOR:
786 GetImplementation( button ).SetButtonImage( Scripting::NewActor( value.Get< Property::Map >() ) );
790 case Toolkit::Button::PROPERTY_SELECTED_STATE_ACTOR:
792 GetImplementation( button ).SetSelectedImage( Scripting::NewActor( value.Get< Property::Map >() ) );
796 case Toolkit::Button::PROPERTY_DISABLED_STATE_ACTOR:
798 GetImplementation( button ).SetDisabledImage( Scripting::NewActor( value.Get< Property::Map >() ) );
802 case Toolkit::Button::PROPERTY_LABEL_ACTOR:
804 GetImplementation( button ).SetLabel( Scripting::NewActor( value.Get< Property::Map >() ) );
811 Property::Value Button::GetProperty( BaseObject* object, Property::Index propertyIndex )
813 Property::Value value;
815 Toolkit::Button button = Toolkit::Button::DownCast( Dali::BaseHandle( object ) );
819 switch ( propertyIndex )
821 case Toolkit::Button::PROPERTY_DISABLED:
823 value = GetImplementation( button ).mDisabled;
827 case Toolkit::Button::PROPERTY_AUTO_REPEATING:
829 value = GetImplementation( button ).mAutoRepeating;
833 case Toolkit::Button::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
835 value = GetImplementation( button ).mInitialAutoRepeatingDelay;
839 case Toolkit::Button::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
841 value = GetImplementation( button ).mNextAutoRepeatingDelay;
845 case Toolkit::Button::PROPERTY_TOGGLABLE:
847 value = GetImplementation( button ).mTogglableButton;
851 case Toolkit::Button::PROPERTY_SELECTED:
853 value = GetImplementation( button ).mSelected;
857 case Toolkit::Button::PROPERTY_NORMAL_STATE_ACTOR:
860 Scripting::CreatePropertyMap( GetImplementation( button ).mButtonImage, map );
865 case Toolkit::Button::PROPERTY_SELECTED_STATE_ACTOR:
868 Scripting::CreatePropertyMap( GetImplementation( button ).mSelectedImage, map );
873 case Toolkit::Button::PROPERTY_DISABLED_STATE_ACTOR:
876 Scripting::CreatePropertyMap( GetImplementation( button ).mDisabledImage, map );
881 case Toolkit::Button::PROPERTY_LABEL_ACTOR:
884 Scripting::CreatePropertyMap( GetImplementation( button ).mLabel, map );
894 } // namespace Internal
896 } // namespace Toolkit