2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 "push-button-impl.h"
27 #include "push-button-default-painter-impl.h"
29 #include <dali-toolkit/public-api/controls/text-view/text-view.h>
37 const Property::Index PushButton::PROPERTY_AUTO_REPEATING = Internal::Button::BUTTON_PROPERTY_END_INDEX + 1;
38 const Property::Index PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY = Internal::Button::BUTTON_PROPERTY_END_INDEX + 2;
39 const Property::Index PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY = Internal::Button::BUTTON_PROPERTY_END_INDEX + 3;
40 const Property::Index PushButton::PROPERTY_TOGGLABLE = Internal::Button::BUTTON_PROPERTY_END_INDEX + 4;
41 const Property::Index PushButton::PROPERTY_TOGGLE = Internal::Button::BUTTON_PROPERTY_END_INDEX + 5;
42 const Property::Index PushButton::PROPERTY_NORMAL_STATE_ACTOR = Internal::Button::BUTTON_PROPERTY_END_INDEX + 6;
43 const Property::Index PushButton::PROPERTY_PRESSED_STATE_ACTOR = Internal::Button::BUTTON_PROPERTY_END_INDEX + 7;
44 const Property::Index PushButton::PROPERTY_DIMMED_STATE_ACTOR = Internal::Button::BUTTON_PROPERTY_END_INDEX + 8;
45 const Property::Index PushButton::PROPERTY_LABEL_ACTOR = Internal::Button::BUTTON_PROPERTY_END_INDEX + 9;
55 return Toolkit::PushButton::New();
58 TypeRegistration typeRegistration( typeid(Toolkit::PushButton), typeid(Toolkit::Button), Create );
60 SignalConnectorType signalConnector1( typeRegistration, Toolkit::PushButton::SIGNAL_TOGGLED , &PushButton::DoConnectSignal );
61 SignalConnectorType signalConnector2( typeRegistration, Toolkit::PushButton::SIGNAL_PRESSED , &PushButton::DoConnectSignal );
62 SignalConnectorType signalConnector3( typeRegistration, Toolkit::PushButton::SIGNAL_RELEASED, &PushButton::DoConnectSignal );
64 TypeAction action1( typeRegistration, Toolkit::PushButton::ACTION_PUSH_BUTTON_CLICK, &PushButton::DoAction );
66 PropertyRegistration property1( typeRegistration, "auto-repeating", Toolkit::PushButton::PROPERTY_AUTO_REPEATING, Property::BOOLEAN, &PushButton::SetProperty, &PushButton::GetProperty );
67 PropertyRegistration property2( typeRegistration, "initial-auto-repeating-delay", Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY, Property::FLOAT, &PushButton::SetProperty, &PushButton::GetProperty );
68 PropertyRegistration property3( typeRegistration, "next-auto-repeating-delay", Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY, Property::FLOAT, &PushButton::SetProperty, &PushButton::GetProperty );
69 PropertyRegistration property4( typeRegistration, "togglable", Toolkit::PushButton::PROPERTY_TOGGLABLE, Property::BOOLEAN, &PushButton::SetProperty, &PushButton::GetProperty );
70 PropertyRegistration property5( typeRegistration, "toggle", Toolkit::PushButton::PROPERTY_TOGGLE, Property::BOOLEAN, &PushButton::SetProperty, &PushButton::GetProperty );
71 PropertyRegistration property6( typeRegistration, "normal-state-actor", Toolkit::PushButton::PROPERTY_NORMAL_STATE_ACTOR, Property::MAP, &PushButton::SetProperty, &PushButton::GetProperty );
72 PropertyRegistration property7( typeRegistration, "pressed-state-actor", Toolkit::PushButton::PROPERTY_PRESSED_STATE_ACTOR, Property::MAP, &PushButton::SetProperty, &PushButton::GetProperty );
73 PropertyRegistration property8( typeRegistration, "dimmed-state-actor", Toolkit::PushButton::PROPERTY_DIMMED_STATE_ACTOR, Property::MAP, &PushButton::SetProperty, &PushButton::GetProperty );
74 PropertyRegistration property9( typeRegistration, "label-actor", Toolkit::PushButton::PROPERTY_LABEL_ACTOR, Property::MAP, &PushButton::SetProperty, &PushButton::GetProperty );
76 } // unnamed namespace
81 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
82 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
84 // Helper function used to cast a ButtonPainter to PushButtonDefaultPainter
85 PushButtonDefaultPainterPtr GetPushButtonPainter( Dali::Toolkit::Internal::ButtonPainterPtr painter )
87 return static_cast<PushButtonDefaultPainter*>( painter.Get() );
90 } // unnamed namespace
92 Dali::Toolkit::PushButton PushButton::New()
94 // Create the implementation, temporarily owned on stack
95 IntrusivePtr< PushButton > internalPushButton = new PushButton();
97 // Pass ownership to CustomActor
98 Dali::Toolkit::PushButton pushButton( *internalPushButton );
100 // Second-phase init of the implementation
101 // This can only be done after the CustomActor connection has been made...
102 internalPushButton->Initialize();
107 void PushButton::SetAutoRepeating( bool autoRepeating )
109 mAutoRepeating = autoRepeating;
111 // An autorepeating button can't be a toggle button.
114 mToggleButton = false;
117 // Emit a signal is not wanted, only change the appearance.
118 Toolkit::PushButton handle( GetOwner() );
119 GetPushButtonPainter( mPainter )->Toggled( handle );
124 // Notifies the painter.
125 GetPushButtonPainter( mPainter )->SetAutoRepeating( mAutoRepeating );
128 bool PushButton::IsAutoRepeating() const
130 return mAutoRepeating;
133 void PushButton::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
135 DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
136 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
139 float PushButton::GetInitialAutoRepeatingDelay() const
141 return mInitialAutoRepeatingDelay;
144 void PushButton::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
146 DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
147 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
150 float PushButton::GetNextAutoRepeatingDelay() const
152 return mNextAutoRepeatingDelay;
155 void PushButton::SetToggleButton( bool toggle )
157 mToggleButton = toggle;
159 // A toggle button can't be an autorepeating button.
162 mAutoRepeating = false;
164 // Notifies the painter.
165 GetPushButtonPainter( mPainter )->SetAutoRepeating( mAutoRepeating );
169 bool PushButton::IsToggleButton() const
171 return mToggleButton;
174 void PushButton::SetToggled( bool toggle )
176 if( !mDimmed && mToggleButton && ( toggle != mToggled ) )
180 Toolkit::PushButton handle( GetOwner() );
182 // Notifies the painter the button has been toggled.
183 GetPushButtonPainter( mPainter )->Toggled( handle );
186 mToggledSignalV2.Emit( handle, mToggled );
190 bool PushButton::IsToggled() const
192 return mToggleButton && mToggled;
195 void PushButton::SetButtonImage( Image image )
197 SetButtonImage( ImageActor::New( image ) );
200 void PushButton::SetButtonImage( Actor image )
202 Toolkit::PushButton handle( GetOwner() );
203 GetPushButtonPainter( mPainter )->SetButtonImage( handle, image );
206 Actor& PushButton::GetButtonImage()
211 Actor PushButton::GetButtonImage() const
216 void PushButton::SetBackgroundImage( Image image )
218 SetBackgroundImage( ImageActor::New( image ) );
221 void PushButton::SetBackgroundImage( Actor image )
223 Toolkit::PushButton handle( GetOwner() );
224 GetPushButtonPainter( mPainter )->SetBackgroundImage( handle, image );
227 Actor& PushButton::GetBackgroundImage()
229 return mBackgroundImage;
232 Actor PushButton::GetBackgroundImage() const
234 return mBackgroundImage;
237 void PushButton::SetPressedImage( Image image )
239 SetPressedImage( ImageActor::New( image ) );
242 void PushButton::SetPressedImage( Actor image )
244 Toolkit::PushButton handle( GetOwner() );
245 GetPushButtonPainter( mPainter )->SetPressedImage( handle, image );
248 Actor& PushButton::GetPressedImage()
250 return mPressedImage;
253 Actor PushButton::GetPressedImage() const
255 return mPressedImage;
258 void PushButton::SetDimmedBackgroundImage( Image image )
260 SetDimmedBackgroundImage( ImageActor::New( image ) );
263 void PushButton::SetDimmedBackgroundImage( Actor image )
265 Toolkit::PushButton handle( GetOwner() );
266 GetPushButtonPainter( mPainter )->SetDimmedBackgroundImage( handle, image );
269 Actor& PushButton::GetDimmedBackgroundImage()
271 return mDimmedBackgroundImage;
274 Actor PushButton::GetDimmedBackgroundImage() const
276 return mDimmedBackgroundImage;
279 void PushButton::SetDimmedImage( Image image )
281 SetDimmedImage( ImageActor::New( image ) );
284 void PushButton::SetDimmedImage( Actor image )
286 Toolkit::PushButton handle( GetOwner() );
287 GetPushButtonPainter( mPainter )->SetDimmedImage( handle, image );
290 Actor& PushButton::GetDimmedImage()
295 Actor PushButton::GetDimmedImage() const
300 void PushButton::SetLabelText( const std::string& text )
302 Toolkit::TextView textView ( Toolkit::TextView::New( text ) );
303 textView.SetWidthExceedPolicy( Toolkit::TextView::ShrinkToFit ); // Make sure our text always fits inside the button
304 SetLabelText( textView );
307 void PushButton::SetLabelText( Actor text )
309 Toolkit::PushButton handle( GetOwner() );
310 GetPushButtonPainter( mPainter )->SetLabelText( handle, text );
313 Actor& PushButton::GetLabel()
318 Actor PushButton::GetLabelText() const
323 Actor& PushButton::GetFadeOutBackgroundImage()
325 return mFadeOutBackgroundImage;
328 Actor& PushButton::GetFadeOutButtonImage()
330 return mFadeOutButtonImage;
333 Toolkit::PushButton::ToggledSignalV2& PushButton::ToggledSignal()
335 return mToggledSignalV2;
338 Toolkit::PushButton::PressedSignalV2& PushButton::PressedSignal()
340 return mPressedSignalV2;
343 Toolkit::PushButton::ReleasedSignalV2& PushButton::ReleasedSignal()
345 return mReleasedSignalV2;
348 bool PushButton::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
350 Dali::BaseHandle handle( object );
352 bool connected( true );
353 Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
355 if( Toolkit::PushButton::SIGNAL_TOGGLED == signalName )
357 button.ToggledSignal().Connect( tracker, functor );
359 else if( Toolkit::PushButton::SIGNAL_PRESSED == signalName )
361 button.PressedSignal().Connect( tracker, functor );
363 else if( Toolkit::PushButton::SIGNAL_RELEASED == signalName )
365 button.ReleasedSignal().Connect( tracker, functor );
369 // signalName does not match any signal
376 void PushButton::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
378 Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
382 PushButton& pushButtonImpl( GetImplementation( pushButton ) );
384 switch ( propertyIndex )
386 case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
388 pushButtonImpl.SetAutoRepeating( value.Get< bool >() );
392 case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
394 pushButtonImpl.SetInitialAutoRepeatingDelay( value.Get< float >() );
398 case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
400 pushButtonImpl.SetNextAutoRepeatingDelay( value.Get< float >() );
404 case Toolkit::PushButton::PROPERTY_TOGGLABLE:
406 pushButtonImpl.SetToggleButton( value.Get< bool >() );
410 case Toolkit::PushButton::PROPERTY_TOGGLE:
412 pushButtonImpl.SetToggled( value.Get< bool >() );
416 case Toolkit::PushButton::PROPERTY_NORMAL_STATE_ACTOR:
418 pushButtonImpl.SetButtonImage( Scripting::NewActor( value.Get< Property::Map >() ) );
422 case Toolkit::PushButton::PROPERTY_PRESSED_STATE_ACTOR:
424 pushButtonImpl.SetPressedImage( Scripting::NewActor( value.Get< Property::Map >() ) );
428 case Toolkit::PushButton::PROPERTY_DIMMED_STATE_ACTOR:
430 pushButtonImpl.SetDimmedImage( Scripting::NewActor( value.Get< Property::Map >() ) );
434 case Toolkit::PushButton::PROPERTY_LABEL_ACTOR:
436 pushButtonImpl.SetLabelText( Scripting::NewActor( value.Get< Property::Map >() ) );
443 Property::Value PushButton::GetProperty( BaseObject* object, Property::Index propertyIndex )
445 Property::Value value;
447 Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
451 PushButton& pushButtonImpl( GetImplementation( pushButton ) );
453 switch ( propertyIndex )
455 case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
457 value = pushButtonImpl.mAutoRepeating;
461 case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
463 value = pushButtonImpl.mInitialAutoRepeatingDelay;
467 case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
469 value = pushButtonImpl.mNextAutoRepeatingDelay;
473 case Toolkit::PushButton::PROPERTY_TOGGLABLE:
475 value = pushButtonImpl.mToggleButton;
479 case Toolkit::PushButton::PROPERTY_TOGGLE:
481 value = pushButtonImpl.mToggled;
485 case Toolkit::PushButton::PROPERTY_NORMAL_STATE_ACTOR:
488 Scripting::CreatePropertyMap( pushButtonImpl.mButtonImage, map );
493 case Toolkit::PushButton::PROPERTY_PRESSED_STATE_ACTOR:
496 Scripting::CreatePropertyMap( pushButtonImpl.mPressedImage, map );
501 case Toolkit::PushButton::PROPERTY_DIMMED_STATE_ACTOR:
504 Scripting::CreatePropertyMap( pushButtonImpl.mDimmedImage, map );
509 case Toolkit::PushButton::PROPERTY_LABEL_ACTOR:
512 Scripting::CreatePropertyMap( pushButtonImpl.mLabel, map );
522 void PushButton::OnButtonInitialize()
524 // Push button requires the Leave event.
526 root.SetLeaveRequired( true );
529 void PushButton::OnButtonDown()
533 Toolkit::PushButton handle( GetOwner() );
535 // Notifies the painter the button has been pressed.
536 GetPushButtonPainter( mPainter )->Pressed( handle );
540 SetUpTimer( mInitialAutoRepeatingDelay );
544 mPressedSignalV2.Emit( handle );
548 void PushButton::OnButtonUp()
550 if( ButtonDown == mState )
554 mToggled = !mToggled;
556 Toolkit::PushButton handle( GetOwner() );
558 // Notifies the painter the button has been toggled.
559 GetPushButtonPainter( mPainter )->Toggled( handle );
562 mToggledSignalV2.Emit( handle, mToggled );
566 Toolkit::PushButton handle( GetOwner() );
568 // Notifies the painter the button has been clicked.
569 GetPushButtonPainter( mPainter )->Released( handle );
570 GetPushButtonPainter( mPainter )->Clicked( handle );
574 mAutoRepeatingTimer.Reset();
578 mReleasedSignalV2.Emit( handle );
579 mClickedSignalV2.Emit( handle );
584 void PushButton::OnTouchPointLeave()
586 if( ButtonDown == mState )
590 Toolkit::PushButton handle( GetOwner() );
592 // Notifies the painter the button has been released.
593 GetPushButtonPainter( mPainter )->Released( handle );
597 mAutoRepeatingTimer.Reset();
601 mReleasedSignalV2.Emit( handle );
606 void PushButton::OnTouchPointInterrupted()
611 void PushButton::OnAnimationTimeSet( float animationTime )
613 GetPushButtonPainter( mPainter )->SetAnimationTime( animationTime );
616 float PushButton::OnAnimationTimeRequested() const
618 return GetPushButtonPainter( mPainter )->GetAnimationTime();
621 PushButton::PushButton()
623 mAutoRepeating( false ),
624 mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
625 mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
626 mToggleButton( false ),
627 mAutoRepeatingTimer(),
629 mClickActionPerforming(false)
631 // Creates specific painter.
632 mPainter = PushButtonDefaultPainterPtr( new PushButtonDefaultPainter() );
635 PushButton::~PushButton()
637 if( mAutoRepeatingTimer )
639 mAutoRepeatingTimer.Reset();
645 void PushButton::SetUpTimer( float delay )
647 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
648 mAutoRepeatingTimer.TickSignal().Connect( this, &PushButton::AutoRepeatingSlot );
649 mAutoRepeatingTimer.Start();
652 bool PushButton::AutoRepeatingSlot()
654 bool consumed = false;
657 // Restart the autorepeat timer.
658 SetUpTimer( mNextAutoRepeatingDelay );
660 Toolkit::PushButton handle( GetOwner() );
662 // Notifies the painter the button has been pressed.
663 GetPushButtonPainter( mPainter )->Pressed( handle );
666 consumed = mReleasedSignalV2.Emit( handle );
667 consumed |= mClickedSignalV2.Emit( handle );
668 consumed |= mPressedSignalV2.Emit( handle );
674 void PushButton::OnActivated()
676 // When the button is activated, it performs the click action
677 std::vector<Property::Value> attributes;
678 DoClickAction(attributes);
681 void PushButton::DoClickAction(const PropertyValueContainer& attributes)
683 // Prevents the button signals from doing a recursive loop by sending an action
684 // and re-emitting the signals.
685 if(!mClickActionPerforming)
687 mClickActionPerforming = true;
691 mClickActionPerforming = false;
695 bool PushButton::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
699 Dali::BaseHandle handle(object);
701 Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
703 DALI_ASSERT_ALWAYS(button);
705 if(Toolkit::PushButton::ACTION_PUSH_BUTTON_CLICK == actionName)
707 GetImplementation(button).DoClickAction(attributes);
714 } // namespace Internal
716 } // namespace Toolkit