3910e43af120105fcfe7e1ba6942b8d07664cd26
[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 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 <dali/public-api/actors/image-actor.h>
23 #include <dali/public-api/object/type-registry.h>
24
25 // INTERNAL INCLUDES
26 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
27
28 namespace Dali
29 {
30
31 namespace Toolkit
32 {
33
34 namespace Internal
35 {
36
37 namespace
38 {
39
40 const float TEXT_PADDING = 12.0f;
41 const float ANIMATION_TIME( 0.2f );
42
43 BaseHandle Create()
44 {
45   return Toolkit::PushButton::New();
46 }
47
48 TypeRegistration typeRegistration( typeid(Toolkit::PushButton), typeid(Toolkit::Button), Create );
49
50 } // unnamed namespace
51
52 namespace
53 {
54
55 /**
56  * Get size of Actor if larger than given size
57  * @param[in] root the actor to get the size of
58  * @param[out] size the greater of the given size or the size of the Actor
59  */
60 void SizeOfActorIfLarger( Actor root, Vector3& size )
61 {
62   if ( root )
63   {
64     // RelayoutSize retreived for Actor to use any padding set to it.
65     size.width = std::max( root.GetRelayoutSize( WIDTH ), size.width );
66     size.height = std::max( root.GetRelayoutSize( HEIGHT ), size.height );
67   }
68 }
69
70 } // unnamed namespace
71
72 Dali::Toolkit::PushButton PushButton::New()
73 {
74   // Create the implementation, temporarily owned on stack
75   IntrusivePtr< PushButton > internalPushButton = new PushButton();
76
77   // Pass ownership to CustomActor
78   Dali::Toolkit::PushButton pushButton( *internalPushButton );
79
80   // Second-phase init of the implementation
81   // This can only be done after the CustomActor connection has been made...
82   internalPushButton->Initialize();
83
84   return pushButton;
85 }
86
87 PushButton::PushButton()
88 : Button(),
89   mSize()
90 {
91   SetAnimationTime( ANIMATION_TIME );
92 }
93
94 PushButton::~PushButton()
95 {
96 }
97
98 void PushButton::OnButtonInitialize()
99 {
100   // Push button requires the Leave event.
101   Actor self = Self();
102   self.SetLeaveRequired( true );
103
104   // Set resize policy to natural size so that buttons will resize to background images
105   self.SetResizePolicy( USE_NATURAL_SIZE, ALL_DIMENSIONS );
106 }
107
108 void PushButton::OnLabelSet()
109 {
110   Actor& label = GetLabel();
111
112   if( label )
113   {
114     label.SetAnchorPoint( AnchorPoint::CENTER );
115     label.SetParentOrigin( ParentOrigin::CENTER );
116     label.SetSize( mSize );
117   }
118 }
119
120 void PushButton::OnButtonImageSet()
121 {
122   Actor& buttonImage = GetButtonImage();
123
124   buttonImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
125
126   buttonImage.RelayoutRequestTree();
127
128   RelayoutRequest();
129 }
130
131 void PushButton::OnSelectedImageSet()
132 {
133   Actor& selectedImage = GetSelectedImage();
134
135   selectedImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
136
137   selectedImage.RelayoutRequestTree();
138
139   RelayoutRequest();
140 }
141
142 void PushButton::OnBackgroundImageSet()
143 {
144   Actor& backgroundImage = GetBackgroundImage();
145
146   backgroundImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
147
148   backgroundImage.RelayoutRequestTree();
149
150   RelayoutRequest();
151 }
152
153 void PushButton::OnSelectedBackgroundImageSet()
154 {
155   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
156
157   selectedBackgroundImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
158 }
159
160 void PushButton::OnDisabledImageSet()
161 {
162   Actor& disabledImage = GetDisabledImage();
163
164   disabledImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
165
166   disabledImage.RelayoutRequestTree();
167
168   RelayoutRequest();
169 }
170
171 void PushButton::OnDisabledBackgroundImageSet()
172 {
173   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
174
175   disabledBackgroundImage.SetResizePolicy( FILL_TO_PARENT, ALL_DIMENSIONS );
176
177   disabledBackgroundImage.RelayoutRequestTree();
178
179   RelayoutRequest();
180 }
181
182 bool PushButton::OnSelected()
183 {
184   Actor& buttonImage = GetButtonImage();
185   Actor& selectedImage = GetSelectedImage();
186   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
187
188   PaintState paintState = GetPaintState();
189
190   switch( paintState )
191   {
192     case UnselectedState:
193     {
194       FadeOutImage( buttonImage );
195       FadeInImage( selectedBackgroundImage );
196       FadeInImage( selectedImage );
197       StartTransitionAnimation();
198       break;
199     }
200     case SelectedState:
201     {
202       FadeOutImage( selectedBackgroundImage );
203       FadeOutImage( selectedImage );
204       FadeInImage( buttonImage );
205       StartTransitionAnimation();
206       break;
207     }
208     case UnselectedSelectedTransition:
209     {
210       float opacity = 1.f;
211       if( selectedImage )
212       {
213         opacity = selectedImage.GetCurrentOpacity();
214       }
215
216       StopTransitionAnimation( false );
217       FadeOutImage( selectedBackgroundImage, opacity );
218       FadeOutImage( selectedImage, opacity );
219       FadeInImage( buttonImage, 1.f - opacity );
220       StartTransitionAnimation();
221       break;
222     }
223     case SelectedUnselectedTransition:
224     {
225       float opacity = 0.f;
226       if( selectedImage )
227       {
228         opacity = selectedImage.GetCurrentOpacity();
229       }
230
231       StopTransitionAnimation( false );
232       FadeOutImage( buttonImage, 1.f - opacity );
233       FadeInImage( selectedBackgroundImage, opacity );
234       FadeInImage( selectedImage, opacity );
235       StartTransitionAnimation();
236       break;
237     }
238     case DisabledUnselectedTransition:
239     {
240       StopTransitionAnimation();
241       FadeOutImage( buttonImage );
242       FadeInImage( selectedBackgroundImage );
243       FadeInImage( selectedImage );
244       StartTransitionAnimation();
245       break;
246     }
247     case DisabledSelectedTransition:
248     {
249       StopTransitionAnimation();
250       FadeOutImage( selectedBackgroundImage );
251       FadeOutImage( selectedImage );
252       FadeInImage( buttonImage );
253       StartTransitionAnimation();
254       break;
255     }
256     default:
257     {
258       break;
259     }
260   }
261
262   if( mTransitionAnimation )
263   {
264     return true;
265   }
266
267   return false;
268 }
269
270 bool PushButton::OnDisabled()
271 {
272   Actor& buttonImage = GetButtonImage();
273   Actor& selectedImage = GetSelectedImage();
274   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
275   Actor& backgroundImage = GetBackgroundImage();
276   Actor& disabledImage = GetDisabledImage();
277   Actor& disabledSelectedImage = GetDisabledSelectedImage();
278   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
279
280   PaintState paintState = GetPaintState();
281
282   switch( paintState )
283   {
284     case UnselectedState:
285     {
286       FadeOutImage( backgroundImage );
287       FadeOutImage( buttonImage );
288       FadeInImage( disabledBackgroundImage );
289       FadeInImage( disabledImage );
290       StartTransitionAnimation();
291       break;
292     }
293     case SelectedState:
294     {
295       FadeOutImage( backgroundImage );
296       FadeOutImage( selectedBackgroundImage );
297       FadeOutImage( selectedImage );
298       FadeInImage( disabledBackgroundImage );
299       FadeInImage( disabledSelectedImage );
300       StartTransitionAnimation();
301       break;
302     }
303     case DisabledUnselectedState:
304     {
305       FadeOutImage( disabledBackgroundImage );
306       FadeOutImage( disabledImage );
307       FadeInImage( backgroundImage );
308       FadeInImage( buttonImage );
309       StartTransitionAnimation();
310       break;
311     }
312     case DisabledSelectedState:
313     {
314       FadeOutImage( disabledBackgroundImage );
315       FadeOutImage( disabledSelectedImage );
316       FadeInImage( backgroundImage );
317       FadeInImage( selectedBackgroundImage );
318       FadeInImage( selectedImage );
319       StartTransitionAnimation();
320       break;
321     }
322     case UnselectedSelectedTransition:
323     {
324       float opacity = 1.f;
325       if( selectedImage )
326       {
327         opacity = selectedImage.GetCurrentOpacity();
328       }
329
330       StopTransitionAnimation();
331       FadeOutImage( backgroundImage );
332       FadeOutImage( selectedBackgroundImage, opacity );
333       FadeOutImage( selectedImage, opacity );
334       FadeInImage( disabledBackgroundImage );
335       FadeInImage( disabledSelectedImage );
336       StartTransitionAnimation();
337       break;
338     }
339     case SelectedUnselectedTransition:
340     {
341       float opacity = 1.f;
342       if( buttonImage )
343       {
344         opacity = buttonImage.GetCurrentOpacity();
345       }
346
347       StopTransitionAnimation();
348       FadeOutImage( backgroundImage );
349       FadeOutImage( buttonImage, opacity );
350       FadeInImage( disabledBackgroundImage );
351       FadeInImage( disabledImage );
352       StartTransitionAnimation();
353       break;
354     }
355     case UnselectedDisabledTransition:
356     {
357       float opacity = 1.f;
358       if( disabledImage )
359       {
360         opacity = disabledImage.GetCurrentOpacity();
361       }
362
363       StopTransitionAnimation( false );
364       FadeOutImage( disabledBackgroundImage, opacity );
365       FadeOutImage( disabledImage, opacity );
366       FadeInImage( backgroundImage, 1.f - opacity );
367       FadeInImage( buttonImage, 1.f - opacity );
368       StartTransitionAnimation();
369       break;
370     }
371     case DisabledUnselectedTransition:
372     {
373       float opacity = 1.f;
374       if( buttonImage )
375       {
376         opacity = buttonImage.GetCurrentOpacity();
377       }
378
379       StopTransitionAnimation( false );
380       FadeOutImage( backgroundImage, opacity );
381       FadeOutImage( buttonImage, opacity );
382       FadeInImage( disabledBackgroundImage, 1.f - opacity );
383       FadeInImage( disabledImage, 1.f - opacity );
384       StartTransitionAnimation();
385       break;
386     }
387     case SelectedDisabledTransition:
388     {
389       float opacity = 1.f;
390       if( disabledSelectedImage )
391       {
392         opacity = disabledSelectedImage.GetCurrentOpacity();
393       }
394
395       StopTransitionAnimation( false );
396       FadeOutImage( disabledBackgroundImage, opacity );
397       FadeOutImage( disabledSelectedImage, opacity );
398       FadeInImage( backgroundImage, 1.f - opacity );
399       FadeInImage( selectedBackgroundImage, 1.f - opacity );
400       FadeInImage( selectedImage, 1.f - opacity );
401       StartTransitionAnimation();
402       break;
403     }
404     case DisabledSelectedTransition:
405     {
406       float opacity = 1.f;
407       if( selectedImage )
408       {
409         opacity = selectedImage.GetCurrentOpacity();
410       }
411
412       StopTransitionAnimation( false );
413       FadeOutImage( backgroundImage, opacity );
414       FadeOutImage( selectedBackgroundImage, opacity );
415       FadeOutImage( selectedImage, opacity );
416       FadeInImage( disabledBackgroundImage, 1.f - opacity );
417       FadeInImage( disabledSelectedImage, 1.f - opacity );
418       StartTransitionAnimation();
419       break;
420     }
421   }
422
423   if( mTransitionAnimation )
424   {
425     return true;
426   }
427
428   return false;
429 }
430
431 bool PushButton::OnPressed()
432 {
433   Actor& buttonImage = GetButtonImage();
434   Actor& selectedImage = GetSelectedImage();
435   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
436
437   PaintState paintState = GetPaintState();
438
439   switch( paintState )
440   {
441     case UnselectedState:
442     {
443       FadeOutImage( buttonImage );
444       FadeInImage( selectedBackgroundImage );
445       FadeInImage( selectedImage );
446       StartTransitionAnimation();
447       break;
448     }
449     case SelectedUnselectedTransition:
450     {
451       float opacity = 1.f;
452       if( buttonImage )
453       {
454         opacity = buttonImage.GetCurrentOpacity();
455       }
456
457       StopTransitionAnimation( false );
458       FadeOutImage( buttonImage, opacity );
459       FadeInImage( selectedBackgroundImage, 1.f - opacity );
460       FadeInImage( selectedImage, 1.f - opacity );
461       StartTransitionAnimation();
462       break;
463     }
464     case DisabledUnselectedTransition:
465     {
466       float opacity = 1.f;
467       if( buttonImage )
468       {
469         opacity = buttonImage.GetCurrentOpacity();
470       }
471
472       StopTransitionAnimation();
473       FadeOutImage( buttonImage, opacity );
474       FadeInImage( selectedBackgroundImage );
475       FadeInImage( selectedImage );
476       StartTransitionAnimation();
477       break;
478     }
479     default:
480       break;
481   }
482
483   if( mTransitionAnimation )
484   {
485     return true;
486   }
487
488   return false;
489 }
490
491 bool PushButton::OnReleased()
492 {
493   Actor& buttonImage = GetButtonImage();
494   Actor& selectedImage = GetSelectedImage();
495   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
496
497   PaintState paintState = GetPaintState();
498
499   switch( paintState )
500   {
501     case SelectedState:
502     {
503       FadeOutImage( selectedBackgroundImage );
504       FadeOutImage( selectedImage );
505       FadeInImage( buttonImage );
506       StartTransitionAnimation();
507       break;
508     }
509     case UnselectedSelectedTransition:
510     {
511       float opacity = 1.f;
512       if( selectedImage )
513       {
514         opacity = selectedImage.GetCurrentOpacity();
515       }
516
517       StopTransitionAnimation( false );
518       FadeOutImage( selectedBackgroundImage, opacity );
519       FadeOutImage( selectedImage, opacity );
520       FadeInImage( buttonImage, 1.f - opacity );
521       StartTransitionAnimation();
522       break;
523     }
524     case DisabledSelectedTransition:
525     {
526       float opacity = 1.f;
527       if( selectedImage )
528       {
529         opacity = selectedImage.GetCurrentOpacity();
530       }
531
532       StopTransitionAnimation();
533       FadeOutImage( selectedBackgroundImage, opacity );
534       FadeOutImage( selectedImage, opacity );
535       FadeInImage( buttonImage );
536       StartTransitionAnimation();
537       break;
538     }
539     default:
540     {
541       break;
542     }
543   }
544
545   if( mTransitionAnimation )
546   {
547     return true;
548   }
549
550   return false;
551 }
552
553 void PushButton::StopAllAnimations()
554 {
555   StopTransitionAnimation();
556 }
557
558 void PushButton::OnControlSizeSet( const Vector3& targetSize )
559 {
560   if( targetSize != mSize )
561   {
562     mSize = targetSize;
563
564     Actor& label = GetLabel();
565
566     if( label )
567     {
568       label.SetSize( mSize );
569     }
570   }
571 }
572
573 Vector3 PushButton::GetNaturalSize()
574 {
575   Vector3 size;
576
577   // Check Image and Background image and use the largest size as the control's Natural size.
578   SizeOfActorIfLarger( GetButtonImage(), size );
579   SizeOfActorIfLarger( GetBackgroundImage(), size );
580
581   // If label, test against it's size
582   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( GetLabel() );
583   if( label )
584   {
585     Vector3 labelSize = label.GetNaturalSize();
586
587     size.width  = std::max( size.width,  labelSize.width  + TEXT_PADDING * 2.0f );
588     size.height = std::max( size.height, labelSize.height + TEXT_PADDING * 2.0f );
589   }
590
591   return size;
592 }
593
594 void PushButton::StartTransitionAnimation()
595 {
596   if( mTransitionAnimation )
597   {
598     mTransitionAnimation.FinishedSignal().Connect( this, &PushButton::TransitionAnimationFinished );
599     mTransitionAnimation.Play();
600   }
601 }
602
603 void PushButton::StopTransitionAnimation( bool remove )
604 {
605   if( mTransitionAnimation )
606   {
607     mTransitionAnimation.Clear();
608     mTransitionAnimation.Reset();
609   }
610
611   if( remove )
612   {
613     UpdatePaintTransitionState();
614   }
615 }
616
617 void PushButton::FadeInImage( Actor& image, float opacity, Vector3 scale )
618 {
619   if( image )
620   {
621     image.SetOpacity( opacity );
622     image.SetScale( scale );
623
624     if( !mTransitionAnimation )
625     {
626       mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
627     }
628
629     mTransitionAnimation.AnimateTo( Property( image, Actor::Property::COLOR_ALPHA ), 1.f );
630   }
631 }
632
633 void PushButton::FadeOutImage( Actor& image, float opacity, Vector3 scale )
634 {
635   if( image )
636   {
637     image.SetOpacity( opacity );
638     image.SetScale( scale );
639
640     if( !mTransitionAnimation )
641     {
642       mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
643     }
644
645     mTransitionAnimation.AnimateTo( Property( image, Actor::Property::COLOR_ALPHA ), 0.f );
646   }
647 }
648
649 void PushButton::TransitionAnimationFinished( Dali::Animation& source )
650 {
651   StopTransitionAnimation();
652 }
653
654 } // namespace Internal
655
656 } // namespace Toolkit
657
658 } // namespace Dali