Merge "Refactoring Button: remove painter" into tizen
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / buttons / check-box-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 "check-box-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 namespace Dali
26 {
27
28 namespace Toolkit
29 {
30
31 namespace Internal
32 {
33
34 namespace
35 {
36
37 const float FOREGROUND_DEPTH( 0.5f );
38 const float BACKGROUND_DEPTH( 0.25f );
39
40 const float ANIMATION_TIME( 0.26f );  // EFL checkbox tick time
41
42 const Vector3 DISTANCE_BETWEEN_IMAGE_AND_LABEL(5.0f, 0.0f, 0.0f);
43
44 BaseHandle Create()
45 {
46   return Toolkit::CheckBoxButton::New();
47 }
48
49 TypeRegistration mType( typeid(Toolkit::CheckBoxButton), typeid(Toolkit::Button), Create );
50
51 }
52
53 Dali::Toolkit::CheckBoxButton CheckBoxButton::New()
54 {
55   // Create the implementation, temporarily owned on stack
56   IntrusivePtr< CheckBoxButton > internalCheckBoxButton = new CheckBoxButton();
57
58   // Pass ownership to CustomActor
59   Dali::Toolkit::CheckBoxButton checkBoxButton( *internalCheckBoxButton );
60
61   // Second-phase init of the implementation
62   // This can only be done after the CustomActor connection has been made...
63   internalCheckBoxButton->Initialize();
64
65   return checkBoxButton;
66 }
67
68 CheckBoxButton::CheckBoxButton()
69 : Button(),
70   mPaintState( UnselectedState )
71 {
72   SetTogglableButton( true );
73
74   SetAnimationTime( ANIMATION_TIME );
75 }
76
77 CheckBoxButton::~CheckBoxButton()
78 {
79   if( mCheckInAnimation )
80   {
81     mCheckInAnimation.Clear();
82   }
83 }
84
85 void CheckBoxButton::SetSelectedImage( Actor image )
86 {
87   Actor& selectedImage = GetSelectedImage();
88
89   switch( mPaintState )
90   {
91     case SelectedState:
92     {
93       if( selectedImage && selectedImage.GetParent() )
94       {
95         Self().Remove( selectedImage );
96       }
97
98       selectedImage = image;
99       Self().Add( selectedImage );
100       break;
101     }
102     case UnselectedSelectedTransition:
103     {
104       StopCheckInAnimation();
105       Self().Remove( selectedImage );
106
107       selectedImage = image;
108       Self().Add( selectedImage );
109
110       mPaintState = SelectedState;
111       break;
112     }
113     default:
114     {
115       selectedImage = image;
116       break;
117     }
118   }
119
120   selectedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
121   selectedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
122   selectedImage.SetZ( FOREGROUND_DEPTH );
123 }
124
125 void CheckBoxButton::SetBackgroundImage( Actor image )
126 {
127   Actor& backgroundImage = GetBackgroundImage();
128
129   switch( mPaintState )
130   {
131     case UnselectedState:             // FALLTHROUGH
132     case SelectedState:
133     case UnselectedSelectedTransition:
134     {
135       if( backgroundImage && backgroundImage.GetParent() )
136       {
137         Self().Remove( backgroundImage );
138
139         Actor& label = GetLabel();
140
141         if( label )
142         {
143           backgroundImage.Remove( label );
144           image.Add( label );
145         }
146       }
147
148       backgroundImage = image;
149       Self().Add( backgroundImage );
150       break;
151     }
152     default:
153     {
154       backgroundImage = image;
155       break;
156     }
157   }
158
159   backgroundImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
160   backgroundImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
161   backgroundImage.SetZ( BACKGROUND_DEPTH );
162 }
163
164 void CheckBoxButton::SetDisabledSelectedImage( Actor image )
165 {
166   Actor& disabledSelectedImage = GetDisabledSelectedImage();
167
168   switch( mPaintState )
169   {
170     case DisabledSelectedState:
171     {
172       if( disabledSelectedImage && disabledSelectedImage.GetParent() )
173       {
174         Self().Remove( disabledSelectedImage );
175       }
176
177       disabledSelectedImage = image;
178       Self().Add( disabledSelectedImage );
179       break;
180     }
181     default:
182     {
183       disabledSelectedImage = image;
184       break;
185     }
186   }
187
188   disabledSelectedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
189   disabledSelectedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
190   disabledSelectedImage.SetZ( FOREGROUND_DEPTH );
191 }
192
193 void CheckBoxButton::SetDisabledBackgroundImage( Actor image )
194 {
195   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
196
197   switch( mPaintState )
198   {
199     case DisabledSelectedState:
200     case DisabledUnselectedState:
201     {
202       if( disabledBackgroundImage && disabledBackgroundImage.GetParent() )
203       {
204         Self().Remove( disabledBackgroundImage );
205
206         Actor& label = GetLabel();
207
208         if( label )
209         {
210           disabledBackgroundImage.Remove( label );
211           image.Add( label );
212         }
213       }
214
215       disabledBackgroundImage = image;
216       Self().Add( disabledBackgroundImage );
217       break;
218     }
219     default:
220     {
221       disabledBackgroundImage = image;
222       break;
223     }
224   }
225
226   disabledBackgroundImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
227   disabledBackgroundImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
228   disabledBackgroundImage.SetZ( BACKGROUND_DEPTH );
229 }
230
231 void CheckBoxButton::OnLabelSet()
232 {
233   Actor& label = GetLabel();
234
235   if( label )
236   {
237     label.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
238     label.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
239     label.MoveBy( DISTANCE_BETWEEN_IMAGE_AND_LABEL );
240
241     if( IsDisabled() && GetDisabledBackgroundImage() )
242     {
243       GetDisabledBackgroundImage().Add( label );
244     }
245     else if ( GetBackgroundImage() )
246     {
247       GetBackgroundImage().Add( label );
248     }
249     else
250     {
251       Self().Add( label );
252     }
253   }
254 }
255
256 void CheckBoxButton::OnSelected( bool selected )
257 {
258   Actor& selectedImage = GetSelectedImage();
259
260   switch( mPaintState )
261   {
262     case UnselectedState:
263     {
264       AddChild( selectedImage );
265       StartCheckInAnimation( selectedImage );    // Animate in the check actor
266
267       mPaintState = UnselectedSelectedTransition;
268       break;
269     }
270     case SelectedState:
271     {
272       RemoveChild( selectedImage );
273
274       mPaintState = UnselectedState;
275       break;
276     }
277     case UnselectedSelectedTransition:
278     {
279       StopCheckInAnimation();
280       RemoveChild( selectedImage );
281
282       mPaintState = UnselectedState;
283       break;
284     }
285     default:
286       break;
287   }
288 }
289
290 void CheckBoxButton::OnDisabled( bool disabled )
291 {
292   Actor& backgroundImage = GetBackgroundImage();
293   Actor& selectedImage = GetSelectedImage();
294   Actor& disabledBackgroundImage = GetDisabledBackgroundImage();
295   Actor& disabledSelectedImage = GetDisabledSelectedImage();
296
297   switch( mPaintState )
298   {
299     case UnselectedState:
300     {
301       if( disabled )
302       {
303         RemoveChild( backgroundImage );
304         AddChild( disabledBackgroundImage );
305         mPaintState = DisabledUnselectedState;
306       }
307       break;
308     }
309     case SelectedState:
310     {
311       if( disabled )
312       {
313         RemoveChild( backgroundImage );
314         RemoveChild( selectedImage );
315         AddChild( disabledBackgroundImage );
316         AddChild( disabledSelectedImage );
317
318         mPaintState = DisabledSelectedState;
319       }
320       break;
321     }
322     case DisabledUnselectedState:
323     {
324       if( !disabled )
325       {
326         RemoveChild( disabledBackgroundImage );
327         AddChild( backgroundImage );
328
329         mPaintState = UnselectedState;
330       }
331       break;
332     }
333     case DisabledSelectedState:
334     {
335       if( !disabled )
336       {
337         RemoveChild( disabledBackgroundImage );
338         RemoveChild( disabledSelectedImage );
339         AddChild( backgroundImage );
340         AddChild( selectedImage );
341
342         mPaintState = SelectedState;
343       }
344       break;
345     }
346     case UnselectedSelectedTransition:
347     {
348       if( disabled )
349       {
350         StopCheckInAnimation();
351
352         RemoveChild( backgroundImage );
353         RemoveChild( selectedImage );
354         AddChild( disabledBackgroundImage );
355         AddChild( disabledSelectedImage );
356
357         mPaintState = DisabledSelectedState;
358       }
359       break;
360     }
361     default:
362       break;
363   }
364
365   Actor& label = GetLabel();
366
367   if( label )
368   {
369     if( label.GetParent() )
370     {
371       label.GetParent().Remove( label );
372     }
373
374     if( disabled && disabledBackgroundImage)
375     {
376       disabledBackgroundImage.Add( label );
377     }
378     else if( backgroundImage )
379     {
380       backgroundImage.Add( label );
381     }
382   }
383 }
384
385 void CheckBoxButton::OnRelayout( const Vector2& size, ActorSizeContainer& container )
386 {
387   Vector3 newSize;
388
389   if( IsDisabled() && GetDisabledBackgroundImage() )
390   {
391     newSize = GetDisabledBackgroundImage().GetNaturalSize();
392   }
393   else if( GetBackgroundImage() )
394   {
395     newSize = GetBackgroundImage().GetNaturalSize();
396   }
397
398   Actor& label = GetLabel();
399
400   if( label )
401   {
402     // Offset the label from the radio button image
403     newSize.width += DISTANCE_BETWEEN_IMAGE_AND_LABEL.width;
404
405     // Find the size of the control using size negotiation
406     Vector3 actorNaturalSize( label.GetNaturalSize() );
407     Control::Relayout( label, Vector2( actorNaturalSize.width, actorNaturalSize.height ), container );
408
409     Vector3 actorSize( label.GetSize() );
410     newSize.width += actorSize.width;
411     newSize.height = std::max( newSize.height, actorSize.height );
412   }
413
414   Self().SetSize( newSize );
415 }
416
417 void CheckBoxButton::AddChild( Actor& actor )
418 {
419   if( actor )
420   {
421     Self().Add( actor);
422   }
423 }
424
425 void CheckBoxButton::RemoveChild( Actor& actor )
426 {
427   if( actor )
428   {
429     Self().Remove( actor );
430   }
431 }
432
433 void CheckBoxButton::StartCheckInAnimation( Actor& actor )
434 {
435   if( actor )
436   {
437     if( !mTickUVEffect )
438     {
439       ImageActor imageActor = ImageActor::DownCast( actor );
440       mTickUVEffect = ImageRegionEffect::New();
441       imageActor.SetShaderEffect( mTickUVEffect );
442     }
443
444     actor.SetScale( Vector3( 0.0f, 1.0f, 1.0f ) );
445
446     mTickUVEffect.SetBottomRight( Vector2( 0.0f, 1.0f ) );
447
448     if( !mCheckInAnimation )
449     {
450       mCheckInAnimation = Dali::Animation::New( GetAnimationTime()  );
451     }
452
453     // UV anim
454     mCheckInAnimation.AnimateTo( Property( mTickUVEffect, mTickUVEffect.GetBottomRightPropertyName() ), Vector2( 1.0f, 1.0f ) );
455
456     // Actor size anim
457     mCheckInAnimation.AnimateTo( Property( actor, Actor::SCALE_X ), 1.0f);
458
459     mCheckInAnimation.FinishedSignal().Connect( this, &CheckBoxButton::CheckInAnimationFinished );
460     mCheckInAnimation.Play();
461   }
462 }
463
464 void CheckBoxButton::StopCheckInAnimation()
465 {
466   if( mCheckInAnimation )
467   {
468     mCheckInAnimation.Clear();
469     mCheckInAnimation.Reset();
470   }
471 }
472
473 void CheckBoxButton::CheckInAnimationFinished( Dali::Animation& source )
474 {
475   switch( mPaintState )
476   {
477     case UnselectedSelectedTransition:
478     {
479       mPaintState = SelectedState;
480       break;
481     }
482     default:
483     {
484       break;
485     }
486   }
487
488   StopCheckInAnimation();
489 }
490
491 } // namespace Internal
492
493 } // namespace Toolkit
494
495 } // namespace Dali