Commit c973151b54264a643b5cf15fcc904b351b116c31

Authored by Adeel Kazmi
1 parent 31cfda0c

(ContactCards) Use a mask image when not animating & add Back/Esc key handling to fold contact-cards

- Applying a mask is better quality
- When a contact card is unfolded and Esc/Back is pressed, the contact card is folded
  - Before we used to Quit the application

Change-Id: I85f245dea9e24b98e312a7870129b2c44711ba2d
examples/contact-cards/contact-card.cpp
1 /* 1 /*
2 - * Copyright (c) 2016 Samsung Electronics Co., Ltd. 2 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -20,10 +20,12 @@ @@ -20,10 +20,12 @@
20 20
21 // EXTERNAL INCLUDES 21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/dali-toolkit.h> 22 #include <dali-toolkit/dali-toolkit.h>
  23 +#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
23 24
24 // INTERNAL INCLUDES 25 // INTERNAL INCLUDES
25 #include "contact-card-layout-info.h" 26 #include "contact-card-layout-info.h"
26 #include "clipped-image.h" 27 #include "clipped-image.h"
  28 +#include "masked-image.h"
27 29
28 using namespace Dali; 30 using namespace Dali;
29 using namespace Dali::Toolkit; 31 using namespace Dali::Toolkit;
@@ -93,14 +95,20 @@ ContactCard::ContactCard( @@ -93,14 +95,20 @@ ContactCard::ContactCard(
93 mContactCard(), 95 mContactCard(),
94 mHeader(), 96 mHeader(),
95 mClippedImage(), 97 mClippedImage(),
  98 + mMaskedImage(),
96 mNameText(), 99 mNameText(),
97 mDetailText(), 100 mDetailText(),
  101 + mAnimation(),
98 mSlotDelegate( this ), 102 mSlotDelegate( this ),
99 mContactCardLayoutInfo( contactCardLayoutInfo ), 103 mContactCardLayoutInfo( contactCardLayoutInfo ),
100 foldedPosition( position ), 104 foldedPosition( position ),
101 mClippedImagePropertyIndex( Property::INVALID_INDEX ), 105 mClippedImagePropertyIndex( Property::INVALID_INDEX ),
102 mFolded( true ) 106 mFolded( true )
103 { 107 {
  108 + // Connect to the stage's key signal to allow Back and Escape to fold a contact card if it is unfolded
  109 + Stage stage = Stage::GetCurrent();
  110 + stage.KeyEventSignal().Connect( mSlotDelegate, &ContactCard::OnKeyEvent );
  111 +
104 // Create a control which will be used for the background and to clip the contents 112 // Create a control which will be used for the background and to clip the contents
105 mContactCard = Control::New(); 113 mContactCard = Control::New();
106 mContactCard.SetProperty( Control::Property::BACKGROUND, 114 mContactCard.SetProperty( Control::Property::BACKGROUND,
@@ -111,7 +119,7 @@ ContactCard::ContactCard( @@ -111,7 +119,7 @@ ContactCard::ContactCard(
111 mContactCard.SetAnchorPoint( AnchorPoint::TOP_LEFT ); 119 mContactCard.SetAnchorPoint( AnchorPoint::TOP_LEFT );
112 mContactCard.SetPosition( foldedPosition.x, foldedPosition.y ); 120 mContactCard.SetPosition( foldedPosition.x, foldedPosition.y );
113 mContactCard.SetSize( mContactCardLayoutInfo.foldedSize ); 121 mContactCard.SetSize( mContactCardLayoutInfo.foldedSize );
114 - Stage::GetCurrent().Add( mContactCard ); 122 + stage.Add( mContactCard );
115 123
116 // Create the header which will be shown only when the contact is unfolded 124 // Create the header which will be shown only when the contact is unfolded
117 mHeader = Control::New(); 125 mHeader = Control::New();
@@ -129,8 +137,17 @@ ContactCard::ContactCard( @@ -129,8 +137,17 @@ ContactCard::ContactCard(
129 mClippedImage.SetParentOrigin( ParentOrigin::TOP_LEFT ); 137 mClippedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
130 mClippedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT ); 138 mClippedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
131 mClippedImage.SetPosition( mContactCardLayoutInfo.imageFoldedPosition.x, mContactCardLayoutInfo.imageFoldedPosition.y ); 139 mClippedImage.SetPosition( mContactCardLayoutInfo.imageFoldedPosition.x, mContactCardLayoutInfo.imageFoldedPosition.y );
  140 + mClippedImage.SetVisible( false ); // Hide image as we only want to display it if we are animating or unfolded
132 mContactCard.Add( mClippedImage ); 141 mContactCard.Add( mClippedImage );
133 142
  143 + // Create an image with a mask which is to be used when the contact is folded
  144 + mMaskedImage = MaskedImage::Create( imagePath );
  145 + mMaskedImage.SetSize( mContactCardLayoutInfo.imageSize );
  146 + mMaskedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
  147 + mMaskedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  148 + mMaskedImage.SetPosition( mContactCardLayoutInfo.imageFoldedPosition.x, mContactCardLayoutInfo.imageFoldedPosition.y );
  149 + mContactCard.Add( mMaskedImage );
  150 +
134 // Add the text label for just the name 151 // Add the text label for just the name
135 mNameText = TextLabel::New( contactName ); 152 mNameText = TextLabel::New( contactName );
136 mNameText.SetStyleName( "ContactNameTextLabel" ); 153 mNameText.SetStyleName( "ContactNameTextLabel" );
@@ -167,112 +184,158 @@ ContactCard::~ContactCard() @@ -167,112 +184,158 @@ ContactCard::~ContactCard()
167 } 184 }
168 } 185 }
169 186
170 -void ContactCard::OnTap( Actor actor, const TapGesture& gesture ) 187 +void ContactCard::OnTap( Actor actor, const TapGesture& /* gesture */ )
  188 +{
  189 + if( actor == mContactCard )
  190 + {
  191 + Animate();
  192 + }
  193 +}
  194 +
  195 +void ContactCard::Animate()
171 { 196 {
  197 + KeyInputFocusManager keyInputFocusManager = KeyInputFocusManager::Get();
  198 +
  199 + mAnimation = Animation::New( 0.0f ); // Overall duration is unimportant as superseded by TimePeriods set later
  200 +
172 if( mFolded ) 201 if( mFolded )
173 { 202 {
  203 + // Set key-input-focus to our contact-card so that we can fold the contact-card if we receive a Back or Esc key
  204 + keyInputFocusManager.SetFocus( mContactCard );
  205 +
174 mContactCard.Add( mHeader ); 206 mContactCard.Add( mHeader );
175 mContactCard.Add( mDetailText ); 207 mContactCard.Add( mDetailText );
176 208
  209 + // Show clipped-image to animate geometry and hide the masked-image
  210 + mClippedImage.SetVisible( true );
  211 + mMaskedImage.SetVisible( false );
  212 +
177 // Animate the size of the control (and clipping area) 213 // 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 ); 214 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ), mContactCardLayoutInfo.unfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
  215 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.unfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
  216 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ), mContactCardLayoutInfo.unfoldedSize.width, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_WIDTH );
  217 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.unfoldedSize.height, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_HEIGHT );
183 218
184 // Animate the header area into position 219 // 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 ); 220 + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
  221 + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
187 222
188 // Animate the clipped image into the unfolded position and into a quad 223 // 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 ); 224 + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ), mContactCardLayoutInfo.imageUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
  225 + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.imageUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
  226 + mAnimation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::QUAD_GEOMETRY, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_MESH_MORPH );
192 227
193 // Fade out the opacity of the name, and animate into the unfolded position 228 // 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 ); 229 + mAnimation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_NAME_OPACITY );
  230 + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
  231 + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
197 232
198 // Fade in the opacity of the detail, and animate into the unfolded position 233 // 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 ); 234 + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_DETAIL_OPACITY );
  235 + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X );
  236 + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y );
202 237
203 // Fade out all the siblings 238 // Fade out all the siblings
204 - Actor parent = actor.GetParent(); 239 + Actor parent = mContactCard.GetParent();
205 for( size_t i = 0; i < parent.GetChildCount(); ++i ) 240 for( size_t i = 0; i < parent.GetChildCount(); ++i )
206 { 241 {
207 Actor sibling = parent.GetChildAt( i ); 242 Actor sibling = parent.GetChildAt( i );
208 - if( sibling != actor ) 243 + if( sibling != mContactCard )
209 { 244 {
210 - animation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_SIBLING_OPACITY ); 245 + mAnimation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_SIBLING_OPACITY );
211 sibling.SetSensitive( false ); 246 sibling.SetSensitive( false );
212 } 247 }
213 } 248 }
214 249
215 - animation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished );  
216 - animation.Play(); 250 + mAnimation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished );
  251 + mAnimation.Play();
217 } 252 }
218 else 253 else
219 { 254 {
  255 + // Remove key-input-focus from our contact-card when we are folded
  256 + keyInputFocusManager.RemoveFocus( mContactCard );
  257 +
220 mContactCard.Add( mNameText ); 258 mContactCard.Add( mNameText );
221 259
222 // Animate the size of the control (and clipping area) 260 // 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 ); 261 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ), foldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
  262 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ), foldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
  263 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ), mContactCardLayoutInfo.foldedSize.width, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_WIDTH );
  264 + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.foldedSize.height, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_HEIGHT );
228 265
229 // Animate the header area out of position 266 // 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 ); 267 + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
  268 + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
232 269
233 // Animate the clipped image into the folded position and into a circle 270 // 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 ); 271 + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ), mContactCardLayoutInfo.imageFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
  272 + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.imageFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
  273 + mAnimation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::CIRCLE_GEOMETRY, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_MESH_MORPH );
237 274
238 // Fade in the opacity of the name, and animate into the folded position 275 // 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 ); 276 + mAnimation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_NAME_OPACITY );
  277 + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
  278 + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
242 279
243 // Fade out the opacity of the detail, and animate into the folded position 280 // 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 ); 281 + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_DETAIL_OPACITY );
  282 + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X );
  283 + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y );
247 284
248 // Slowly fade in all the siblings 285 // Slowly fade in all the siblings
249 - Actor parent = actor.GetParent(); 286 + Actor parent = mContactCard.GetParent();
250 for( size_t i = 0; i < parent.GetChildCount(); ++i ) 287 for( size_t i = 0; i < parent.GetChildCount(); ++i )
251 { 288 {
252 Actor sibling = parent.GetChildAt( i ); 289 Actor sibling = parent.GetChildAt( i );
253 - if( sibling != actor ) 290 + if( sibling != mContactCard )
254 { 291 {
255 - animation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_SIBLING_OPACITY ); 292 + mAnimation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_SIBLING_OPACITY );
256 sibling.SetSensitive( true ); 293 sibling.SetSensitive( true );
257 } 294 }
258 } 295 }
259 296
260 - animation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished );  
261 - animation.Play(); 297 + mAnimation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished );
  298 + mAnimation.Play();
262 } 299 }
263 300
264 mFolded = !mFolded; 301 mFolded = !mFolded;
265 } 302 }
266 303
267 -void ContactCard::OnAnimationFinished( Dali::Animation& animation ) 304 +void ContactCard::OnAnimationFinished( Animation& animation )
268 { 305 {
269 - if( mFolded ) 306 + // Ensure the finishing animation is the latest as we do not want to change state if a previous animation has finished
  307 + if( mAnimation == animation )
270 { 308 {
271 - mHeader.Unparent();  
272 - mDetailText.Unparent(); 309 + if( mFolded )
  310 + {
  311 + mHeader.Unparent();
  312 + mDetailText.Unparent();
  313 +
  314 + // Hide the clipped-image as we have finished animating the geometry and show the masked-image again
  315 + mClippedImage.SetVisible( false );
  316 + mMaskedImage.SetVisible( true );
  317 + }
  318 + else
  319 + {
  320 + mNameText.Unparent();
  321 + }
  322 + mAnimation.Reset();
273 } 323 }
274 - else 324 +}
  325 +
  326 +void ContactCard::OnKeyEvent( const KeyEvent& event )
  327 +{
  328 + if( ( ! mFolded ) && // If we're folded then there's no need to do any more checking
  329 + ( event.state == KeyEvent::Down ) )
275 { 330 {
276 - mNameText.Unparent(); 331 + if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
  332 + {
  333 + KeyInputFocusManager keyInputFocusManager = KeyInputFocusManager::Get();
  334 + if( keyInputFocusManager.GetCurrentFocusControl() == mContactCard )
  335 + {
  336 + // Our contact-card is set to receive focus so call OnTap which should trigger the required animation
  337 + Animate();
  338 + }
  339 + }
277 } 340 }
278 } 341 }
examples/contact-cards/contact-card.h
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 #define CONTACT_CARD_H 2 #define CONTACT_CARD_H
3 3
4 /* 4 /*
5 - * Copyright (c) 2016 Samsung Electronics Co., Ltd. 5 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
6 * 6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License. 8 * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 // EXTERNAL INCLUDES 21 // EXTERNAL INCLUDES
22 #include <string> 22 #include <string>
23 #include <dali/public-api/actors/actor.h> 23 #include <dali/public-api/actors/actor.h>
  24 +#include <dali/public-api/animation/animation.h>
24 #include <dali/public-api/events/tap-gesture-detector.h> 25 #include <dali/public-api/events/tap-gesture-detector.h>
25 #include <dali/public-api/object/ref-object.h> 26 #include <dali/public-api/object/ref-object.h>
26 #include <dali-toolkit/public-api/controls/control.h> 27 #include <dali-toolkit/public-api/controls/control.h>
@@ -67,24 +68,40 @@ private: @@ -67,24 +68,40 @@ private:
67 68
68 /** 69 /**
69 * @brief Called when this contact card is tapped. 70 * @brief Called when this contact card is tapped.
70 - * @param[in] actor The tapped actor.  
71 - * @param[in] gesture The tap gesture. 71 + * @param[in] actor The tapped actor.
  72 + * @param[in] gesture The tap gesture.
72 */ 73 */
73 void OnTap( Dali::Actor actor, const Dali::TapGesture& gesture ); 74 void OnTap( Dali::Actor actor, const Dali::TapGesture& gesture );
74 75
75 /** 76 /**
  77 + * @brief Animates the fold/unfold animation as required.
  78 + */
  79 + void Animate();
  80 +
  81 + /**
76 * @brief Called when the animation finishes. 82 * @brief Called when the animation finishes.
77 - * @param[in] animation The animation which has just finished. 83 + * @param[in] animation The animation which has just finished.
78 */ 84 */
79 void OnAnimationFinished( Dali::Animation& animation ); 85 void OnAnimationFinished( Dali::Animation& animation );
80 86
  87 + /**
  88 + * @brief Called when any key event is received
  89 + *
  90 + * Will use this to fold a contact card if it is unfolded.
  91 + * @param[in] event The key event information
  92 + */
  93 + void OnKeyEvent( const Dali::KeyEvent& event );
  94 +
81 Dali::TapGestureDetector mTapDetector; ///< Used for tap detection. 95 Dali::TapGestureDetector mTapDetector; ///< Used for tap detection.
82 Dali::Toolkit::Control mContactCard; ///< Used for the background and to clip the contents. 96 Dali::Toolkit::Control mContactCard; ///< Used for the background and to clip the contents.
83 Dali::Toolkit::Control mHeader; ///< Header shown when unfolded. 97 Dali::Toolkit::Control mHeader; ///< Header shown when unfolded.
84 Dali::Toolkit::Control mClippedImage; ///< The image representing the contact (whose clipping can be animated). 98 Dali::Toolkit::Control mClippedImage; ///< The image representing the contact (whose clipping can be animated).
  99 + Dali::Toolkit::Control mMaskedImage; ///< The image with a mask (better quality around the edges than the clipped image when folded).
85 Dali::Toolkit::Control mNameText; ///< The text shown when folded. 100 Dali::Toolkit::Control mNameText; ///< The text shown when folded.
86 Dali::Toolkit::Control mDetailText; ///< The text shown when unfolded. 101 Dali::Toolkit::Control mDetailText; ///< The text shown when unfolded.
87 102
  103 + Dali::Animation mAnimation; ///< The fold/unfold animation.
  104 +
88 Dali::SlotDelegate< ContactCard > mSlotDelegate; ///< Used to automatically disconnect our member functions from signals that this class connects to upon destruction. Can be used instead of inheriting from ConnectionTracker. 105 Dali::SlotDelegate< ContactCard > mSlotDelegate; ///< Used to automatically disconnect our member functions from signals that this class connects to upon destruction. Can be used instead of inheriting from ConnectionTracker.
89 106
90 const ContactCardLayoutInfo& mContactCardLayoutInfo; ///< Reference to the common data used by all contact cards. 107 const ContactCardLayoutInfo& mContactCardLayoutInfo; ///< Reference to the common data used by all contact cards.
examples/contact-cards/contact-cards-example.cpp
1 /* 1 /*
2 - * Copyright (c) 2016 Samsung Electronics Co., Ltd. 2 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -21,12 +21,14 @@ @@ -21,12 +21,14 @@
21 #include <dali/public-api/adaptor-framework/key.h> 21 #include <dali/public-api/adaptor-framework/key.h>
22 #include <dali/public-api/common/stage.h> 22 #include <dali/public-api/common/stage.h>
23 #include <dali/public-api/events/key-event.h> 23 #include <dali/public-api/events/key-event.h>
  24 +#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
24 25
25 // INTERNAL INCLUDES 26 // INTERNAL INCLUDES
26 #include "contact-card-layouter.h" 27 #include "contact-card-layouter.h"
27 #include "contact-data.h" 28 #include "contact-data.h"
28 29
29 using namespace Dali; 30 using namespace Dali;
  31 +using namespace Dali::Toolkit;
30 32
31 namespace 33 namespace
32 { 34 {
@@ -51,6 +53,8 @@ const char * const THEME_PATH( DEMO_STYLE_DIR &quot;contact-cards-example-theme.json&quot; @@ -51,6 +53,8 @@ const char * const THEME_PATH( DEMO_STYLE_DIR &quot;contact-cards-example-theme.json&quot;
51 * This clipping comes in the form of a Circle or Quad. 53 * This clipping comes in the form of a Circle or Quad.
52 * The Vertex shader mixes in the Circle and Quad geometry depending on the value of a uniform float. 54 * The Vertex shader mixes in the Circle and Quad geometry depending on the value of a uniform float.
53 * Animating this float between CIRCLE_GEOMETRY and QUAD_GEOMETRY is what enables the morphing between the two geometries. 55 * Animating this float between CIRCLE_GEOMETRY and QUAD_GEOMETRY is what enables the morphing between the two geometries.
  56 + * MaskedImage: This namespace provides a helper function which creates an ImageView with a mask that matches the Circle geometry provided by ClippedImage.
  57 + * Using a mask yields much better quality than when using an image with a circle geometry, so this is ONLY used when the contact card is folded.
54 */ 58 */
55 class ContactCardController : public ConnectionTracker // Inherit from ConnectionTracker so that our signals can be automatically disconnected upon our destruction. 59 class ContactCardController : public ConnectionTracker // Inherit from ConnectionTracker so that our signals can be automatically disconnected upon our destruction.
56 { 60 {
@@ -100,9 +104,13 @@ private: @@ -100,9 +104,13 @@ private:
100 { 104 {
101 if( event.state == KeyEvent::Down ) 105 if( event.state == KeyEvent::Down )
102 { 106 {
103 - if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) ) 107 + KeyInputFocusManager keyInputFocusManager = KeyInputFocusManager::Get();
  108 + if( ! keyInputFocusManager.GetCurrentFocusControl() ) // Don't quit if a control has focus
104 { 109 {
105 - mApplication.Quit(); 110 + if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
  111 + {
  112 + mApplication.Quit();
  113 + }
106 } 114 }
107 } 115 }
108 } 116 }
examples/contact-cards/masked-image.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2018 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 +// HEADER
  19 +#include "masked-image.h"
  20 +
  21 +// EXTERNAL INCLUDES
  22 +#include <dali-toolkit/dali-toolkit.h>
  23 +
  24 +namespace MaskedImage
  25 +{
  26 +
  27 +using namespace Dali;
  28 +using namespace Dali::Toolkit;
  29 +
  30 +namespace
  31 +{
  32 +const char* const IMAGE_MASK ( DEMO_IMAGE_DIR "contact-cards-mask.png" );
  33 +} // unnamed namespace
  34 +
  35 +Dali::Toolkit::Control Create( const std::string& imagePath )
  36 +{
  37 + Control maskedImage = ImageView::New();
  38 + maskedImage.SetProperty(
  39 + Toolkit::ImageView::Property::IMAGE,
  40 + Property::Map().Add( Visual::Property::TYPE, Toolkit::Visual::Type::IMAGE )
  41 + .Add( ImageVisual::Property::URL, imagePath )
  42 + .Add( ImageVisual::Property::ALPHA_MASK_URL, IMAGE_MASK )
  43 + );
  44 + return maskedImage;
  45 +}
  46 +
  47 +} // namespace ClippedImage
examples/contact-cards/masked-image.h 0 → 100644
  1 +#ifndef MASKED_IMAGE_H
  2 +#define MASKED_IMAGE_H
  3 +
  4 +/*
  5 + * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +// EXTERNAL INCLUDES
  22 +#include <string>
  23 +#include <dali-toolkit/public-api/controls/control.h>
  24 +
  25 +/**
  26 + * @brief This namespace provides a helper function which creates an ImageView with a mask that matches the Circle geometry provided by ClippedImage.
  27 + *
  28 + * Using a mask yields much better quality than when using an image with a circle geometry.
  29 + * @see ClippedImage
  30 + */
  31 +namespace MaskedImage
  32 +{
  33 +
  34 +/**
  35 + * @brief Creates an image with a circular mask.
  36 + *
  37 + * @param[in] imagePath The path to the image to show.
  38 + * @return The ImageView with a mask control.
  39 + */
  40 +Dali::Toolkit::Control Create( const std::string& imagePath );
  41 +
  42 +} // namespace ClippedImage
  43 +
  44 +#endif // MASKED_IMAGE_H
resources/images/contact-cards-mask.png 0 → 100644

3.22 KB