Cleaning up property public API and usage of typedefs
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / controls / buttons / push-button-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
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
18 // CLASS HEADER
19 #include "push-button-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <dali/public-api/actors/image-actor.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/scripting/scripting.h>
26
27 // INTERNAL INCLUDES
28 #include "push-button-default-painter-impl.h"
29
30 #include <dali-toolkit/public-api/controls/text-view/text-view.h>
31 #include <dali-toolkit/internal/controls/relayout-helper.h>
32
33 namespace Dali
34 {
35
36 namespace Toolkit
37 {
38
39 const Property::Index PushButton::PROPERTY_AUTO_REPEATING               = Internal::Button::BUTTON_PROPERTY_END_INDEX + 1;
40 const Property::Index PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY = Internal::Button::BUTTON_PROPERTY_END_INDEX + 2;
41 const Property::Index PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY    = Internal::Button::BUTTON_PROPERTY_END_INDEX + 3;
42 const Property::Index PushButton::PROPERTY_TOGGLABLE                    = Internal::Button::BUTTON_PROPERTY_END_INDEX + 4;
43 const Property::Index PushButton::PROPERTY_TOGGLE                       = Internal::Button::BUTTON_PROPERTY_END_INDEX + 5;
44 const Property::Index PushButton::PROPERTY_NORMAL_STATE_ACTOR           = Internal::Button::BUTTON_PROPERTY_END_INDEX + 6;
45 const Property::Index PushButton::PROPERTY_PRESSED_STATE_ACTOR          = Internal::Button::BUTTON_PROPERTY_END_INDEX + 7;
46 const Property::Index PushButton::PROPERTY_DIMMED_STATE_ACTOR           = Internal::Button::BUTTON_PROPERTY_END_INDEX + 8;
47 const Property::Index PushButton::PROPERTY_LABEL_ACTOR                  = Internal::Button::BUTTON_PROPERTY_END_INDEX + 9;
48
49 namespace Internal
50 {
51
52 namespace
53 {
54
55 BaseHandle Create()
56 {
57   return Toolkit::PushButton::New();
58 }
59
60 TypeRegistration typeRegistration( typeid(Toolkit::PushButton), typeid(Toolkit::Button), Create );
61
62 SignalConnectorType signalConnector1( typeRegistration, Toolkit::PushButton::SIGNAL_PRESSED , &PushButton::DoConnectSignal );
63 SignalConnectorType signalConnector2( typeRegistration, Toolkit::PushButton::SIGNAL_RELEASED, &PushButton::DoConnectSignal );
64
65 TypeAction action1( typeRegistration, Toolkit::PushButton::ACTION_PUSH_BUTTON_CLICK, &PushButton::DoAction );
66
67 PropertyRegistration property1( typeRegistration, "auto-repeating",               Toolkit::PushButton::PROPERTY_AUTO_REPEATING,               Property::BOOLEAN, &PushButton::SetProperty, &PushButton::GetProperty );
68 PropertyRegistration property2( typeRegistration, "initial-auto-repeating-delay", Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY, Property::FLOAT,   &PushButton::SetProperty, &PushButton::GetProperty );
69 PropertyRegistration property3( typeRegistration, "next-auto-repeating-delay",    Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY,    Property::FLOAT,   &PushButton::SetProperty, &PushButton::GetProperty );
70 PropertyRegistration property4( typeRegistration, "togglable",                    Toolkit::PushButton::PROPERTY_TOGGLABLE,                    Property::BOOLEAN, &PushButton::SetProperty, &PushButton::GetProperty );
71 PropertyRegistration property5( typeRegistration, "toggle",                       Toolkit::PushButton::PROPERTY_TOGGLE,                       Property::BOOLEAN, &PushButton::SetProperty, &PushButton::GetProperty );
72 PropertyRegistration property6( typeRegistration, "normal-state-actor",           Toolkit::PushButton::PROPERTY_NORMAL_STATE_ACTOR,           Property::MAP,     &PushButton::SetProperty, &PushButton::GetProperty );
73 PropertyRegistration property7( typeRegistration, "pressed-state-actor",          Toolkit::PushButton::PROPERTY_PRESSED_STATE_ACTOR,          Property::MAP,     &PushButton::SetProperty, &PushButton::GetProperty );
74 PropertyRegistration property8( typeRegistration, "dimmed-state-actor",           Toolkit::PushButton::PROPERTY_DIMMED_STATE_ACTOR,           Property::MAP,     &PushButton::SetProperty, &PushButton::GetProperty );
75 PropertyRegistration property9( typeRegistration, "label-actor",                  Toolkit::PushButton::PROPERTY_LABEL_ACTOR,                  Property::MAP,     &PushButton::SetProperty, &PushButton::GetProperty );
76
77 } // unnamed namespace
78
79 namespace
80 {
81
82 const unsigned int INITIAL_AUTOREPEATING_DELAY( 0.15f );
83 const unsigned int NEXT_AUTOREPEATING_DELAY( 0.05f );
84
85 const float TEXT_PADDING = 12.0f;
86
87 // Helper function used to cast a ButtonPainter to PushButtonDefaultPainter
88 PushButtonDefaultPainterPtr GetPushButtonPainter( Dali::Toolkit::Internal::ButtonPainterPtr painter )
89 {
90   return static_cast<PushButtonDefaultPainter*>( painter.Get() );
91 }
92
93 /**
94  * Find the first image actor in the actor hierarchy
95  */
96 ImageActor FindImageActor( Actor root )
97 {
98   ImageActor imageActor = ImageActor::DownCast( root );
99   if( !imageActor && root )
100   {
101     for( unsigned int i = 0, numChildren = root.GetChildCount(); i < numChildren; ++i )
102     {
103       ImageActor childImageActor = FindImageActor( root.GetChildAt( i ) );
104       if( childImageActor )
105       {
106         return childImageActor;
107       }
108     }
109   }
110
111   return imageActor;
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::PressedSignalV2& PushButton::PressedSignal()
359 {
360   return mPressedSignalV2;
361 }
362
363 Toolkit::PushButton::ReleasedSignalV2& PushButton::ReleasedSignal()
364 {
365   return mReleasedSignalV2;
366 }
367
368 bool PushButton::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
369 {
370   Dali::BaseHandle handle( object );
371
372   bool connected( true );
373   Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
374
375   if( Toolkit::PushButton::SIGNAL_TOGGLED == signalName )
376   {
377     button.ToggledSignal().Connect( tracker, functor );
378   }
379   else if( Toolkit::PushButton::SIGNAL_PRESSED == signalName )
380   {
381     button.PressedSignal().Connect( tracker, functor );
382   }
383   else if( Toolkit::PushButton::SIGNAL_RELEASED == signalName )
384   {
385     button.ReleasedSignal().Connect( tracker, functor );
386   }
387   else
388   {
389     // signalName does not match any signal
390     connected = false;
391   }
392
393   return connected;
394 }
395
396 void PushButton::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
397 {
398   Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
399
400   if ( pushButton )
401   {
402     PushButton& pushButtonImpl( GetImplementation( pushButton ) );
403
404     switch ( propertyIndex )
405     {
406       case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
407       {
408         pushButtonImpl.SetAutoRepeating( value.Get< bool >() );
409         break;
410       }
411
412       case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
413       {
414         pushButtonImpl.SetInitialAutoRepeatingDelay( value.Get< float >() );
415         break;
416       }
417
418       case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
419       {
420         pushButtonImpl.SetNextAutoRepeatingDelay( value.Get< float >() );
421         break;
422       }
423
424       case Toolkit::PushButton::PROPERTY_TOGGLABLE:
425       {
426         pushButtonImpl.SetToggleButton( value.Get< bool >() );
427         break;
428       }
429
430       case Toolkit::PushButton::PROPERTY_TOGGLE:
431       {
432         pushButtonImpl.SetToggled( value.Get< bool >() );
433         break;
434       }
435
436       case Toolkit::PushButton::PROPERTY_NORMAL_STATE_ACTOR:
437       {
438         pushButtonImpl.SetButtonImage( Scripting::NewActor( value.Get< Property::Map >() ) );
439         break;
440       }
441
442       case Toolkit::PushButton::PROPERTY_PRESSED_STATE_ACTOR:
443       {
444         pushButtonImpl.SetPressedImage( Scripting::NewActor( value.Get< Property::Map >() ) );
445         break;
446       }
447
448       case Toolkit::PushButton::PROPERTY_DIMMED_STATE_ACTOR:
449       {
450         pushButtonImpl.SetDimmedImage( Scripting::NewActor( value.Get< Property::Map >() ) );
451         break;
452       }
453
454       case Toolkit::PushButton::PROPERTY_LABEL_ACTOR:
455       {
456         pushButtonImpl.SetLabelText( Scripting::NewActor( value.Get< Property::Map >() ) );
457         break;
458       }
459     }
460   }
461 }
462
463 Property::Value PushButton::GetProperty( BaseObject* object, Property::Index propertyIndex )
464 {
465   Property::Value value;
466
467   Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( Dali::BaseHandle( object ) );
468
469   if ( pushButton )
470   {
471     PushButton& pushButtonImpl( GetImplementation( pushButton ) );
472
473     switch ( propertyIndex )
474     {
475       case Toolkit::PushButton::PROPERTY_AUTO_REPEATING:
476       {
477         value = pushButtonImpl.mAutoRepeating;
478         break;
479       }
480
481       case Toolkit::PushButton::PROPERTY_INITIAL_AUTO_REPEATING_DELAY:
482       {
483         value = pushButtonImpl.mInitialAutoRepeatingDelay;
484         break;
485       }
486
487       case Toolkit::PushButton::PROPERTY_NEXT_AUTO_REPEATING_DELAY:
488       {
489         value = pushButtonImpl.mNextAutoRepeatingDelay;
490         break;
491       }
492
493       case Toolkit::PushButton::PROPERTY_TOGGLABLE:
494       {
495         value = pushButtonImpl.mToggleButton;
496         break;
497       }
498
499       case Toolkit::PushButton::PROPERTY_TOGGLE:
500       {
501         value = pushButtonImpl.mToggled;
502         break;
503       }
504
505       case Toolkit::PushButton::PROPERTY_NORMAL_STATE_ACTOR:
506       {
507         Property::Map map;
508         Scripting::CreatePropertyMap( pushButtonImpl.mButtonImage, map );
509         value = map;
510         break;
511       }
512
513       case Toolkit::PushButton::PROPERTY_PRESSED_STATE_ACTOR:
514       {
515         Property::Map map;
516         Scripting::CreatePropertyMap( pushButtonImpl.mPressedImage, map );
517         value = map;
518         break;
519       }
520
521       case Toolkit::PushButton::PROPERTY_DIMMED_STATE_ACTOR:
522       {
523         Property::Map map;
524         Scripting::CreatePropertyMap( pushButtonImpl.mDimmedImage, map );
525         value = map;
526         break;
527       }
528
529       case Toolkit::PushButton::PROPERTY_LABEL_ACTOR:
530       {
531         Property::Map map;
532         Scripting::CreatePropertyMap( pushButtonImpl.mLabel, map );
533         value = map;
534         break;
535       }
536     }
537   }
538
539   return value;
540 }
541
542 void PushButton::OnButtonInitialize()
543 {
544   // Push button requires the Leave event.
545   Actor root = Self();
546   root.SetLeaveRequired( true );
547 }
548
549 void PushButton::OnButtonDown()
550 {
551   if( !mToggleButton )
552   {
553     Toolkit::PushButton handle( GetOwner() );
554
555     // Notifies the painter the button has been pressed.
556     GetPushButtonPainter( mPainter )->Pressed( handle );
557
558     if( mAutoRepeating )
559     {
560       SetUpTimer( mInitialAutoRepeatingDelay );
561     }
562
563     //Emit signal.
564     mPressedSignalV2.Emit( handle );
565   }
566 }
567
568 void PushButton::OnButtonUp()
569 {
570   if( ButtonDown == mState )
571   {
572     if( mToggleButton )
573     {
574       mToggled = !mToggled;
575
576       Toolkit::PushButton handle( GetOwner() );
577
578       // Notifies the painter the button has been toggled.
579       GetPushButtonPainter( mPainter )->Toggled( handle );
580
581       // Emit signal.
582       mToggledSignalV2.Emit( handle, mToggled );
583     }
584     else
585     {
586       Toolkit::PushButton handle( GetOwner() );
587
588       // Notifies the painter the button has been clicked.
589       GetPushButtonPainter( mPainter )->Released( handle );
590       GetPushButtonPainter( mPainter )->Clicked( handle );
591
592       if( mAutoRepeating )
593       {
594         mAutoRepeatingTimer.Reset();
595       }
596
597       //Emit signal.
598       mReleasedSignalV2.Emit( handle );
599       mClickedSignalV2.Emit( handle );
600     }
601   }
602 }
603
604 void PushButton::OnTouchPointLeave()
605 {
606   if( ButtonDown == mState )
607   {
608     if( !mToggleButton )
609     {
610       Toolkit::PushButton handle( GetOwner() );
611
612       // Notifies the painter the button has been released.
613       GetPushButtonPainter( mPainter )->Released( handle );
614
615       if( mAutoRepeating )
616       {
617         mAutoRepeatingTimer.Reset();
618       }
619
620       //Emit signal.
621       mReleasedSignalV2.Emit( handle );
622     }
623   }
624 }
625
626 void PushButton::OnTouchPointInterrupted()
627 {
628   OnTouchPointLeave();
629 }
630
631 void PushButton::OnAnimationTimeSet( float animationTime )
632 {
633   GetPushButtonPainter( mPainter )->SetAnimationTime( animationTime );
634 }
635
636 float PushButton::OnAnimationTimeRequested() const
637 {
638   return GetPushButtonPainter( mPainter )->GetAnimationTime();
639 }
640
641 void PushButton::OnButtonStageDisconnection()
642 {
643   if( ButtonDown == mState )
644   {
645     if( !mToggleButton )
646     {
647       Toolkit::PushButton handle( GetOwner() );
648
649       // Notifies the painter the button has been released.
650       GetPushButtonPainter( mPainter )->Released( handle );
651
652       if( mAutoRepeating )
653       {
654         mAutoRepeatingTimer.Reset();
655       }
656     }
657   }
658 }
659
660 PushButton::PushButton()
661 : Button(),
662   mAutoRepeating( false ),
663   mInitialAutoRepeatingDelay( INITIAL_AUTOREPEATING_DELAY ),
664   mNextAutoRepeatingDelay( NEXT_AUTOREPEATING_DELAY ),
665   mToggleButton( false ),
666   mAutoRepeatingTimer(),
667   mToggled( false ),
668   mClickActionPerforming(false)
669 {
670   // Creates specific painter.
671   mPainter = PushButtonDefaultPainterPtr( new PushButtonDefaultPainter() );
672 }
673
674 PushButton::~PushButton()
675 {
676   if( mAutoRepeatingTimer )
677   {
678     mAutoRepeatingTimer.Reset();
679   }
680
681   mPainter = NULL;
682 }
683
684 void PushButton::SetUpTimer( float delay )
685 {
686   mAutoRepeatingTimer = Dali::Timer::New( static_cast<unsigned int>( 1000.f * delay ) );
687   mAutoRepeatingTimer.TickSignal().Connect( this, &PushButton::AutoRepeatingSlot );
688   mAutoRepeatingTimer.Start();
689 }
690
691 bool PushButton::AutoRepeatingSlot()
692 {
693   bool consumed = false;
694   if( !mDimmed )
695   {
696     // Restart the autorepeat timer.
697     SetUpTimer( mNextAutoRepeatingDelay );
698
699     Toolkit::PushButton handle( GetOwner() );
700
701     // Notifies the painter the button has been pressed.
702     GetPushButtonPainter( mPainter )->Pressed( handle );
703
704     //Emit signal.
705     consumed = mReleasedSignalV2.Emit( handle );
706     consumed |= mClickedSignalV2.Emit( handle );
707     consumed |= mPressedSignalV2.Emit( handle );
708  }
709
710   return consumed;
711 }
712
713 void PushButton::OnActivated()
714 {
715   // When the button is activated, it performs the click action
716   PropertyValueContainer attributes;
717   DoClickAction(attributes);
718 }
719
720 Vector3 PushButton::GetNaturalSize()
721 {
722   Vector3 size = Control::GetNaturalSize();
723
724   const bool widthIsZero = EqualsZero( size.width );
725   const bool heightIsZero = EqualsZero( size.height );
726
727   if( widthIsZero || heightIsZero )
728   {
729     // If background and background not scale9 try get size from that
730     ImageActor imageActor = FindImageActor( mButtonImage );
731     if( imageActor && imageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
732     {
733       Vector3 imageSize = RelayoutHelper::GetNaturalSize( imageActor );
734
735       if( widthIsZero )
736       {
737         size.width = imageSize.width;
738       }
739
740       if( heightIsZero )
741       {
742         size.height = imageSize.height;
743       }
744     }
745
746     ImageActor backgroundImageActor = FindImageActor( mBackgroundImage );
747     if( backgroundImageActor && backgroundImageActor.GetStyle() != ImageActor::STYLE_NINE_PATCH )
748     {
749       Vector3 imageSize = RelayoutHelper::GetNaturalSize( backgroundImageActor );
750
751       if( widthIsZero )
752       {
753         size.width = std::max( size.width, imageSize.width );
754       }
755
756       if( heightIsZero )
757       {
758         size.height = std::max( size.height, imageSize.height );
759       }
760     }
761
762     // If label, test against it's size
763     Toolkit::TextView textView = Toolkit::TextView::DownCast( mLabel );
764     if( textView )
765     {
766       Vector3 textViewSize = textView.GetNaturalSize();
767
768       if( widthIsZero )
769       {
770         size.width = std::max( size.width, textViewSize.width + TEXT_PADDING * 2.0f );
771       }
772
773       if( heightIsZero )
774       {
775         size.height = std::max( size.height, textViewSize.height + TEXT_PADDING * 2.0f );
776       }
777     }
778   }
779
780   return size;
781 }
782
783 void PushButton::DoClickAction(const PropertyValueContainer& attributes)
784 {
785   // Prevents the button signals from doing a recursive loop by sending an action
786   // and re-emitting the signals.
787   if(!mClickActionPerforming)
788   {
789     mClickActionPerforming = true;
790     OnButtonDown();
791     mState = ButtonDown;
792     OnButtonUp();
793     mClickActionPerforming = false;
794   }
795 }
796
797 bool PushButton::DoAction(BaseObject* object, const std::string& actionName, const PropertyValueContainer& attributes)
798 {
799   bool ret = false;
800
801   Dali::BaseHandle handle(object);
802
803   Toolkit::PushButton button = Toolkit::PushButton::DownCast(handle);
804
805   DALI_ASSERT_ALWAYS(button);
806
807   if(Toolkit::PushButton::ACTION_PUSH_BUTTON_CLICK == actionName)
808   {
809     GetImplementation(button).DoClickAction(attributes);
810     ret = true;
811   }
812
813   return ret;
814 }
815
816 } // namespace Internal
817
818 } // namespace Toolkit
819
820 } // namespace Dali