diff --git a/examples/contact-cards/contact-card.cpp b/examples/contact-cards/contact-card.cpp index 61fd38e..d9f55e0 100644 --- a/examples/contact-cards/contact-card.cpp +++ b/examples/contact-cards/contact-card.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,12 @@ // EXTERNAL INCLUDES #include +#include // INTERNAL INCLUDES #include "contact-card-layout-info.h" #include "clipped-image.h" +#include "masked-image.h" using namespace Dali; using namespace Dali::Toolkit; @@ -93,14 +95,20 @@ ContactCard::ContactCard( mContactCard(), mHeader(), mClippedImage(), + mMaskedImage(), mNameText(), mDetailText(), + mAnimation(), mSlotDelegate( this ), mContactCardLayoutInfo( contactCardLayoutInfo ), foldedPosition( position ), mClippedImagePropertyIndex( Property::INVALID_INDEX ), mFolded( true ) { + // Connect to the stage's key signal to allow Back and Escape to fold a contact card if it is unfolded + Stage stage = Stage::GetCurrent(); + stage.KeyEventSignal().Connect( mSlotDelegate, &ContactCard::OnKeyEvent ); + // Create a control which will be used for the background and to clip the contents mContactCard = Control::New(); mContactCard.SetProperty( Control::Property::BACKGROUND, @@ -111,7 +119,7 @@ ContactCard::ContactCard( mContactCard.SetAnchorPoint( AnchorPoint::TOP_LEFT ); mContactCard.SetPosition( foldedPosition.x, foldedPosition.y ); mContactCard.SetSize( mContactCardLayoutInfo.foldedSize ); - Stage::GetCurrent().Add( mContactCard ); + stage.Add( mContactCard ); // Create the header which will be shown only when the contact is unfolded mHeader = Control::New(); @@ -129,8 +137,17 @@ ContactCard::ContactCard( mClippedImage.SetParentOrigin( ParentOrigin::TOP_LEFT ); mClippedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT ); mClippedImage.SetPosition( mContactCardLayoutInfo.imageFoldedPosition.x, mContactCardLayoutInfo.imageFoldedPosition.y ); + mClippedImage.SetVisible( false ); // Hide image as we only want to display it if we are animating or unfolded mContactCard.Add( mClippedImage ); + // Create an image with a mask which is to be used when the contact is folded + mMaskedImage = MaskedImage::Create( imagePath ); + mMaskedImage.SetSize( mContactCardLayoutInfo.imageSize ); + mMaskedImage.SetParentOrigin( ParentOrigin::TOP_LEFT ); + mMaskedImage.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + mMaskedImage.SetPosition( mContactCardLayoutInfo.imageFoldedPosition.x, mContactCardLayoutInfo.imageFoldedPosition.y ); + mContactCard.Add( mMaskedImage ); + // Add the text label for just the name mNameText = TextLabel::New( contactName ); mNameText.SetStyleName( "ContactNameTextLabel" ); @@ -167,112 +184,158 @@ ContactCard::~ContactCard() } } -void ContactCard::OnTap( Actor actor, const TapGesture& gesture ) +void ContactCard::OnTap( Actor actor, const TapGesture& /* gesture */ ) +{ + if( actor == mContactCard ) + { + Animate(); + } +} + +void ContactCard::Animate() { + KeyInputFocusManager keyInputFocusManager = KeyInputFocusManager::Get(); + + mAnimation = Animation::New( 0.0f ); // Overall duration is unimportant as superseded by TimePeriods set later + if( mFolded ) { + // Set key-input-focus to our contact-card so that we can fold the contact-card if we receive a Back or Esc key + keyInputFocusManager.SetFocus( mContactCard ); + mContactCard.Add( mHeader ); mContactCard.Add( mDetailText ); + // Show clipped-image to animate geometry and hide the masked-image + mClippedImage.SetVisible( true ); + mMaskedImage.SetVisible( false ); + // Animate the size of the control (and clipping area) - Animation animation = Animation::New( 0.0f ); // Overall duration is unimportant as superseded by TimePeriods set later - animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ), mContactCardLayoutInfo.unfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); - animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.unfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); - animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ), mContactCardLayoutInfo.unfoldedSize.width, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_WIDTH ); - animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.unfoldedSize.height, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_HEIGHT ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ), mContactCardLayoutInfo.unfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.unfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ), mContactCardLayoutInfo.unfoldedSize.width, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_WIDTH ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.unfoldedSize.height, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_HEIGHT ); // Animate the header area into position - animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); - animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); // Animate the clipped image into the unfolded position and into a quad - animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ), mContactCardLayoutInfo.imageUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); - animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.imageUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); - animation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::QUAD_GEOMETRY, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_MESH_MORPH ); + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ), mContactCardLayoutInfo.imageUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.imageUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); + mAnimation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::QUAD_GEOMETRY, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_MESH_MORPH ); // Fade out the opacity of the name, and animate into the unfolded position - animation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_NAME_OPACITY ); - animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); - animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); + mAnimation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_NAME_OPACITY ); + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); // Fade in the opacity of the detail, and animate into the unfolded position - animation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_DETAIL_OPACITY ); - animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); - animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_DETAIL_OPACITY ); + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textUnfoldedPosition.x, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_X ); + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textUnfoldedPosition.y, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_Y ); // Fade out all the siblings - Actor parent = actor.GetParent(); + Actor parent = mContactCard.GetParent(); for( size_t i = 0; i < parent.GetChildCount(); ++i ) { Actor sibling = parent.GetChildAt( i ); - if( sibling != actor ) + if( sibling != mContactCard ) { - animation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_SIBLING_OPACITY ); + mAnimation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_UNFOLD, TIME_PERIOD_UNFOLD_SIBLING_OPACITY ); sibling.SetSensitive( false ); } } - animation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished ); - animation.Play(); + mAnimation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished ); + mAnimation.Play(); } else { + // Remove key-input-focus from our contact-card when we are folded + keyInputFocusManager.RemoveFocus( mContactCard ); + mContactCard.Add( mNameText ); // Animate the size of the control (and clipping area) - Animation animation = Animation::New( 0.0f ); // Overall duration is unimportant as superseded by TimePeriods set later - animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ), foldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); - animation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ), foldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); - animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ), mContactCardLayoutInfo.foldedSize.width, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_WIDTH ); - animation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.foldedSize.height, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_HEIGHT ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_X ), foldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::POSITION_Y ), foldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_WIDTH ), mContactCardLayoutInfo.foldedSize.width, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_WIDTH ); + mAnimation.AnimateTo( Property( mContactCard, Actor::Property::SIZE_HEIGHT ), mContactCardLayoutInfo.foldedSize.height, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_HEIGHT ); // Animate the header area out of position - animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); - animation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_X ), mContactCardLayoutInfo.headerFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); + mAnimation.AnimateTo( Property( mHeader, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.headerFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); // Animate the clipped image into the folded position and into a circle - animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ), mContactCardLayoutInfo.imageFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); - animation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.imageFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); - animation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::CIRCLE_GEOMETRY, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_MESH_MORPH ); + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_X ), mContactCardLayoutInfo.imageFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); + mAnimation.AnimateTo( Property( mClippedImage, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.imageFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); + mAnimation.AnimateTo( Property( mClippedImage, mClippedImagePropertyIndex ), ClippedImage::CIRCLE_GEOMETRY, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_MESH_MORPH ); // Fade in the opacity of the name, and animate into the folded position - animation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_NAME_OPACITY ); - animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); - animation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); + mAnimation.AnimateTo( Property( mNameText, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_NAME_OPACITY ); + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); + mAnimation.AnimateTo( Property( mNameText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); // Fade out the opacity of the detail, and animate into the folded position - animation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_DETAIL_OPACITY ); - animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); - animation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::COLOR_ALPHA ), 0.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_DETAIL_OPACITY ); + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_X ), mContactCardLayoutInfo.textFoldedPosition.x, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_X ); + mAnimation.AnimateTo( Property( mDetailText, Actor::Property::POSITION_Y ), mContactCardLayoutInfo.textFoldedPosition.y, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_Y ); // Slowly fade in all the siblings - Actor parent = actor.GetParent(); + Actor parent = mContactCard.GetParent(); for( size_t i = 0; i < parent.GetChildCount(); ++i ) { Actor sibling = parent.GetChildAt( i ); - if( sibling != actor ) + if( sibling != mContactCard ) { - animation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_SIBLING_OPACITY ); + mAnimation.AnimateTo( Property( sibling, Actor::Property::COLOR_ALPHA ), 1.0f, ALPHA_FUNCTION_FOLD, TIME_PERIOD_FOLD_SIBLING_OPACITY ); sibling.SetSensitive( true ); } } - animation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished ); - animation.Play(); + mAnimation.FinishedSignal().Connect( mSlotDelegate, &ContactCard::OnAnimationFinished ); + mAnimation.Play(); } mFolded = !mFolded; } -void ContactCard::OnAnimationFinished( Dali::Animation& animation ) +void ContactCard::OnAnimationFinished( Animation& animation ) { - if( mFolded ) + // Ensure the finishing animation is the latest as we do not want to change state if a previous animation has finished + if( mAnimation == animation ) { - mHeader.Unparent(); - mDetailText.Unparent(); + if( mFolded ) + { + mHeader.Unparent(); + mDetailText.Unparent(); + + // Hide the clipped-image as we have finished animating the geometry and show the masked-image again + mClippedImage.SetVisible( false ); + mMaskedImage.SetVisible( true ); + } + else + { + mNameText.Unparent(); + } + mAnimation.Reset(); } - else +} + +void ContactCard::OnKeyEvent( const KeyEvent& event ) +{ + if( ( ! mFolded ) && // If we're folded then there's no need to do any more checking + ( event.state == KeyEvent::Down ) ) { - mNameText.Unparent(); + if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) ) + { + KeyInputFocusManager keyInputFocusManager = KeyInputFocusManager::Get(); + if( keyInputFocusManager.GetCurrentFocusControl() == mContactCard ) + { + // Our contact-card is set to receive focus and we're unfolded so animate back to the folded state + Animate(); + } + } } } diff --git a/examples/contact-cards/contact-card.h b/examples/contact-cards/contact-card.h index 043bfde..c922e58 100644 --- a/examples/contact-cards/contact-card.h +++ b/examples/contact-cards/contact-card.h @@ -2,7 +2,7 @@ #define CONTACT_CARD_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include #include #include #include @@ -67,24 +68,40 @@ private: /** * @brief Called when this contact card is tapped. - * @param[in] actor The tapped actor. - * @param[in] gesture The tap gesture. + * @param[in] actor The tapped actor. + * @param[in] gesture The tap gesture. */ void OnTap( Dali::Actor actor, const Dali::TapGesture& gesture ); /** + * @brief Animates the fold/unfold animation as required. + */ + void Animate(); + + /** * @brief Called when the animation finishes. - * @param[in] animation The animation which has just finished. + * @param[in] animation The animation which has just finished. */ void OnAnimationFinished( Dali::Animation& animation ); + /** + * @brief Called when any key event is received + * + * Will use this to fold a contact card if it is unfolded. + * @param[in] event The key event information + */ + void OnKeyEvent( const Dali::KeyEvent& event ); + Dali::TapGestureDetector mTapDetector; ///< Used for tap detection. Dali::Toolkit::Control mContactCard; ///< Used for the background and to clip the contents. Dali::Toolkit::Control mHeader; ///< Header shown when unfolded. Dali::Toolkit::Control mClippedImage; ///< The image representing the contact (whose clipping can be animated). + Dali::Toolkit::Control mMaskedImage; ///< The image with a mask (better quality around the edges than the clipped image when folded). Dali::Toolkit::Control mNameText; ///< The text shown when folded. Dali::Toolkit::Control mDetailText; ///< The text shown when unfolded. + Dali::Animation mAnimation; ///< The fold/unfold animation. + 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. const ContactCardLayoutInfo& mContactCardLayoutInfo; ///< Reference to the common data used by all contact cards. diff --git a/examples/contact-cards/contact-cards-example.cpp b/examples/contact-cards/contact-cards-example.cpp index d9c4d57..a0967a1 100644 --- a/examples/contact-cards/contact-cards-example.cpp +++ b/examples/contact-cards/contact-cards-example.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,14 @@ #include #include #include +#include // INTERNAL INCLUDES #include "contact-card-layouter.h" #include "contact-data.h" using namespace Dali; +using namespace Dali::Toolkit; namespace { @@ -51,6 +53,8 @@ const char * const THEME_PATH( DEMO_STYLE_DIR "contact-cards-example-theme.json" * This clipping comes in the form of a Circle or Quad. * The Vertex shader mixes in the Circle and Quad geometry depending on the value of a uniform float. * Animating this float between CIRCLE_GEOMETRY and QUAD_GEOMETRY is what enables the morphing between the two geometries. + * MaskedImage: This namespace provides a helper function which creates an ImageView with a mask that matches the Circle geometry provided by ClippedImage. + * 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. */ class ContactCardController : public ConnectionTracker // Inherit from ConnectionTracker so that our signals can be automatically disconnected upon our destruction. { @@ -100,9 +104,13 @@ private: { if( event.state == KeyEvent::Down ) { - if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) ) + KeyInputFocusManager keyInputFocusManager = KeyInputFocusManager::Get(); + if( ! keyInputFocusManager.GetCurrentFocusControl() ) // Don't quit if a control has focus { - mApplication.Quit(); + if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) ) + { + mApplication.Quit(); + } } } } diff --git a/examples/contact-cards/masked-image.cpp b/examples/contact-cards/masked-image.cpp new file mode 100644 index 0000000..abf7001 --- /dev/null +++ b/examples/contact-cards/masked-image.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// HEADER +#include "masked-image.h" + +// EXTERNAL INCLUDES +#include + +namespace MaskedImage +{ + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace +{ +const char* const IMAGE_MASK ( DEMO_IMAGE_DIR "contact-cards-mask.png" ); +} // unnamed namespace + +Dali::Toolkit::Control Create( const std::string& imagePath ) +{ + Control maskedImage = ImageView::New(); + maskedImage.SetProperty( + Toolkit::ImageView::Property::IMAGE, + Property::Map().Add( Visual::Property::TYPE, Toolkit::Visual::Type::IMAGE ) + .Add( ImageVisual::Property::URL, imagePath ) + .Add( ImageVisual::Property::ALPHA_MASK_URL, IMAGE_MASK ) + ); + return maskedImage; +} + +} // namespace ClippedImage diff --git a/examples/contact-cards/masked-image.h b/examples/contact-cards/masked-image.h new file mode 100644 index 0000000..9fefc84 --- /dev/null +++ b/examples/contact-cards/masked-image.h @@ -0,0 +1,44 @@ +#ifndef MASKED_IMAGE_H +#define MASKED_IMAGE_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include + +/** + * @brief This namespace provides a helper function which creates an ImageView with a mask that matches the Circle geometry provided by ClippedImage. + * + * Using a mask yields much better quality than when using an image with a circle geometry. + * @see ClippedImage + */ +namespace MaskedImage +{ + +/** + * @brief Creates an image with a circular mask. + * + * @param[in] imagePath The path to the image to show. + * @return The ImageView with a mask control. + */ +Dali::Toolkit::Control Create( const std::string& imagePath ); + +} // namespace ClippedImage + +#endif // MASKED_IMAGE_H diff --git a/examples/layouting/animation-example.cpp b/examples/layouting/animation-example.cpp new file mode 100644 index 0000000..8582ca5 --- /dev/null +++ b/examples/layouting/animation-example.cpp @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include "animation-example.h" +#include +#include +#include +#include +#include + +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace +{ +const char* const TITLE = "Animation Example"; + +// Button file names +const char* LTR_IMAGE( DEMO_IMAGE_DIR "icon-play.png" ); +const char* LTR_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-play-selected.png" ); + +const char* RTL_IMAGE( DEMO_IMAGE_DIR "icon-reverse.png" ); +const char* RTL_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-reverse-selected.png" ); + +const char* ROTATE_CLOCKWISE_IMAGE( DEMO_IMAGE_DIR "icon-reset.png" ); +const char* ROTATE_CLOCKWISE_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-reset-selected.png" ); + +const char* GRID_IMAGE( DEMO_IMAGE_DIR "icon-item-view-layout-grid.png" ); +const char* GRID_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-item-view-layout-grid-selected.png" ); + +// Child image filenames +const char* IMAGE_PATH[] = { + DEMO_IMAGE_DIR "application-icon-101.png", + DEMO_IMAGE_DIR "application-icon-102.png", + DEMO_IMAGE_DIR "application-icon-103.png", + DEMO_IMAGE_DIR "application-icon-104.png" +}; + +#if defined(DEBUG_ENABLED) +Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" ); +#endif + +const unsigned int NUMBER_OF_RESOURCES = sizeof(IMAGE_PATH) / sizeof(char*); + +// Helper function to create ImageViews with given filename and size. +void CreateChildImageView( ImageView& imageView, int index, Size size ) +{ + imageView = ImageView::New(); + Property::Map imagePropertyMap; + imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = IMAGE_PATH[ index ]; + imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = size.width; + imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = size.height; + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imagePropertyMap ); + std::string name = "ImageView"; + name.append( 1, '0' + index ); + imageView.SetName( name ); + imageView.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + imageView.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS ); +} + +LayoutTransitionData CreateOnSetLayoutTransition( Control& parent, std::vector< Toolkit::ImageView >& children ) +{ + auto layoutTransitionData = LayoutTransitionData::New(); + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::COLOR_ALPHA; + map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = 0.5f; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = 1.0f; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN_OUT" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.25f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); + + // Apply to parent only + layoutTransitionData.AddPropertyAnimator( parent, map ); + + for( size_t i = 0; i < children.size(); i++ ) + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f * 1.2f, 100.0f * 1.2f, 0 ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "SIN" ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.5f + 0.1f * i) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.25f ) ); + layoutTransitionData.AddPropertyAnimator( children[i], map ); + } + + return layoutTransitionData; +} + +LayoutTransitionData CreateOnChildAddTransition( Control& parent, ImageView& child ) +{ + auto layoutTransitionData = LayoutTransitionData::New(); + + // Want the parent to resize itself instantly so children will position themselves correctly when the parent is added to stage first time + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( parent, map ); + + // New child is growing + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; + map["initialValue"] = Vector3( 0.0f, 0.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f, 100.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); + layoutTransitionData.AddPropertyAnimator( child, map ); + } + + // Want new children instantly appear in their positions + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( child, map ); + } + + return layoutTransitionData; +} + +LayoutTransitionData CreateOnChildRemoveTransition(std::vector< Toolkit::ImageView >& images) +{ + auto layoutTransitionData = LayoutTransitionData::New(); + // Apply animation to remaining children + for (unsigned int i = 0; i < images.size(); i++) + { + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "position"; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "SIN") + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( images[i], map ); + } + } + + return layoutTransitionData; +} + +void CreateChildImageViewAndAdd( Control& container, int index, std::vector< Toolkit::ImageView >& images ) +{ + Toolkit::ImageView imageView; + CreateChildImageView( imageView, index, Size( 100.0f, 100.0f ) ); + auto layout = DevelControl::GetLayout( container ); + layout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, CreateOnChildAddTransition( container, imageView ) ); + + container.Add( imageView ); + images.push_back( imageView ); +} + +} // namespace + +namespace Demo +{ + +AnimationExample::AnimationExample() +: Example( TITLE ), + mGridSet( false ) +{ +} + +void AnimationExample::Create() +{ + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "AnimationExample::Create\n"); + auto stage = Stage::GetCurrent(); + + mRemoveButton = PushButton::New(); + mRemoveButton.SetProperty( PushButton::Property::UNSELECTED_ICON, RTL_IMAGE ); + mRemoveButton.SetProperty( PushButton::Property::SELECTED_ICON, RTL_SELECTED_IMAGE ); + mRemoveButton.ClickedSignal().Connect( this, &AnimationExample::OnRemoveClicked ); + mRemoveButton.SetParentOrigin( Vector3( 0.2f, 1.0f, 0.5f ) ); + mRemoveButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mRemoveButton.SetSize( 75, 75 ); + stage.Add( mRemoveButton ); + + mAddButton = PushButton::New(); + mAddButton.SetProperty( PushButton::Property::UNSELECTED_ICON, LTR_IMAGE ); + mAddButton.SetProperty( PushButton::Property::SELECTED_ICON, LTR_SELECTED_IMAGE ); + mAddButton.ClickedSignal().Connect( this, &AnimationExample::OnAddClicked ); + mAddButton.SetParentOrigin( Vector3( 0.4f, 1.0f, 0.5f ) ); + mAddButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mAddButton.SetSize( 75, 75 ); + stage.Add( mAddButton ); + + mSelectGridButton = Toolkit::PushButton::New(); + mSelectGridButton.SetProperty( PushButton::Property::UNSELECTED_ICON, GRID_IMAGE ); + mSelectGridButton.SetProperty( PushButton::Property::SELECTED_ICON, GRID_SELECTED_IMAGE ); + mSelectGridButton.ClickedSignal().Connect( this, &AnimationExample::OnSelectGridClicked ); + mSelectGridButton.SetParentOrigin( Vector3( 0.6f, 1.0f, 0.5f ) ); + mSelectGridButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mSelectGridButton.SetSize( 75, 75 ); + stage.Add( mSelectGridButton ); + + mShakeButton = PushButton::New(); + mShakeButton.SetProperty( PushButton::Property::UNSELECTED_ICON, ROTATE_CLOCKWISE_IMAGE ); + mShakeButton.SetProperty( PushButton::Property::SELECTED_ICON, ROTATE_CLOCKWISE_SELECTED_IMAGE ); + mShakeButton.ClickedSignal().Connect( this, &AnimationExample::OnChangeClicked ); + mShakeButton.SetParentOrigin( Vector3( 0.8f, 1.0f, 0.5f ) ); + mShakeButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER ); + mShakeButton.SetSize( 75, 75 ); + stage.Add( mShakeButton ); + + // Create a linear layout + mAnimationContainer = Control::New(); + mAnimationContainer.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + mAnimationContainer.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT ); + mAnimationContainer.SetProperty( Actor::Property::LAYOUT_DIRECTION, LayoutDirection::LEFT_TO_RIGHT ); + mAnimationContainer.SetParentOrigin( ParentOrigin::CENTER ); + mAnimationContainer.SetAnchorPoint( AnchorPoint::CENTER ); + mAnimationContainer.SetName( "AnimationExample" ); + mAnimationContainer.SetProperty( Toolkit::Control::Property::PADDING, Extents( 0.0f, 0.0f, 45.0f, 75.0f) ); + + mHorizontalLayout = LinearLayout::New(); + mHorizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + mHorizontalLayout.SetAlignment( LinearLayout::Alignment::CENTER_HORIZONTAL | LinearLayout::Alignment::CENTER_VERTICAL ); + mHorizontalLayout.SetAnimateLayout(true); + DevelControl::SetLayout( mAnimationContainer, mHorizontalLayout ); + + mGridLayout = Grid::New(); + mGridLayout.SetAnimateLayout(true); + mGridLayout.SetNumberOfColumns(2); + + CreateChildImageViewAndAdd( mAnimationContainer, 0, mImages ); + stage.Add( mAnimationContainer ); +} + +// Remove controls added by this example from stage +void AnimationExample::Remove() +{ + if ( mAnimationContainer ) + { + UnparentAndReset( mRemoveButton ); + UnparentAndReset( mAddButton ); + UnparentAndReset( mSelectGridButton ); + UnparentAndReset( mShakeButton ); + UnparentAndReset( mAnimationContainer); + mImages.clear(); + } +} + +bool AnimationExample::OnRemoveClicked( Button button ) +{ + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "AnimationExample::OnRemoveClicked\n"); + + if (mImages.size() > 1) + { + auto layout = DevelControl::GetLayout( mAnimationContainer ); + layout.SetTransitionData(LayoutTransitionData::ON_CHILD_REMOVE, CreateOnChildRemoveTransition( mImages ) ); + + ImageView imageView = mImages.back(); + mAnimationContainer.Remove( imageView ); + mImages.pop_back(); + } + return true; +} + +// Change layout by setting new layout, triggers set layout transition +bool AnimationExample::OnSelectGridClicked( Button button ) +{ + DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "AnimationExample::OnRotateClicked\n"); + + if ( !mGridSet ) + { + mGridLayout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, CreateOnSetLayoutTransition( mAnimationContainer, mImages ) ); + DevelControl::SetLayout( mAnimationContainer, mGridLayout ); + } + else + { + mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, CreateOnSetLayoutTransition( mAnimationContainer, mImages ) ); + DevelControl::SetLayout( mAnimationContainer, mHorizontalLayout ); + } + + mGridSet = !mGridSet; + return true; +} + +bool AnimationExample::OnAddClicked( Button button ) +{ + if (mImages.size() < 4) + { + CreateChildImageViewAndAdd( mAnimationContainer, mImages.size(), mImages ); + } + return true; +} + +bool AnimationExample::OnChangeClicked( Button button ) +{ + if ( !mGridSet ) + { + auto layout = LinearLayout::DownCast( DevelControl::GetLayout( mAnimationContainer ) ); + layout.SetAlignment( LinearLayout::Alignment::CENTER_HORIZONTAL | LinearLayout::Alignment::CENTER_VERTICAL ); + if ( layout.GetOrientation() == LinearLayout::Orientation::VERTICAL ) + { + layout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); + } + else + { + layout.SetOrientation( LinearLayout::Orientation::VERTICAL ); + } + } + else + { + auto layout = Grid::DownCast( DevelControl::GetLayout( mAnimationContainer ) ); + if ( layout.GetNumberOfColumns() == 2 ) + { + layout.SetNumberOfColumns(3); + } + else + { + layout.SetNumberOfColumns(2); + } + } + return true; +} + +} // namespace Demo diff --git a/examples/layouting/animation-example.h b/examples/layouting/animation-example.h new file mode 100644 index 0000000..e8ea61b --- /dev/null +++ b/examples/layouting/animation-example.h @@ -0,0 +1,73 @@ +#ifndef DALI_DEMO_ANIMATION_EXAMPLE_H +#define DALI_DEMO_ANIMATION_EXAMPLE_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include "example.h" + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace Demo +{ + +/** + * @file animation-example.hcpp + * @brief Example of a layout complex animation. + */ +class AnimationExample final: public ConnectionTracker, public Example +{ +public: + AnimationExample(); + + // Creates a Animation Layout Example and displays it. + virtual void Create() override; + + // Remove and destroy this layout + virtual void Remove() override; + +private: + + bool OnRemoveClicked( Button button ); + + bool OnSelectGridClicked( Button button ); + + bool OnAddClicked( Button button ); + + bool OnChangeClicked( Button button ); + +private: + PushButton mRemoveButton; + PushButton mAddButton; + PushButton mSelectGridButton; + PushButton mShakeButton; + std::vector< Toolkit::ImageView > mImages; + Control mAnimationContainer; + Grid mGridLayout; + LinearLayout mHorizontalLayout; + bool mGridSet; +}; // class AnimationContainer + +} // namespace Demo + +#endif //DALI_DEMO_ANIMATION_CONTAINER_H diff --git a/examples/layouting/layouting-examples.cpp b/examples/layouting/layouting-examples.cpp index fde22de..085dffc 100644 --- a/examples/layouting/layouting-examples.cpp +++ b/examples/layouting/layouting-examples.cpp @@ -24,6 +24,7 @@ // INTERNAL INCLUDES #include "shared/view.h" +#include "animation-example.h" #include "linear-example.h" #include "padding-example.h" #include "flex-example.h" @@ -47,6 +48,7 @@ typedef std::vector< ExamplePointer > ExampleContainer; /// All layouting examples to be shown should be added to this method void CreateExamples( ExampleContainer& container ) { + container.push_back( ExamplePointer(new Demo::AnimationExample) ); container.push_back( ExamplePointer(new Demo::LinearExample) ); container.push_back( ExamplePointer(new Demo::PaddingExample) ); container.push_back( ExamplePointer(new Demo::AbsoluteExample) ); diff --git a/packaging/com.samsung.dali-demo.spec b/packaging/com.samsung.dali-demo.spec index 61f5fdf..11143bd 100755 --- a/packaging/com.samsung.dali-demo.spec +++ b/packaging/com.samsung.dali-demo.spec @@ -2,7 +2,7 @@ Name: com.samsung.dali-demo Summary: The OpenGLES Canvas Core Demo -Version: 1.3.46 +Version: 1.3.47 Release: 1 Group: System/Libraries License: Apache-2.0 diff --git a/resources/images/contact-cards-mask.png b/resources/images/contact-cards-mask.png new file mode 100644 index 0000000..d2866c6 --- /dev/null +++ b/resources/images/contact-cards-mask.png