[dali_1.0.38] Merge branch 'tizen'
[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( Dimension::WIDTH ), size.width );
66     size.height = std::max( root.GetRelayoutSize( Dimension::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( ResizePolicy::USE_NATURAL_SIZE, Dimension::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.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
117
118     Toolkit::TextLabel textLabel = Toolkit::TextLabel::DownCast( label );
119     if( textLabel )
120     {
121       textLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
122       textLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
123       textLabel.SetProperty( Toolkit::TextLabel::Property::MULTI_LINE, true );
124     }
125   }
126 }
127
128 void PushButton::OnButtonImageSet()
129 {
130   Actor& buttonImage = GetButtonImage();
131
132   buttonImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
133
134   buttonImage.RelayoutRequestTree();
135
136   RelayoutRequest();
137 }
138
139 void PushButton::OnSelectedImageSet()
140 {
141   Actor& selectedImage = GetSelectedImage();
142
143   selectedImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
144
145   selectedImage.RelayoutRequestTree();
146
147   RelayoutRequest();
148 }
149
150 void PushButton::OnBackgroundImageSet()
151 {
152   Actor& backgroundImage = GetBackgroundImage();
153
154   backgroundImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
155
156   backgroundImage.RelayoutRequestTree();
157
158   RelayoutRequest();
159 }
160
161 void PushButton::OnSelectedBackgroundImageSet()
162 {
163   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
164
165   selectedBackgroundImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
166 }
167
168 void PushButton::OnDisabledImageSet()
169 {
170   Actor& disabledImage = GetDisabledImage();
171
172   disabledImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
173
174   disabledImage.RelayoutRequestTree();
175
176   RelayoutRequest();
177 }
178
179 void PushButton::OnDisabledBackgroundImageSet()
180 {
181   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
182
183   disabledBackgroundImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
184
185   disabledBackgroundImage.RelayoutRequestTree();
186
187   RelayoutRequest();
188 }
189
190 bool PushButton::OnSelected()
191 {
192   Actor& buttonImage = GetButtonImage();
193   Actor& selectedImage = GetSelectedImage();
194   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
195
196   PaintState paintState = GetPaintState();
197
198   switch( paintState )
199   {
200     case UnselectedState:
201     {
202       FadeOutImage( buttonImage );
203       FadeInImage( selectedBackgroundImage );
204       FadeInImage( selectedImage );
205       StartTransitionAnimation();
206       break;
207     }
208     case SelectedState:
209     {
210       FadeOutImage( selectedBackgroundImage );
211       FadeOutImage( selectedImage );
212       FadeInImage( buttonImage );
213       StartTransitionAnimation();
214       break;
215     }
216     case UnselectedSelectedTransition:
217     {
218       float opacity = 1.f;
219       if( selectedImage )
220       {
221         opacity = selectedImage.GetCurrentOpacity();
222       }
223
224       StopTransitionAnimation( false );
225       FadeOutImage( selectedBackgroundImage, opacity );
226       FadeOutImage( selectedImage, opacity );
227       FadeInImage( buttonImage, 1.f - opacity );
228       StartTransitionAnimation();
229       break;
230     }
231     case SelectedUnselectedTransition:
232     {
233       float opacity = 0.f;
234       if( selectedImage )
235       {
236         opacity = selectedImage.GetCurrentOpacity();
237       }
238
239       StopTransitionAnimation( false );
240       FadeOutImage( buttonImage, 1.f - opacity );
241       FadeInImage( selectedBackgroundImage, opacity );
242       FadeInImage( selectedImage, opacity );
243       StartTransitionAnimation();
244       break;
245     }
246     case DisabledUnselectedTransition:
247     {
248       StopTransitionAnimation();
249       FadeOutImage( buttonImage );
250       FadeInImage( selectedBackgroundImage );
251       FadeInImage( selectedImage );
252       StartTransitionAnimation();
253       break;
254     }
255     case DisabledSelectedTransition:
256     {
257       StopTransitionAnimation();
258       FadeOutImage( selectedBackgroundImage );
259       FadeOutImage( selectedImage );
260       FadeInImage( buttonImage );
261       StartTransitionAnimation();
262       break;
263     }
264     default:
265     {
266       break;
267     }
268   }
269
270   if( mTransitionAnimation )
271   {
272     return true;
273   }
274
275   return false;
276 }
277
278 bool PushButton::OnDisabled()
279 {
280   Actor& buttonImage = GetButtonImage();
281   Actor& selectedImage = GetSelectedImage();
282   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
283   Actor& backgroundImage = GetBackgroundImage();
284   Actor& disabledImage = GetDisabledImage();
285   Actor& disabledSelectedImage = GetDisabledSelectedImage();
286   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
287
288   PaintState paintState = GetPaintState();
289
290   switch( paintState )
291   {
292     case UnselectedState:
293     {
294       FadeOutImage( backgroundImage );
295       FadeOutImage( buttonImage );
296       FadeInImage( disabledBackgroundImage );
297       FadeInImage( disabledImage );
298       StartTransitionAnimation();
299       break;
300     }
301     case SelectedState:
302     {
303       FadeOutImage( backgroundImage );
304       FadeOutImage( selectedBackgroundImage );
305       FadeOutImage( selectedImage );
306       FadeInImage( disabledBackgroundImage );
307       FadeInImage( disabledSelectedImage );
308       StartTransitionAnimation();
309       break;
310     }
311     case DisabledUnselectedState:
312     {
313       FadeOutImage( disabledBackgroundImage );
314       FadeOutImage( disabledImage );
315       FadeInImage( backgroundImage );
316       FadeInImage( buttonImage );
317       StartTransitionAnimation();
318       break;
319     }
320     case DisabledSelectedState:
321     {
322       FadeOutImage( disabledBackgroundImage );
323       FadeOutImage( disabledSelectedImage );
324       FadeInImage( backgroundImage );
325       FadeInImage( selectedBackgroundImage );
326       FadeInImage( selectedImage );
327       StartTransitionAnimation();
328       break;
329     }
330     case UnselectedSelectedTransition:
331     {
332       float opacity = 1.f;
333       if( selectedImage )
334       {
335         opacity = selectedImage.GetCurrentOpacity();
336       }
337
338       StopTransitionAnimation();
339       FadeOutImage( backgroundImage );
340       FadeOutImage( selectedBackgroundImage, opacity );
341       FadeOutImage( selectedImage, opacity );
342       FadeInImage( disabledBackgroundImage );
343       FadeInImage( disabledSelectedImage );
344       StartTransitionAnimation();
345       break;
346     }
347     case SelectedUnselectedTransition:
348     {
349       float opacity = 1.f;
350       if( buttonImage )
351       {
352         opacity = buttonImage.GetCurrentOpacity();
353       }
354
355       StopTransitionAnimation();
356       FadeOutImage( backgroundImage );
357       FadeOutImage( buttonImage, opacity );
358       FadeInImage( disabledBackgroundImage );
359       FadeInImage( disabledImage );
360       StartTransitionAnimation();
361       break;
362     }
363     case UnselectedDisabledTransition:
364     {
365       float opacity = 1.f;
366       if( disabledImage )
367       {
368         opacity = disabledImage.GetCurrentOpacity();
369       }
370
371       StopTransitionAnimation( false );
372       FadeOutImage( disabledBackgroundImage, opacity );
373       FadeOutImage( disabledImage, opacity );
374       FadeInImage( backgroundImage, 1.f - opacity );
375       FadeInImage( buttonImage, 1.f - opacity );
376       StartTransitionAnimation();
377       break;
378     }
379     case DisabledUnselectedTransition:
380     {
381       float opacity = 1.f;
382       if( buttonImage )
383       {
384         opacity = buttonImage.GetCurrentOpacity();
385       }
386
387       StopTransitionAnimation( false );
388       FadeOutImage( backgroundImage, opacity );
389       FadeOutImage( buttonImage, opacity );
390       FadeInImage( disabledBackgroundImage, 1.f - opacity );
391       FadeInImage( disabledImage, 1.f - opacity );
392       StartTransitionAnimation();
393       break;
394     }
395     case SelectedDisabledTransition:
396     {
397       float opacity = 1.f;
398       if( disabledSelectedImage )
399       {
400         opacity = disabledSelectedImage.GetCurrentOpacity();
401       }
402
403       StopTransitionAnimation( false );
404       FadeOutImage( disabledBackgroundImage, opacity );
405       FadeOutImage( disabledSelectedImage, opacity );
406       FadeInImage( backgroundImage, 1.f - opacity );
407       FadeInImage( selectedBackgroundImage, 1.f - opacity );
408       FadeInImage( selectedImage, 1.f - opacity );
409       StartTransitionAnimation();
410       break;
411     }
412     case DisabledSelectedTransition:
413     {
414       float opacity = 1.f;
415       if( selectedImage )
416       {
417         opacity = selectedImage.GetCurrentOpacity();
418       }
419
420       StopTransitionAnimation( false );
421       FadeOutImage( backgroundImage, opacity );
422       FadeOutImage( selectedBackgroundImage, opacity );
423       FadeOutImage( selectedImage, opacity );
424       FadeInImage( disabledBackgroundImage, 1.f - opacity );
425       FadeInImage( disabledSelectedImage, 1.f - opacity );
426       StartTransitionAnimation();
427       break;
428     }
429   }
430
431   if( mTransitionAnimation )
432   {
433     return true;
434   }
435
436   return false;
437 }
438
439 bool PushButton::OnPressed()
440 {
441   Actor& buttonImage = GetButtonImage();
442   Actor& selectedImage = GetSelectedImage();
443   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
444
445   PaintState paintState = GetPaintState();
446
447   switch( paintState )
448   {
449     case UnselectedState:
450     {
451       FadeOutImage( buttonImage );
452       FadeInImage( selectedBackgroundImage );
453       FadeInImage( selectedImage );
454       StartTransitionAnimation();
455       break;
456     }
457     case SelectedUnselectedTransition:
458     {
459       float opacity = 1.f;
460       if( buttonImage )
461       {
462         opacity = buttonImage.GetCurrentOpacity();
463       }
464
465       StopTransitionAnimation( false );
466       FadeOutImage( buttonImage, opacity );
467       FadeInImage( selectedBackgroundImage, 1.f - opacity );
468       FadeInImage( selectedImage, 1.f - opacity );
469       StartTransitionAnimation();
470       break;
471     }
472     case DisabledUnselectedTransition:
473     {
474       float opacity = 1.f;
475       if( buttonImage )
476       {
477         opacity = buttonImage.GetCurrentOpacity();
478       }
479
480       StopTransitionAnimation();
481       FadeOutImage( buttonImage, opacity );
482       FadeInImage( selectedBackgroundImage );
483       FadeInImage( selectedImage );
484       StartTransitionAnimation();
485       break;
486     }
487     default:
488       break;
489   }
490
491   if( mTransitionAnimation )
492   {
493     return true;
494   }
495
496   return false;
497 }
498
499 bool PushButton::OnReleased()
500 {
501   Actor& buttonImage = GetButtonImage();
502   Actor& selectedImage = GetSelectedImage();
503   Actor& selectedBackgroundImage = GetSelectedBackgroundImage();
504
505   PaintState paintState = GetPaintState();
506
507   switch( paintState )
508   {
509     case SelectedState:
510     {
511       FadeOutImage( selectedBackgroundImage );
512       FadeOutImage( selectedImage );
513       FadeInImage( buttonImage );
514       StartTransitionAnimation();
515       break;
516     }
517     case UnselectedSelectedTransition:
518     {
519       float opacity = 1.f;
520       if( selectedImage )
521       {
522         opacity = selectedImage.GetCurrentOpacity();
523       }
524
525       StopTransitionAnimation( false );
526       FadeOutImage( selectedBackgroundImage, opacity );
527       FadeOutImage( selectedImage, opacity );
528       FadeInImage( buttonImage, 1.f - opacity );
529       StartTransitionAnimation();
530       break;
531     }
532     case DisabledSelectedTransition:
533     {
534       float opacity = 1.f;
535       if( selectedImage )
536       {
537         opacity = selectedImage.GetCurrentOpacity();
538       }
539
540       StopTransitionAnimation();
541       FadeOutImage( selectedBackgroundImage, opacity );
542       FadeOutImage( selectedImage, opacity );
543       FadeInImage( buttonImage );
544       StartTransitionAnimation();
545       break;
546     }
547     default:
548     {
549       break;
550     }
551   }
552
553   if( mTransitionAnimation )
554   {
555     return true;
556   }
557
558   return false;
559 }
560
561 void PushButton::StopAllAnimations()
562 {
563   StopTransitionAnimation();
564 }
565
566 void PushButton::OnControlSizeSet( const Vector3& targetSize )
567 {
568   if( targetSize != mSize )
569   {
570     mSize = targetSize;
571
572     Actor& label = GetLabel();
573
574     if( label )
575     {
576       label.SetSize( mSize );
577     }
578   }
579 }
580
581 Vector3 PushButton::GetNaturalSize()
582 {
583   Vector3 size;
584
585   // Check Image and Background image and use the largest size as the control's Natural size.
586   SizeOfActorIfLarger( GetButtonImage(), size );
587   SizeOfActorIfLarger( GetBackgroundImage(), size );
588
589   // If label, test against it's size
590   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( GetLabel() );
591   if( label )
592   {
593     Vector3 labelSize = label.GetNaturalSize();
594
595     size.width  = std::max( size.width,  labelSize.width  + TEXT_PADDING * 2.0f );
596     size.height = std::max( size.height, labelSize.height + TEXT_PADDING * 2.0f );
597   }
598
599   return size;
600 }
601
602 void PushButton::StartTransitionAnimation()
603 {
604   if( mTransitionAnimation )
605   {
606     mTransitionAnimation.FinishedSignal().Connect( this, &PushButton::TransitionAnimationFinished );
607     mTransitionAnimation.Play();
608   }
609 }
610
611 void PushButton::StopTransitionAnimation( bool remove )
612 {
613   if( mTransitionAnimation )
614   {
615     mTransitionAnimation.Clear();
616     mTransitionAnimation.Reset();
617   }
618
619   if( remove )
620   {
621     UpdatePaintTransitionState();
622   }
623 }
624
625 void PushButton::FadeInImage( Actor& image, float opacity, Vector3 scale )
626 {
627   if( image )
628   {
629     image.SetOpacity( opacity );
630     image.SetScale( scale );
631
632     if( !mTransitionAnimation )
633     {
634       mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
635     }
636
637     mTransitionAnimation.AnimateTo( Property( image, Actor::Property::COLOR_ALPHA ), 1.f );
638   }
639 }
640
641 void PushButton::FadeOutImage( Actor& image, float opacity, Vector3 scale )
642 {
643   if( image )
644   {
645     image.SetOpacity( opacity );
646     image.SetScale( scale );
647
648     if( !mTransitionAnimation )
649     {
650       mTransitionAnimation = Dali::Animation::New( GetAnimationTime() );
651     }
652
653     mTransitionAnimation.AnimateTo( Property( image, Actor::Property::COLOR_ALPHA ), 0.f );
654   }
655 }
656
657 void PushButton::TransitionAnimationFinished( Dali::Animation& source )
658 {
659   StopTransitionAnimation();
660 }
661
662 } // namespace Internal
663
664 } // namespace Toolkit
665
666 } // namespace Dali