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 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 5 * you may not use this file except in compliance with the License.
... ... @@ -20,10 +20,12 @@
20 20  
21 21 // EXTERNAL INCLUDES
22 22 #include <dali-toolkit/dali-toolkit.h>
  23 +#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
23 24  
24 25 // INTERNAL INCLUDES
25 26 #include "contact-card-layout-info.h"
26 27 #include "clipped-image.h"
  28 +#include "masked-image.h"
27 29  
28 30 using namespace Dali;
29 31 using namespace Dali::Toolkit;
... ... @@ -93,14 +95,20 @@ ContactCard::ContactCard(
93 95 mContactCard(),
94 96 mHeader(),
95 97 mClippedImage(),
  98 + mMaskedImage(),
96 99 mNameText(),
97 100 mDetailText(),
  101 + mAnimation(),
98 102 mSlotDelegate( this ),
99 103 mContactCardLayoutInfo( contactCardLayoutInfo ),
100 104 foldedPosition( position ),
101 105 mClippedImagePropertyIndex( Property::INVALID_INDEX ),
102 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 112 // Create a control which will be used for the background and to clip the contents
105 113 mContactCard = Control::New();
106 114 mContactCard.SetProperty( Control::Property::BACKGROUND,
... ... @@ -111,7 +119,7 @@ ContactCard::ContactCard(
111 119 mContactCard.SetAnchorPoint( AnchorPoint::TOP_LEFT );
112 120 mContactCard.SetPosition( foldedPosition.x, foldedPosition.y );
113 121 mContactCard.SetSize( mContactCardLayoutInfo.foldedSize );
114   - Stage::GetCurrent().Add( mContactCard );
  122 + stage.Add( mContactCard );
115 123  
116 124 // Create the header which will be shown only when the contact is unfolded
117 125 mHeader = Control::New();
... ... @@ -129,8 +137,17 @@ ContactCard::ContactCard(
129 137 mClippedImage.SetParentOrigin( ParentOrigin::TOP_LEFT );
130 138 mClippedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT );
131 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 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 151 // Add the text label for just the name
135 152 mNameText = TextLabel::New( contactName );
136 153 mNameText.SetStyleName( "ContactNameTextLabel" );
... ... @@ -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 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 206 mContactCard.Add( mHeader );
175 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 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 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 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 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 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 238 // Fade out all the siblings
204   - Actor parent = actor.GetParent();
  239 + Actor parent = mContactCard.GetParent();
205 240 for( size_t i = 0; i < parent.GetChildCount(); ++i )
206 241 {
207 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 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 253 else
219 254 {
  255 + // Remove key-input-focus from our contact-card when we are folded
  256 + keyInputFocusManager.RemoveFocus( mContactCard );
  257 +
220 258 mContactCard.Add( mNameText );
221 259  
222 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 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 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 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 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 285 // Slowly fade in all the siblings
249   - Actor parent = actor.GetParent();
  286 + Actor parent = mContactCard.GetParent();
250 287 for( size_t i = 0; i < parent.GetChildCount(); ++i )
251 288 {
252 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 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 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 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 7 * Licensed under the Apache License, Version 2.0 (the "License");
8 8 * you may not use this file except in compliance with the License.
... ... @@ -21,6 +21,7 @@
21 21 // EXTERNAL INCLUDES
22 22 #include <string>
23 23 #include <dali/public-api/actors/actor.h>
  24 +#include <dali/public-api/animation/animation.h>
24 25 #include <dali/public-api/events/tap-gesture-detector.h>
25 26 #include <dali/public-api/object/ref-object.h>
26 27 #include <dali-toolkit/public-api/controls/control.h>
... ... @@ -67,24 +68,40 @@ private:
67 68  
68 69 /**
69 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 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 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 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 95 Dali::TapGestureDetector mTapDetector; ///< Used for tap detection.
82 96 Dali::Toolkit::Control mContactCard; ///< Used for the background and to clip the contents.
83 97 Dali::Toolkit::Control mHeader; ///< Header shown when unfolded.
84 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 100 Dali::Toolkit::Control mNameText; ///< The text shown when folded.
86 101 Dali::Toolkit::Control mDetailText; ///< The text shown when unfolded.
87 102  
  103 + Dali::Animation mAnimation; ///< The fold/unfold animation.
  104 +
88 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 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 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 5 * you may not use this file except in compliance with the License.
... ... @@ -21,12 +21,14 @@
21 21 #include <dali/public-api/adaptor-framework/key.h>
22 22 #include <dali/public-api/common/stage.h>
23 23 #include <dali/public-api/events/key-event.h>
  24 +#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
24 25  
25 26 // INTERNAL INCLUDES
26 27 #include "contact-card-layouter.h"
27 28 #include "contact-data.h"
28 29  
29 30 using namespace Dali;
  31 +using namespace Dali::Toolkit;
30 32  
31 33 namespace
32 34 {
... ... @@ -51,6 +53,8 @@ const char * const THEME_PATH( DEMO_STYLE_DIR &quot;contact-cards-example-theme.json&quot;
51 53 * This clipping comes in the form of a Circle or Quad.
52 54 * The Vertex shader mixes in the Circle and Quad geometry depending on the value of a uniform float.
53 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 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 104 {
101 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