2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "animation-example.h"
20 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
21 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
22 #include <dali-toolkit/devel-api/controls/control-devel.h>
23 #include <dali-toolkit/devel-api/layouting/linear-layout.h>
24 #include <dali-toolkit/devel-api/layouting/grid.h>
26 #include <dali/integration-api/debug.h>
29 using namespace Dali::Toolkit;
33 const char* const TITLE = "Animation Example";
36 const char* LTR_IMAGE( DEMO_IMAGE_DIR "icon-play.png" );
37 const char* LTR_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-play-selected.png" );
39 const char* RTL_IMAGE( DEMO_IMAGE_DIR "icon-reverse.png" );
40 const char* RTL_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-reverse-selected.png" );
42 const char* ROTATE_CLOCKWISE_IMAGE( DEMO_IMAGE_DIR "icon-reset.png" );
43 const char* ROTATE_CLOCKWISE_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-reset-selected.png" );
45 const char* GRID_IMAGE( DEMO_IMAGE_DIR "icon-item-view-layout-grid.png" );
46 const char* GRID_SELECTED_IMAGE( DEMO_IMAGE_DIR "icon-item-view-layout-grid-selected.png" );
48 // Child image filenames
49 const char* IMAGE_PATH[] = {
50 DEMO_IMAGE_DIR "application-icon-101.png",
51 DEMO_IMAGE_DIR "application-icon-102.png",
52 DEMO_IMAGE_DIR "application-icon-103.png",
53 DEMO_IMAGE_DIR "application-icon-104.png"
56 #if defined(DEBUG_ENABLED)
57 Debug::Filter* gLayoutFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" );
60 const unsigned int NUMBER_OF_RESOURCES = sizeof(IMAGE_PATH) / sizeof(char*);
62 // Helper function to create ImageViews with given filename and size.
63 void CreateChildImageView( ImageView& imageView, int index, Size size )
65 imageView = ImageView::New();
66 Property::Map imagePropertyMap;
67 imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE;
68 imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = IMAGE_PATH[ index ];
69 imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = size.width;
70 imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = size.height;
71 imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imagePropertyMap );
72 std::string name = "ImageView";
73 name.append( 1, '0' + index );
74 imageView.SetName( name );
75 imageView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
76 imageView.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
79 LayoutTransitionData CreateOnSetLayoutTransition( Control& parent, std::vector< Toolkit::ImageView >& children )
81 auto layoutTransitionData = LayoutTransitionData::New();
83 map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::COLOR_ALPHA;
84 map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = 0.5f;
85 map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = 1.0f;
86 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
87 .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "EASE_IN_OUT" )
88 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
89 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.25f )
90 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
92 // Apply to parent only
93 layoutTransitionData.AddPropertyAnimator( parent, map );
95 for( size_t i = 0; i < children.size(); i++ )
98 map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
99 map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f * 1.2f, 100.0f * 1.2f, 0 );
100 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
101 .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "SIN" )
102 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
103 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.5f + 0.1f * i)
104 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.25f ) );
105 layoutTransitionData.AddPropertyAnimator( children[i], map );
108 return layoutTransitionData;
111 LayoutTransitionData CreateOnChildAddTransition( Control& parent, ImageView& child )
113 auto layoutTransitionData = LayoutTransitionData::New();
115 // Want the parent to resize itself instantly so children will position themselves correctly when the parent is added to stage first time
117 map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
118 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
119 .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
120 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
121 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
122 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
123 layoutTransitionData.AddPropertyAnimator( parent, map );
125 // New child is growing
128 map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE;
129 map["initialValue"] = Vector3( 0.0f, 0.0f, 0 );
130 map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f, 100.0f, 0 );
131 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
132 .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
133 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
134 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
135 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) );
136 layoutTransitionData.AddPropertyAnimator( child, map );
139 // Want new children instantly appear in their positions
142 map[ LayoutTransitionData::AnimatorKey::PROPERTY] = Actor::Property::POSITION;
143 map[ LayoutTransitionData::AnimatorKey::ANIMATOR] = Property::Map()
144 .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "LINEAR")
145 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
146 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f )
147 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) );
148 layoutTransitionData.AddPropertyAnimator( child, map );
151 return layoutTransitionData;
154 LayoutTransitionData CreateOnChildRemoveTransition(std::vector< Toolkit::ImageView >& images)
156 auto layoutTransitionData = LayoutTransitionData::New();
157 // Apply animation to remaining children
158 for (unsigned int i = 0; i < images.size(); i++)
162 map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = "position";
163 map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map()
164 .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, "SIN")
165 .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map()
166 .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f)
167 .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f));
168 layoutTransitionData.AddPropertyAnimator( images[i], map );
172 return layoutTransitionData;
175 void CreateChildImageViewAndAdd( Control& container, int index, std::vector< Toolkit::ImageView >& images )
177 Toolkit::ImageView imageView;
178 CreateChildImageView( imageView, index, Size( 100.0f, 100.0f ) );
179 auto layout = DevelControl::GetLayout( container );
180 layout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, CreateOnChildAddTransition( container, imageView ) );
182 container.Add( imageView );
183 images.push_back( imageView );
191 AnimationExample::AnimationExample()
197 void AnimationExample::Create()
199 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "AnimationExample::Create\n");
200 auto stage = Stage::GetCurrent();
202 mRemoveButton = PushButton::New();
203 mRemoveButton.SetProperty( PushButton::Property::UNSELECTED_ICON, RTL_IMAGE );
204 mRemoveButton.SetProperty( PushButton::Property::SELECTED_ICON, RTL_SELECTED_IMAGE );
205 mRemoveButton.ClickedSignal().Connect( this, &AnimationExample::OnRemoveClicked );
206 mRemoveButton.SetParentOrigin( Vector3( 0.2f, 1.0f, 0.5f ) );
207 mRemoveButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
208 mRemoveButton.SetSize( 75, 75 );
209 stage.Add( mRemoveButton );
211 mAddButton = PushButton::New();
212 mAddButton.SetProperty( PushButton::Property::UNSELECTED_ICON, LTR_IMAGE );
213 mAddButton.SetProperty( PushButton::Property::SELECTED_ICON, LTR_SELECTED_IMAGE );
214 mAddButton.ClickedSignal().Connect( this, &AnimationExample::OnAddClicked );
215 mAddButton.SetParentOrigin( Vector3( 0.4f, 1.0f, 0.5f ) );
216 mAddButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
217 mAddButton.SetSize( 75, 75 );
218 stage.Add( mAddButton );
220 mSelectGridButton = Toolkit::PushButton::New();
221 mSelectGridButton.SetProperty( PushButton::Property::UNSELECTED_ICON, GRID_IMAGE );
222 mSelectGridButton.SetProperty( PushButton::Property::SELECTED_ICON, GRID_SELECTED_IMAGE );
223 mSelectGridButton.ClickedSignal().Connect( this, &AnimationExample::OnSelectGridClicked );
224 mSelectGridButton.SetParentOrigin( Vector3( 0.6f, 1.0f, 0.5f ) );
225 mSelectGridButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
226 mSelectGridButton.SetSize( 75, 75 );
227 stage.Add( mSelectGridButton );
229 mShakeButton = PushButton::New();
230 mShakeButton.SetProperty( PushButton::Property::UNSELECTED_ICON, ROTATE_CLOCKWISE_IMAGE );
231 mShakeButton.SetProperty( PushButton::Property::SELECTED_ICON, ROTATE_CLOCKWISE_SELECTED_IMAGE );
232 mShakeButton.ClickedSignal().Connect( this, &AnimationExample::OnChangeClicked );
233 mShakeButton.SetParentOrigin( Vector3( 0.8f, 1.0f, 0.5f ) );
234 mShakeButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
235 mShakeButton.SetSize( 75, 75 );
236 stage.Add( mShakeButton );
238 // Create a linear layout
239 mAnimationContainer = Control::New();
240 mAnimationContainer.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
241 mAnimationContainer.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
242 mAnimationContainer.SetProperty( Actor::Property::LAYOUT_DIRECTION, LayoutDirection::LEFT_TO_RIGHT );
243 mAnimationContainer.SetParentOrigin( ParentOrigin::CENTER );
244 mAnimationContainer.SetAnchorPoint( AnchorPoint::CENTER );
245 mAnimationContainer.SetName( "AnimationExample" );
246 mAnimationContainer.SetProperty( Toolkit::Control::Property::PADDING, Extents( 0.0f, 0.0f, 45.0f, 75.0f) );
248 mHorizontalLayout = LinearLayout::New();
249 mHorizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
250 mHorizontalLayout.SetAlignment( LinearLayout::Alignment::CENTER_HORIZONTAL | LinearLayout::Alignment::CENTER_VERTICAL );
251 mHorizontalLayout.SetAnimateLayout(true);
252 DevelControl::SetLayout( mAnimationContainer, mHorizontalLayout );
254 mGridLayout = Grid::New();
255 mGridLayout.SetAnimateLayout(true);
256 mGridLayout.SetNumberOfColumns(2);
258 CreateChildImageViewAndAdd( mAnimationContainer, 0, mImages );
259 stage.Add( mAnimationContainer );
262 // Remove controls added by this example from stage
263 void AnimationExample::Remove()
265 if ( mAnimationContainer )
267 UnparentAndReset( mRemoveButton );
268 UnparentAndReset( mAddButton );
269 UnparentAndReset( mSelectGridButton );
270 UnparentAndReset( mShakeButton );
271 UnparentAndReset( mAnimationContainer);
276 bool AnimationExample::OnRemoveClicked( Button button )
278 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "AnimationExample::OnRemoveClicked\n");
280 if (mImages.size() > 1)
282 auto layout = DevelControl::GetLayout( mAnimationContainer );
283 layout.SetTransitionData(LayoutTransitionData::ON_CHILD_REMOVE, CreateOnChildRemoveTransition( mImages ) );
285 ImageView imageView = mImages.back();
286 mAnimationContainer.Remove( imageView );
292 // Change layout by setting new layout, triggers set layout transition
293 bool AnimationExample::OnSelectGridClicked( Button button )
295 DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "AnimationExample::OnRotateClicked\n");
299 mGridLayout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, CreateOnSetLayoutTransition( mAnimationContainer, mImages ) );
300 DevelControl::SetLayout( mAnimationContainer, mGridLayout );
304 mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_OWNER_SET, CreateOnSetLayoutTransition( mAnimationContainer, mImages ) );
305 DevelControl::SetLayout( mAnimationContainer, mHorizontalLayout );
308 mGridSet = !mGridSet;
312 bool AnimationExample::OnAddClicked( Button button )
314 if (mImages.size() < 4)
316 CreateChildImageViewAndAdd( mAnimationContainer, mImages.size(), mImages );
321 bool AnimationExample::OnChangeClicked( Button button )
325 auto layout = LinearLayout::DownCast( DevelControl::GetLayout( mAnimationContainer ) );
326 layout.SetAlignment( LinearLayout::Alignment::CENTER_HORIZONTAL | LinearLayout::Alignment::CENTER_VERTICAL );
327 if ( layout.GetOrientation() == LinearLayout::Orientation::VERTICAL )
329 layout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
333 layout.SetOrientation( LinearLayout::Orientation::VERTICAL );
338 auto layout = Grid::DownCast( DevelControl::GetLayout( mAnimationContainer ) );
339 if ( layout.GetNumberOfColumns() == 2 )
341 layout.SetNumberOfColumns(3);
345 layout.SetNumberOfColumns(2);