Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-demo.git] / examples / contact-cards / contact-card.cpp
1 /*
2  * Copyright (c) 2016 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 "contact-card.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/dali-toolkit.h>
23
24 // INTERNAL INCLUDES
25 #include "contact-card-layout-info.h"
26 #include "clipped-image.h"
27
28 using namespace Dali;
29 using namespace Dali::Toolkit;
30
31 namespace
32 {
33 /*
34  * The constants below are used to create the following Unfold Animation.
35  *
36  * 0ms  50  100  150  200  250  300  350  400 Total Animation time in Milliseconds
37  * |    |    |    |    |    |    |    |    |
38  * o-----------------------------------o   |  X Position Animation            ( 0ms To 360ms)
39  * |   o-----------------------------------o  Y Position Animation            (40ms To 400ms)
40  * o-----------------------------------o   |  Width Animation                 ( 0ms To 360ms)
41  * |   o-----------------------------------o  Height Animation                (40ms To 400ms)
42  * o-------o |    |    |    |    |    |    |  Fade out Name Text Animation    ( 0ms To  80ms)
43  * |       o-------o   |    |    |    |    |  Fade in Details Text Animation  (80ms To 160ms)
44  * o---------------o   |    |    |    |    |  Fade out other cards Animation  ( 0ms To 160ms)
45  * o---------------------------------------o  Mesh Morph Animation            ( 0ms To 400ms)
46  */
47 const TimePeriod TIME_PERIOD_UNFOLD_X( 0.0f,  0.36f ); ///< Start at 0ms, duration 360ms
48 const TimePeriod TIME_PERIOD_UNFOLD_Y( 0.04f, 0.36f ); ///< Start at 40ms, duration 360ms
49 const TimePeriod TIME_PERIOD_UNFOLD_WIDTH( 0.0f,  0.36f ); ///< Start at 0ms, duration 360ms
50 const TimePeriod TIME_PERIOD_UNFOLD_HEIGHT( 0.04f, 0.36f ); ///< Start at 40ms, duration 360ms
51 const TimePeriod TIME_PERIOD_UNFOLD_NAME_OPACITY( 0.0f, 0.08f ); ///< Start at 0ms, duration 80ms
52 const TimePeriod TIME_PERIOD_UNFOLD_DETAIL_OPACITY( 0.08f, 0.08f ); ///< Start at 80ms, duration 80ms
53 const TimePeriod TIME_PERIOD_UNFOLD_SIBLING_OPACITY( 0.0f, 0.08f ); ///< Start at 0ms, duration 80ms
54 const TimePeriod TIME_PERIOD_UNFOLD_MESH_MORPH( 0.0f, 0.4f ); ///< Start at 0ms, duration 400ms
55
56 /*
57  * The constants below are used to create the following Fold Animation:
58  *
59  * 0ms  50  100  150  200  250  300  350  400 Total Animation time in Milliseconds
60  * |    |    |    |    |    |    |    |    |
61  * |    |o---------------------------------o  X Position Animation            ( 64ms To 400ms)
62  * o---------------------------------o|    |  Y Position Animation            (  0ms To 336ms)
63  * |    |o---------------------------------o  Width Animation                 ( 64ms To 400ms)
64  * o---------------------------------o|    |  Height Animation                (  0ms To 336ms)
65  * |       o-------o   |    |    |    |    |  Fade in Name Text animation     ( 80ms To 160ms)
66  * o-------o |    |    |    |    |    |    |  Fade out Details Text animation (  0ms To  80ms)
67  * |    |    |    |    |    |    | o-------o  Fade in other cards animation   (320ms To 400ms)
68  * o---------------------------------------o  Morph Animation                 (  0ms To 400ms)
69  */
70 const TimePeriod TIME_PERIOD_FOLD_X( 0.064f, 0.336f ); ///< Start at 64ms, duration 336ms
71 const TimePeriod TIME_PERIOD_FOLD_Y( 0.0f, 0.336f ); ///< Start at 0ms, duration 336ms
72 const TimePeriod TIME_PERIOD_FOLD_WIDTH( 0.064f, 0.336f ); ///< Start at 64ms, duration 336ms
73 const TimePeriod TIME_PERIOD_FOLD_HEIGHT( 0.0f, 0.336f ); ///< Start at 0ms, duration 336ms
74 const TimePeriod TIME_PERIOD_FOLD_NAME_OPACITY( 0.08f, 0.08f ); ///< Start at 80ms, duration 80ms
75 const TimePeriod TIME_PERIOD_FOLD_DETAIL_OPACITY( 0.0f, 0.08f ); ///< Start at 0ms, duration 80ms
76 const TimePeriod TIME_PERIOD_FOLD_SIBLING_OPACITY( 0.32f, 0.08f ); ///< Start at 320ms, duration 80ms
77 const TimePeriod TIME_PERIOD_FOLD_MESH_MORPH( 0.0f, 0.4f ); ///< Start at 0ms, duration 400ms
78
79 AlphaFunction ALPHA_FUNCTION_UNFOLD( AlphaFunction::DEFAULT ); ///< Alpha function used for the Unfold Animation
80 AlphaFunction ALPHA_FUNCTION_FOLD( AlphaFunction::EASE_IN_OUT ); ///< Alpha function used for the Fold Animation
81
82 const Vector4 HEADER_COLOR( 231.0f/255.0f, 231.0f/255.0f, 231.0f/255.0f, 1.0f ); ///< The color of the header
83
84 } // unnamed namespace
85
86 ContactCard::ContactCard(
87     const ContactCardLayoutInfo& contactCardLayoutInfo,
88     const std::string& contactName,
89     const std::string& contactAddress,
90     const std::string& imagePath,
91     const Vector2& position )
92 : mTapDetector(),
93   mContactCard(),
94   mHeader(),
95   mClippedImage(),
96   mNameText(),
97   mDetailText(),
98   mSlotDelegate( this ),
99   mContactCardLayoutInfo( contactCardLayoutInfo ),
100   foldedPosition( position ),
101   mClippedImagePropertyIndex( Property::INVALID_INDEX ),
102   mFolded( true )
103 {
104   // Create a control which will be used for the background and to clip the contents
105   mContactCard = Control::New();
106   mContactCard.SetProperty( Control::Property::BACKGROUND,
107                             Property::Map().Add( Toolkit::Visual::Property::TYPE, Visual::COLOR )
108                                            .Add( ColorVisual::Property::MIX_COLOR, Color::WHITE ) );
109   mContactCard.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
110   mContactCard.SetParentOrigin( ParentOrigin::TOP_LEFT );
111   mContactCard.SetAnchorPoint( AnchorPoint::TOP_LEFT );
112   mContactCard.SetPosition( foldedPosition.x, foldedPosition.y );
113   mContactCard.SetSize( mContactCardLayoutInfo.foldedSize );
114   Stage::GetCurrent().Add( mContactCard );
115
116   // Create the header which will be shown only when the contact is unfolded
117   mHeader = Control::New();
118   mHeader.SetSize( mContactCardLayoutInfo.headerSize );
119   mHeader.SetProperty( Control::Property::BACKGROUND,
120                        Property::Map().Add( Toolkit::Visual::Property::TYPE, Visual::COLOR )
121                                       .Add( ColorVisual::Property::MIX_COLOR, HEADER_COLOR ) );
122   mHeader.SetParentOrigin( ParentOrigin::TOP_LEFT );
123   mHeader.SetAnchorPoint( AnchorPoint::TOP_LEFT );
124   mHeader.SetPosition( mContactCardLayoutInfo.headerFoldedPosition.x, mContactCardLayoutInfo.headerFoldedPosition.y );
125
126   // Create a clipped image (whose clipping can be animated)
127   mClippedImage = ClippedImage::Create( imagePath, mClippedImagePropertyIndex );
128   mClippedImage.SetSize( mContactCardLayoutInfo.imageSize );
129   mClippedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
130   mClippedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
131   mClippedImage.SetPosition( mContactCardLayoutInfo.imageFoldedPosition.x, mContactCardLayoutInfo.imageFoldedPosition.y );
132   mContactCard.Add( mClippedImage );
133
134   // Add the text label for just the name
135   mNameText = TextLabel::New( contactName );
136   mNameText.SetStyleName( "ContactNameTextLabel" );
137   mNameText.SetParentOrigin( ParentOrigin::TOP_LEFT );
138   mNameText.SetAnchorPoint( AnchorPoint::TOP_LEFT );
139   mNameText.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
140   mNameText.SetPosition( mContactCardLayoutInfo.textFoldedPosition.x, mContactCardLayoutInfo.textFoldedPosition.y );
141   mContactCard.Add( mNameText );
142
143   // Create the detail text-label
144   std::string detailString( contactName );
145   detailString += "\n\n";
146   detailString += contactAddress;
147
148   mDetailText = TextLabel::New( detailString );
149   mDetailText.SetStyleName( "ContactDetailTextLabel" );
150   mDetailText.SetParentOrigin( ParentOrigin::TOP_LEFT );
151   mDetailText.SetAnchorPoint( AnchorPoint::TOP_LEFT );
152   mDetailText.SetPosition( mContactCardLayoutInfo.textFoldedPosition.x, mContactCardLayoutInfo.textFoldedPosition.y );
153   mDetailText.SetSize( Vector2( mContactCardLayoutInfo.unfoldedSize.width - mContactCardLayoutInfo.textFoldedPosition.x * 2.0f, 0.0f ) );
154   mDetailText.SetOpacity( 0.0f );
155
156   // Attach tap detection to the overall clip control
157   mTapDetector = TapGestureDetector::New();
158   mTapDetector.Attach( mContactCard );
159   mTapDetector.DetectedSignal().Connect( mSlotDelegate, &ContactCard::OnTap );
160 }
161
162 ContactCard::~ContactCard()
163 {
164   if( mContactCard )
165   {
166     mContactCard.Unparent();
167   }
168 }
169
170 void ContactCard::OnTap( Actor actor, const TapGesture& gesture )
171 {
172   if( mFolded )
173   {
174     mContactCard.Add( mHeader );
175     mContactCard.Add( mDetailText );
176
177     // Animate the size of the control (and clipping area)
178     Animation animation = Animation::New( 0.0f ); // Overall duration is unimportant as superseded by TimePeriods set later
179     animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ),  mContactCardLayoutInfo.unfoldedPosition.x,  ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
180     animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ),  mContactCardLayoutInfo.unfoldedPosition.y,  ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
181     animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ),  mContactCardLayoutInfo.unfoldedSize.width,  ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_WIDTH );
182     animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.unfoldedSize.height, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_HEIGHT );
183
184     // Animate the header area into position
185     animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
186     animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
187
188     // Animate the clipped image into the unfolded position and into a quad
189     animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ),  mContactCardLayoutInfo.imageUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
190     animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ),  mContactCardLayoutInfo.imageUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
191     animation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::QUAD_GEOMETRY, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_MESH_MORPH );
192
193     // Fade out the opacity of the name, and animate into the unfolded position
194     animation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_NAME_OPACITY );
195     animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ),  mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
196     animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ),  mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
197
198     // Fade in the opacity of the detail, and animate into the unfolded position
199     animation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_DETAIL_OPACITY );
200     animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ),  mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
201     animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ),  mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
202
203     // Fade out all the siblings
204     Actor parent = actor.GetParent();
205     for( size_t i = 0; i < parent.GetChildCount(); ++i )
206     {
207       Actor sibling = parent.GetChildAt( i );
208       if( sibling != actor )
209       {
210         animation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_SIBLING_OPACITY );
211         sibling.SetSensitive( false );
212       }
213     }
214
215     animation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished );
216     animation.Play();
217   }
218   else
219   {
220     mContactCard.Add( mNameText );
221
222     // Animate the size of the control (and clipping area)
223     Animation animation = Animation::New( 0.0f ); // Overall duration is unimportant as superseded by TimePeriods set later
224     animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ),  foldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
225     animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ),  foldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
226     animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ),  mContactCardLayoutInfo.foldedSize.width,  ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_WIDTH );
227     animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.foldedSize.height, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_HEIGHT );
228
229     // Animate the header area out of position
230     animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
231     animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
232
233     // Animate the clipped image into the folded position and into a circle
234     animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ),  mContactCardLayoutInfo.imageFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
235     animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ),  mContactCardLayoutInfo.imageFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
236     animation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::CIRCLE_GEOMETRY, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_MESH_MORPH );
237
238     // Fade in the opacity of the name, and animate into the folded position
239     animation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_NAME_OPACITY );
240     animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ),  mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
241     animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ),  mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
242
243     // Fade out the opacity of the detail, and animate into the folded position
244     animation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_DETAIL_OPACITY );
245     animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ),  mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
246     animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ),  mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
247
248     // Slowly fade in all the siblings
249     Actor parent = actor.GetParent();
250     for( size_t i = 0; i < parent.GetChildCount(); ++i )
251     {
252       Actor sibling = parent.GetChildAt( i );
253       if( sibling != actor )
254       {
255         animation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_SIBLING_OPACITY );
256         sibling.SetSensitive( true );
257       }
258     }
259
260     animation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished );
261     animation.Play();
262   }
263
264   mFolded = !mFolded;
265 }
266
267 void ContactCard::OnAnimationFinished( Dali::Animation& animation )
268 {
269   if( mFolded )
270   {
271     mHeader.Unparent();
272     mDetailText.Unparent();
273   }
274   else
275   {
276     mNameText.Unparent();
277   }
278 }