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_BUTTON_IMAGE = Internal::Button::BUTTON_PROPERTY_END_INDEX + 6;
43 const Property::Index PushButton::PROPERTY_PRESSED_IMAGE = Internal::Button::BUTTON_PROPERTY_END_INDEX + 8;
44 const Property::Index PushButton::PROPERTY_DIMMED_IMAGE = Internal::Button::BUTTON_PROPERTY_END_INDEX + 9;
45 const Property::Index PushButton::PROPERTY_LABEL_TEXT = Internal::Button::BUTTON_PROPERTY_END_INDEX + 11;
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, "button-image", Toolkit::PushButton::PROPERTY_BUTTON_IMAGE, Property::STRING, &PushButton::SetProperty, &PushButton::GetProperty );
72 PropertyRegistration property7( typeRegistration, "pressed-image", Toolkit::PushButton::PROPERTY_PRESSED_IMAGE, Property::STRING, &PushButton::SetProperty, &PushButton::GetProperty );
73 PropertyRegistration property8( typeRegistration, "dimmed-image", Toolkit::PushButton::PROPERTY_DIMMED_IMAGE, Property::STRING, &PushButton::SetProperty, &PushButton::GetProperty );
74 PropertyRegistration property9( typeRegistration, "label-text", Toolkit::PushButton::PROPERTY_LABEL_TEXT, Property::STRING, &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() );
91 * Helper function to checks if the specified actor is an ImageActor and if it has an Image with a path.
93 * @param[in] actor Actor handle to check.
94 * @param[out] path The image path will be applied to this parameter, if available.
95 * If not available then this will be an empty string.
97 void GetImageActorFilename( Actor& actor, std::string& path )
99 path = ""; // Just return an empty string if not using ImageActor with an image
103 ImageActor imageActor = ImageActor::DownCast( actor );
106 Image image = imageActor.GetImage();
109 path = image.GetFilename();
115 } // unnamed namespace
117 Dali::Toolkit::PushButton PushButton::New()
119 // Create the implementation, temporarily owned on stack
120 IntrusivePtr< PushButton > internalPushButton = new PushButton();
122 // Pass ownership to CustomActor
123 Dali::Toolkit::PushButton pushButton( *internalPushButton );
125 // Second-phase init of the implementation
126 // This can only be done after the CustomActor connection has been made...
127 internalPushButton->Initialize();
132 void PushButton::SetAutoRepeating( bool autoRepeating )
134 mAutoRepeating = autoRepeating;
136 // An autorepeating button can't be a toggle button.
139 mToggleButton = false;
142 // Emit a signal is not wanted, only change the appearance.
143 Toolkit::PushButton handle( GetOwner() );
144 GetPushButtonPainter( mPainter )->Toggled( handle );
149 // Notifies the painter.
150 GetPushButtonPainter( mPainter )->SetAutoRepeating( mAutoRepeating );
153 bool PushButton::IsAutoRepeating() const
155 return mAutoRepeating;
158 void PushButton::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
160 DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
161 mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
164 float PushButton::GetInitialAutoRepeatingDelay() const
166 return mInitialAutoRepeatingDelay;
169 void PushButton::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
171 DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
172 mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
175 float PushButton::GetNextAutoRepeatingDelay() const
177 return mNextAutoRepeatingDelay;
180 void PushButton::SetToggleButton( bool toggle )
182 mToggleButton = toggle;
184 // A toggle button can't be an autorepeating button.
187 mAutoRepeating = false;
189 // Notifies the painter.
190 GetPushButtonPainter( mPainter )->SetAutoRepeating( mAutoRepeating );
194 bool PushButton::IsToggleButton() const
196 return mToggleButton;
199 void PushButton::SetToggled( bool toggle )
201 if( !mDimmed && mToggleButton && ( toggle != mToggled ) )
205 Toolkit::PushButton handle( GetOwner() );
207 // Notifies the painter the button has been toggled.
208 GetPushButtonPainter( mPainter )->Toggled( handle );
211 mToggledSignalV2.Emit( handle, mToggled );
215 bool PushButton::IsToggled() const
217 return mToggleButton && mToggled;
220 void PushButton::SetButtonImage( Image image )
222 SetButtonImage( ImageActor::New( image ) );
225 void PushButton::SetButtonImage( Actor image )
227 Toolkit::PushButton handle( GetOwner() );
228 GetPushButtonPainter( mPainter )->SetButtonImage( handle, image );
231 Actor& PushButton::GetButtonImage()
236 Actor PushButton::GetButtonImage() const
241 void PushButton::SetBackgroundImage( Image image )
243 SetBackgroundImage( ImageActor::New( image ) );
246 void PushButton::SetBackgroundImage( Actor image )
248 Toolkit::PushButton handle( GetOwner() );
249 GetPushButtonPainter( mPainter )->SetBackgroundImage( handle, image );
252 Actor& PushButton::GetBackgroundImage()
254 return mBackgroundImage;
257 Actor PushButton::GetBackgroundImage() const
259 return mBackgroundImage;
262 void PushButton::SetPressedImage( Image image )
264 SetPressedImage( ImageActor::New( image ) );
267 void PushButton::SetPressedImage( Actor image )
269 Toolkit::PushButton handle( GetOwner() );
270 GetPushButtonPainter( mPainter )->SetPressedImage( handle, image );
273 Actor& PushButton::GetPressedImage()
275 return mPressedImage;
278 Actor PushButton::GetPressedImage() const
280 return mPressedImage;
283 void PushButton::SetDimmedBackgroundImage( Image image )
285 SetDimmedBackgroundImage( ImageActor::New( image ) );
288 void PushButton::SetDimmedBackgroundImage( Actor image )
290 Toolkit::PushButton handle( GetOwner() );
291 GetPushButtonPainter( mPainter )->SetDimmedBackgroundImage( handle, image );
294 Actor& PushButton::GetDimmedBackgroundImage()
296 return mDimmedBackgroundImage;
299 Actor PushButton::GetDimmedBackgroundImage() const
301 return mDimmedBackgroundImage;
304 void PushButton::SetDimmedImage( Image image )
306 SetDimmedImage( ImageActor::New( image ) );
309 void PushButton::SetDimmedImage( Actor image )
311 Toolkit::PushButton handle( GetOwner() );
312 GetPushButtonPainter( mPainter )->SetDimmedImage( handle, image );
315 Actor& PushButton::GetDimmedImage()
320 Actor PushButton::GetDimmedImage() const
325 void PushButton::SetLabelText( const std::string& text )
327 Toolkit::TextView textView ( Toolkit::TextView::New( text ) );
328 textView.SetWidthExceedPolicy( Toolkit::TextView::ShrinkToFit ); // Make sure our text always fits inside the button
329 SetLabelText( textView );
332 void PushButton::SetLabelText( Actor text )
334 Toolkit::PushButton handle( GetOwner() );
335 GetPushButtonPainter( mPainter )->SetLabelText( handle, text );
338 Actor& PushButton::GetLabel()
343 Actor PushButton::GetLabelText() const
348 Actor& PushButton::GetFadeOutBackgroundImage()
350 return mFadeOutBackgroundImage;
353 Actor& PushButton::GetFadeOutButtonImage()
355 return mFadeOutButtonImage;
358 Toolkit::PushButton::ToggledSignalV2& PushButton::ToggledSignal()
360 return mToggledSignalV2;
363 Toolkit::PushButton::PressedSignalV2& PushButton::PressedSignal()
365 return mPressedSignalV2;
368 Toolkit::PushButton::ReleasedSignalV2& PushButton::ReleasedSignal()
370 return mReleasedSignalV2;
373 bool PushButton::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
375 Dali::BaseHandle handle( object );
377 bool connected( true );
378 Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
380 if( Toolkit::PushButton::SIGNAL_TOGGLED == signalName )
382 button.ToggledSignal().Connect( tracker, functor );
384 else if( Toolkit::PushButton::SIGNAL_PRESSED == signalName )
386 button.PressedSignal().Connect( tracker, functor );
388 else if( Toolkit::PushButton::SIGNAL_RELEASED == signalName )
390 button.ReleasedSignal().Connect( tracker, functor );
394 // signalName does not match any signal
401 void PushButton::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
403 Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
407 PushButton& pushButtonImpl( GetImplementation( pushButton ) );
409 switch ( propertyIndex )
411 case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
413 pushButtonImpl.SetAutoRepeating( value.Get< bool >() );
417 case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
419 pushButtonImpl.SetInitialAutoRepeatingDelay( value.Get< float >() );
423 case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
425 pushButtonImpl.SetNextAutoRepeatingDelay( value.Get< float >() );
429 case Toolkit::PushButton::PROPERTY_TOGGLABLE:
431 pushButtonImpl.SetToggleButton( value.Get< bool >() );
435 case Toolkit::PushButton::PROPERTY_TOGGLE:
437 pushButtonImpl.SetToggled( value.Get< bool >() );
441 case Toolkit::PushButton::PROPERTY_BUTTON_IMAGE:
443 Image image = Image::New( value.Get<std::string>() );
444 pushButtonImpl.SetButtonImage( image );
448 case Toolkit::PushButton::PROPERTY_PRESSED_IMAGE:
450 Image image = Image::New( value.Get<std::string>() );
451 pushButtonImpl.SetPressedImage( image );
455 case Toolkit::PushButton::PROPERTY_DIMMED_IMAGE:
457 Image image = Image::New( value.Get<std::string>() );
458 pushButtonImpl.SetDimmedImage( image );
462 case Toolkit::PushButton::PROPERTY_LABEL_TEXT:
464 pushButtonImpl.SetLabelText( value.Get< std::string >() );
471 Property::Value PushButton::GetProperty( BaseObject* object, Property::Index propertyIndex )
473 Property::Value value;
475 Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
479 PushButton& pushButtonImpl( GetImplementation( pushButton ) );
481 switch ( propertyIndex )
483 case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
485 value = pushButtonImpl.mAutoRepeating;
489 case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
491 value = pushButtonImpl.mInitialAutoRepeatingDelay;
495 case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
497 value = pushButtonImpl.mNextAutoRepeatingDelay;
501 case Toolkit::PushButton::PROPERTY_TOGGLABLE:
503 value = pushButtonImpl.mToggleButton;
507 case Toolkit::PushButton::PROPERTY_TOGGLE:
509 value = pushButtonImpl.mToggled;
513 case Toolkit::PushButton::PROPERTY_BUTTON_IMAGE:
516 GetImageActorFilename( pushButtonImpl.mButtonImage, path );
521 case Toolkit::PushButton::PROPERTY_PRESSED_IMAGE:
524 GetImageActorFilename( pushButtonImpl.mPressedImage, path );
529 case Toolkit::PushButton::PROPERTY_DIMMED_IMAGE:
532 GetImageActorFilename( pushButtonImpl.mDimmedImage, path );
537 case Toolkit::PushButton::PROPERTY_LABEL_TEXT:
539 value = ""; // Just return an empty string if not using a TextView
541 if ( pushButtonImpl.mLabel )
543 Toolkit::TextView textView = Toolkit::TextView::DownCast( pushButtonImpl.mLabel );
546 value = textView.GetText();
557 void PushButton::OnButtonInitialize()
559 // Push button requires the Leave event.
561 root.SetLeaveRequired( true );
564 void PushButton::OnButtonDown()
568 Toolkit::PushButton handle( GetOwner() );
570 // Notifies the painter the button has been pressed.
571 GetPushButtonPainter( mPainter )->Pressed( handle );
575 SetUpTimer( mInitialAutoRepeatingDelay );
579 mPressedSignalV2.Emit( handle );
583 void PushButton::OnButtonUp()
585 if( ButtonDown == mState )
589 mToggled = !mToggled;
591 Toolkit::PushButton handle( GetOwner() );
593 // Notifies the painter the button has been toggled.
594 GetPushButtonPainter( mPainter )->Toggled( handle );
597 mToggledSignalV2.Emit( handle, mToggled );
601 Toolkit::PushButton handle( GetOwner() );
603 // Notifies the painter the button has been clicked.
604 GetPushButtonPainter( mPainter )->Released( handle );
605 GetPushButtonPainter( mPainter )->Clicked( handle );
609 mAutoRepeatingTimer.Reset();
613 mReleasedSignalV2.Emit( handle );
614 mClickedSignalV2.Emit( handle );
619 void PushButton::OnTouchPointLeave()
621 if( ButtonDown == mState )
625 Toolkit::PushButton handle( GetOwner() );
627 // Notifies the painter the button has been released.
628 GetPushButtonPainter( mPainter )->Released( handle );
632 mAutoRepeatingTimer.Reset();
636 mReleasedSignalV2.Emit( handle );
641 void PushButton::OnTouchPointInterrupted()
646 void PushButton::OnAnimationTimeSet( float animationTime )
648 GetPushButtonPainter( mPainter )->SetAnimationTime( animationTime );
651 float PushButton::OnAnimationTimeRequested() const
653 return GetPushButtonPainter( mPainter )->GetAnimationTime();
656 PushButton::PushButton()
658 mAutoRepeating( false ),
659 mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
660 mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
661 mToggleButton( false ),
662 mAutoRepeatingTimer(),
664 mClickActionPerforming(false)
666 // Creates specific painter.
667 mPainter = PushButtonDefaultPainterPtr( new PushButtonDefaultPainter() );
670 PushButton::~PushButton()
672 if( mAutoRepeatingTimer )
674 mAutoRepeatingTimer.Reset();
680 void PushButton::SetUpTimer( float delay )
682 mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
683 mAutoRepeatingTimer.TickSignal().Connect( this, &PushButton::AutoRepeatingSlot );
684 mAutoRepeatingTimer.Start();
687 bool PushButton::AutoRepeatingSlot()
689 bool consumed = false;
692 // Restart the autorepeat timer.
693 SetUpTimer( mNextAutoRepeatingDelay );
695 Toolkit::PushButton handle( GetOwner() );
697 // Notifies the painter the button has been pressed.
698 GetPushButtonPainter( mPainter )->Pressed( handle );
701 consumed = mReleasedSignalV2.Emit( handle );
702 consumed |= mClickedSignalV2.Emit( handle );
703 consumed |= mPressedSignalV2.Emit( handle );
709 void PushButton::OnActivated()
711 // When the button is activated, it performs the click action
712 std::vector<Property::Value> attributes;
713 DoClickAction(attributes);
716 void PushButton::DoClickAction(const PropertyValueContainer& attributes)
718 // Prevents the button signals from doing a recursive loop by sending an action
719 // and re-emitting the signals.
720 if(!mClickActionPerforming)
722 mClickActionPerforming = true;
726 mClickActionPerforming = false;
730 bool PushButton::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
734 Dali::BaseHandle handle(object);
736 Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
738 DALI_ASSERT_ALWAYS(button);
740 if(Toolkit::PushButton::ACTION_PUSH_BUTTON_CLICK == actionName)
742 GetImplementation(button).DoClickAction(attributes);
749 } // namespace Internal
751 } // namespace Toolkit