8b96ba537f5eb5690be8df9e42e9fb8ead0a9523
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / buttons / push-button-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://floralicense.org/license/
9 //
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.
15 //
16
17 // CLASS HEADER
18
19 #include "push-button-impl.h"
20
21 // EXTERNAL INCLUDES
22
23 #include <algorithm>
24
25 // INTERNAL INCLUDES
26
27 #include "push-button-default-painter-impl.h"
28
29 #include <dali-toolkit/public-api/controls/text-view/text-view.h>
30
31 namespace Dali
32 {
33
34 namespace Toolkit
35 {
36
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;
46
47 namespace Internal
48 {
49
50 namespace
51 {
52
53 BaseHandle Create()
54 {
55   return Toolkit::PushButton::New();
56 }
57
58 TypeRegistration typeRegistration( typeid(Toolkit::PushButton), typeid(Toolkit::Button), Create );
59
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 );
63
64 TypeAction action1( typeRegistration, Toolkit::PushButton::ACTION_PUSH_BUTTON_CLICK, &PushButton::DoAction );
65
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 );
75
76 } // unnamed namespace
77
78 namespace
79 {
80
81 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
82 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
83
84 // Helper function used to cast a ButtonPainter to PushButtonDefaultPainter
85 PushButtonDefaultPainterPtr GetPushButtonPainter( Dali::Toolkit::Internal::ButtonPainterPtr painter )
86 {
87   return static_cast<PushButtonDefaultPainter*>( painter.Get() );
88 }
89
90 /**
91  * Helper function to checks if the specified actor is an ImageActor and if it has an Image with a path.
92  *
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.
96  */
97 void GetImageActorFilename( Actor& actor, std::string& path )
98 {
99   path = ""; // Just return an empty string if not using ImageActor with an image
100
101   if ( actor )
102   {
103     ImageActor imageActor = ImageActor::DownCast( actor );
104     if ( imageActor )
105     {
106       Image image = imageActor.GetImage();
107       if ( image )
108       {
109         path = image.GetFilename();
110       }
111     }
112   }
113 }
114
115 } // unnamed namespace
116
117 Dali::Toolkit::PushButton PushButton::New()
118 {
119   // Create the implementation, temporarily owned on stack
120   IntrusivePtr< PushButton > internalPushButton = new PushButton();
121
122   // Pass ownership to CustomActor
123   Dali::Toolkit::PushButton pushButton( *internalPushButton );
124
125   // Second-phase init of the implementation
126   // This can only be done after the CustomActor connection has been made...
127   internalPushButton->Initialize();
128
129   return pushButton;
130 }
131
132 void PushButton::SetAutoRepeating( bool autoRepeating )
133 {
134   mAutoRepeating = autoRepeating;
135
136   // An autorepeating button can't be a toggle button.
137   if( autoRepeating )
138   {
139     mToggleButton = false;
140     if( mToggled )
141     {
142       // Emit a signal is not wanted, only change the appearance.
143       Toolkit::PushButton handle( GetOwner() );
144       GetPushButtonPainter( mPainter )->Toggled( handle );
145       mToggled = false;
146     }
147   }
148
149   // Notifies the painter.
150   GetPushButtonPainter( mPainter )->SetAutoRepeating( mAutoRepeating );
151 }
152
153 bool PushButton::IsAutoRepeating() const
154 {
155   return mAutoRepeating;
156 }
157
158 void PushButton::SetInitialAutoRepeatingDelay( float initialAutoRepeatingDelay )
159 {
160   DALI_ASSERT_ALWAYS( initialAutoRepeatingDelay > 0.f );
161   mInitialAutoRepeatingDelay = initialAutoRepeatingDelay;
162 }
163
164 float PushButton::GetInitialAutoRepeatingDelay() const
165 {
166   return mInitialAutoRepeatingDelay;
167 }
168
169 void PushButton::SetNextAutoRepeatingDelay( float nextAutoRepeatingDelay )
170 {
171   DALI_ASSERT_ALWAYS( nextAutoRepeatingDelay > 0.f );
172   mNextAutoRepeatingDelay = nextAutoRepeatingDelay;
173 }
174
175 float PushButton::GetNextAutoRepeatingDelay() const
176 {
177   return mNextAutoRepeatingDelay;
178 }
179
180 void PushButton::SetToggleButton( bool toggle )
181 {
182   mToggleButton = toggle;
183
184   // A toggle button can't be an autorepeating button.
185   if( toggle )
186   {
187     mAutoRepeating = false;
188
189     // Notifies the painter.
190     GetPushButtonPainter( mPainter )->SetAutoRepeating( mAutoRepeating );
191   }
192 }
193
194 bool PushButton::IsToggleButton() const
195 {
196   return mToggleButton;
197 }
198
199 void PushButton::SetToggled( bool toggle )
200 {
201   if( !mDimmed && mToggleButton && ( toggle != mToggled ) )
202   {
203     mToggled = toggle;
204
205     Toolkit::PushButton handle( GetOwner() );
206
207     // Notifies the painter the button has been toggled.
208     GetPushButtonPainter( mPainter )->Toggled( handle );
209
210     // Emit signal.
211     mToggledSignalV2.Emit( handle, mToggled );
212   }
213 }
214
215 bool PushButton::IsToggled() const
216 {
217   return mToggleButton && mToggled;
218 }
219
220 void PushButton::SetButtonImage( Image image )
221 {
222   SetButtonImage( ImageActor::New( image ) );
223 }
224
225 void PushButton::SetButtonImage( Actor image )
226 {
227   Toolkit::PushButton handle( GetOwner() );
228   GetPushButtonPainter( mPainter )->SetButtonImage( handle, image );
229 }
230
231 Actor& PushButton::GetButtonImage()
232 {
233   return mButtonImage;
234 }
235
236 Actor PushButton::GetButtonImage() const
237 {
238   return mButtonImage;
239 }
240
241 void PushButton::SetBackgroundImage( Image image )
242 {
243   SetBackgroundImage( ImageActor::New( image ) );
244 }
245
246 void PushButton::SetBackgroundImage( Actor image )
247 {
248   Toolkit::PushButton handle( GetOwner() );
249   GetPushButtonPainter( mPainter )->SetBackgroundImage( handle, image );
250 }
251
252 Actor& PushButton::GetBackgroundImage()
253 {
254   return mBackgroundImage;
255 }
256
257 Actor PushButton::GetBackgroundImage() const
258 {
259   return mBackgroundImage;
260 }
261
262 void PushButton::SetPressedImage( Image image )
263 {
264   SetPressedImage( ImageActor::New( image ) );
265 }
266
267 void PushButton::SetPressedImage( Actor image )
268 {
269   Toolkit::PushButton handle( GetOwner() );
270   GetPushButtonPainter( mPainter )->SetPressedImage( handle, image );
271 }
272
273 Actor& PushButton::GetPressedImage()
274 {
275   return mPressedImage;
276 }
277
278 Actor PushButton::GetPressedImage() const
279 {
280   return mPressedImage;
281 }
282
283 void PushButton::SetDimmedBackgroundImage( Image image )
284 {
285   SetDimmedBackgroundImage( ImageActor::New( image ) );
286 }
287
288 void PushButton::SetDimmedBackgroundImage( Actor image )
289 {
290   Toolkit::PushButton handle( GetOwner() );
291   GetPushButtonPainter( mPainter )->SetDimmedBackgroundImage( handle, image );
292 }
293
294 Actor& PushButton::GetDimmedBackgroundImage()
295 {
296   return mDimmedBackgroundImage;
297 }
298
299 Actor PushButton::GetDimmedBackgroundImage() const
300 {
301   return mDimmedBackgroundImage;
302 }
303
304 void PushButton::SetDimmedImage( Image image )
305 {
306   SetDimmedImage( ImageActor::New( image ) );
307 }
308
309 void PushButton::SetDimmedImage( Actor image )
310 {
311   Toolkit::PushButton handle( GetOwner() );
312   GetPushButtonPainter( mPainter )->SetDimmedImage( handle, image );
313 }
314
315 Actor& PushButton::GetDimmedImage()
316 {
317   return mDimmedImage;
318 }
319
320 Actor PushButton::GetDimmedImage() const
321 {
322   return mDimmedImage;
323 }
324
325 void PushButton::SetLabelText( const std::string& text )
326 {
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 );
330 }
331
332 void PushButton::SetLabelText( Actor text )
333 {
334   Toolkit::PushButton handle( GetOwner() );
335   GetPushButtonPainter( mPainter )->SetLabelText( handle, text );
336 }
337
338 Actor& PushButton::GetLabel()
339 {
340   return mLabel;
341 }
342
343 Actor PushButton::GetLabelText() const
344 {
345   return mLabel;
346 }
347
348 Actor& PushButton::GetFadeOutBackgroundImage()
349 {
350   return mFadeOutBackgroundImage;
351 }
352
353 Actor& PushButton::GetFadeOutButtonImage()
354 {
355   return mFadeOutButtonImage;
356 }
357
358 Toolkit::PushButton::ToggledSignalV2& PushButton::ToggledSignal()
359 {
360   return mToggledSignalV2;
361 }
362
363 Toolkit::PushButton::PressedSignalV2& PushButton::PressedSignal()
364 {
365   return mPressedSignalV2;
366 }
367
368 Toolkit::PushButton::ReleasedSignalV2& PushButton::ReleasedSignal()
369 {
370   return mReleasedSignalV2;
371 }
372
373 bool PushButton::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
374 {
375   Dali::BaseHandle handle( object );
376
377   bool connected( true );
378   Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
379
380   if( Toolkit::PushButton::SIGNAL_TOGGLED == signalName )
381   {
382     button.ToggledSignal().Connect( tracker, functor );
383   }
384   else if( Toolkit::PushButton::SIGNAL_PRESSED == signalName )
385   {
386     button.PressedSignal().Connect( tracker, functor );
387   }
388   else if( Toolkit::PushButton::SIGNAL_RELEASED == signalName )
389   {
390     button.ReleasedSignal().Connect( tracker, functor );
391   }
392   else
393   {
394     // signalName does not match any signal
395     connected = false;
396   }
397
398   return connected;
399 }
400
401 void PushButton::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
402 {
403   Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
404
405   if ( pushButton )
406   {
407     PushButton& pushButtonImpl( GetImplementation( pushButton ) );
408
409     switch ( propertyIndex )
410     {
411       case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
412       {
413         pushButtonImpl.SetAutoRepeating( value.Get< bool >() );
414         break;
415       }
416
417       case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
418       {
419         pushButtonImpl.SetInitialAutoRepeatingDelay( value.Get< float >() );
420         break;
421       }
422
423       case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
424       {
425         pushButtonImpl.SetNextAutoRepeatingDelay( value.Get< float >() );
426         break;
427       }
428
429       case Toolkit::PushButton::PROPERTY_TOGGLABLE:
430       {
431         pushButtonImpl.SetToggleButton( value.Get< bool >() );
432         break;
433       }
434
435       case Toolkit::PushButton::PROPERTY_TOGGLE:
436       {
437         pushButtonImpl.SetToggled( value.Get< bool >() );
438         break;
439       }
440
441       case Toolkit::PushButton::PROPERTY_BUTTON_IMAGE:
442       {
443         Image image = Image::New( value.Get<std::string>() );
444         pushButtonImpl.SetButtonImage( image );
445         break;
446       }
447
448       case Toolkit::PushButton::PROPERTY_PRESSED_IMAGE:
449       {
450         Image image = Image::New( value.Get<std::string>() );
451         pushButtonImpl.SetPressedImage( image );
452         break;
453       }
454
455       case Toolkit::PushButton::PROPERTY_DIMMED_IMAGE:
456       {
457         Image image = Image::New( value.Get<std::string>() );
458         pushButtonImpl.SetDimmedImage( image );
459         break;
460       }
461
462       case Toolkit::PushButton::PROPERTY_LABEL_TEXT:
463       {
464         pushButtonImpl.SetLabelText( value.Get< std::string >() );
465         break;
466       }
467     }
468   }
469 }
470
471 Property::Value PushButton::GetProperty( BaseObject* object, Property::Index propertyIndex )
472 {
473   Property::Value value;
474
475   Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
476
477   if ( pushButton )
478   {
479     PushButton& pushButtonImpl( GetImplementation( pushButton ) );
480
481     switch ( propertyIndex )
482     {
483       case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
484       {
485         value = pushButtonImpl.mAutoRepeating;
486         break;
487       }
488
489       case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
490       {
491         value = pushButtonImpl.mInitialAutoRepeatingDelay;
492         break;
493       }
494
495       case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
496       {
497         value = pushButtonImpl.mNextAutoRepeatingDelay;
498         break;
499       }
500
501       case Toolkit::PushButton::PROPERTY_TOGGLABLE:
502       {
503         value = pushButtonImpl.mToggleButton;
504         break;
505       }
506
507       case Toolkit::PushButton::PROPERTY_TOGGLE:
508       {
509         value = pushButtonImpl.mToggled;
510         break;
511       }
512
513       case Toolkit::PushButton::PROPERTY_BUTTON_IMAGE:
514       {
515         std::string path;
516         GetImageActorFilename( pushButtonImpl.mButtonImage, path );
517         value = path;
518         break;
519       }
520
521       case Toolkit::PushButton::PROPERTY_PRESSED_IMAGE:
522       {
523         std::string path;
524         GetImageActorFilename( pushButtonImpl.mPressedImage, path );
525         value = path;
526         break;
527       }
528
529       case Toolkit::PushButton::PROPERTY_DIMMED_IMAGE:
530       {
531         std::string path;
532         GetImageActorFilename( pushButtonImpl.mDimmedImage, path );
533         value = path;
534         break;
535       }
536
537       case Toolkit::PushButton::PROPERTY_LABEL_TEXT:
538       {
539         value = ""; // Just return an empty string if not using a TextView
540
541         if ( pushButtonImpl.mLabel )
542         {
543           Toolkit::TextView textView = Toolkit::TextView::DownCast( pushButtonImpl.mLabel );
544           if ( textView )
545           {
546             value = textView.GetText();
547           }
548         }
549         break;
550       }
551     }
552   }
553
554   return value;
555 }
556
557 void PushButton::OnButtonInitialize()
558 {
559   // Push button requires the Leave event.
560   Actor root = Self();
561   root.SetLeaveRequired( true );
562 }
563
564 void PushButton::OnButtonDown()
565 {
566   if( !mToggleButton )
567   {
568     Toolkit::PushButton handle( GetOwner() );
569
570     // Notifies the painter the button has been pressed.
571     GetPushButtonPainter( mPainter )->Pressed( handle );
572
573     if( mAutoRepeating )
574     {
575       SetUpTimer( mInitialAutoRepeatingDelay );
576     }
577
578     //Emit signal.
579     mPressedSignalV2.Emit( handle );
580   }
581 }
582
583 void PushButton::OnButtonUp()
584 {
585   if( ButtonDown == mState )
586   {
587     if( mToggleButton )
588     {
589       mToggled = !mToggled;
590
591       Toolkit::PushButton handle( GetOwner() );
592
593       // Notifies the painter the button has been toggled.
594       GetPushButtonPainter( mPainter )->Toggled( handle );
595
596       //Emit signal.
597       mToggledSignalV2.Emit( handle, mToggled );
598     }
599     else
600     {
601       Toolkit::PushButton handle( GetOwner() );
602
603       // Notifies the painter the button has been clicked.
604       GetPushButtonPainter( mPainter )->Released( handle );
605       GetPushButtonPainter( mPainter )->Clicked( handle );
606
607       if( mAutoRepeating )
608       {
609         mAutoRepeatingTimer.Reset();
610       }
611
612       //Emit signal.
613       mReleasedSignalV2.Emit( handle );
614       mClickedSignalV2.Emit( handle );
615     }
616   }
617 }
618
619 void PushButton::OnTouchPointLeave()
620 {
621   if( ButtonDown == mState )
622   {
623     if( !mToggleButton )
624     {
625       Toolkit::PushButton handle( GetOwner() );
626
627       // Notifies the painter the button has been released.
628       GetPushButtonPainter( mPainter )->Released( handle );
629
630       if( mAutoRepeating )
631       {
632         mAutoRepeatingTimer.Reset();
633       }
634
635       //Emit signal.
636       mReleasedSignalV2.Emit( handle );
637     }
638   }
639 }
640
641 void PushButton::OnTouchPointInterrupted()
642 {
643   OnTouchPointLeave();
644 }
645
646 void PushButton::OnAnimationTimeSet( float animationTime )
647 {
648   GetPushButtonPainter( mPainter )->SetAnimationTime( animationTime );
649 }
650
651 float PushButton::OnAnimationTimeRequested() const
652 {
653   return GetPushButtonPainter( mPainter )->GetAnimationTime();
654 }
655
656 PushButton::PushButton()
657 : Button(),
658   mAutoRepeating( false ),
659   mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
660   mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
661   mToggleButton( false ),
662   mAutoRepeatingTimer(),
663   mToggled( false ),
664   mClickActionPerforming(false)
665 {
666   // Creates specific painter.
667   mPainter = PushButtonDefaultPainterPtr( new PushButtonDefaultPainter() );
668 }
669
670 PushButton::~PushButton()
671 {
672   if( mAutoRepeatingTimer )
673   {
674     mAutoRepeatingTimer.Reset();
675   }
676
677   mPainter = NULL;
678 }
679
680 void PushButton::SetUpTimer( float delay )
681 {
682   mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
683   mAutoRepeatingTimer.TickSignal().Connect( this, &PushButton::AutoRepeatingSlot );
684   mAutoRepeatingTimer.Start();
685 }
686
687 bool PushButton::AutoRepeatingSlot()
688 {
689   bool consumed = false;
690   if( !mDimmed )
691   {
692     // Restart the autorepeat timer.
693     SetUpTimer( mNextAutoRepeatingDelay );
694
695     Toolkit::PushButton handle( GetOwner() );
696
697     // Notifies the painter the button has been pressed.
698     GetPushButtonPainter( mPainter )->Pressed( handle );
699
700     //Emit signal.
701     consumed = mReleasedSignalV2.Emit( handle );
702     consumed |= mClickedSignalV2.Emit( handle );
703     consumed |= mPressedSignalV2.Emit( handle );
704  }
705
706   return consumed;
707 }
708
709 void PushButton::OnActivated()
710 {
711   // When the button is activated, it performs the click action
712   std::vector<Property::Value> attributes;
713   DoClickAction(attributes);
714 }
715
716 void PushButton::DoClickAction(const PropertyValueContainer& attributes)
717 {
718   // Prevents the button signals from doing a recursive loop by sending an action
719   // and re-emitting the signals.
720   if(!mClickActionPerforming)
721   {
722     mClickActionPerforming = true;
723     OnButtonDown();
724     mState = ButtonDown;
725     OnButtonUp();
726     mClickActionPerforming = false;
727   }
728 }
729
730 bool PushButton::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
731 {
732   bool ret = false;
733
734   Dali::BaseHandle handle(object);
735
736   Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
737
738   DALI_ASSERT_ALWAYS(button);
739
740   if(Toolkit::PushButton::ACTION_PUSH_BUTTON_CLICK == actionName)
741   {
742     GetImplementation(button).DoClickAction(attributes);
743     ret = true;
744   }
745
746   return ret;
747 }
748
749 } // namespace Internal
750
751 } // namespace Toolkit
752
753 } // namespace Dali