2 * Copyright (c) 2014 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 * This example shows how to use path animations in DALi
23 #include <dali-toolkit/dali-toolkit.h>
26 #include "shared/view.h"
29 using namespace Dali::Toolkit;
34 const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-default.png" );
35 const char* ACTOR_IMAGE( DALI_IMAGE_DIR "dali-logo.png" );
36 const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
37 const char* APPLICATION_TITLE( "Path Animation Example" );
38 }; //Unnamed namespace
41 * @brief The main class of the demo.
43 class PathController : public ConnectionTracker
47 PathController( Application& application )
48 : mApplication( application )
50 // Connect to the Application's Init signal
51 mApplication.InitSignal().Connect( this, &PathController::Create );
56 // Nothing to do here.
60 * Create a control composed of a label and an slider
61 * @param[in] label The text to be displayed ny the label
62 * @param[in] size The size of the slider
63 * @param[in] callback Pointer to the callback function to be called when user moves the slider
65 Actor CreateVectorComponentControl( const std::string& label, const Vector3& size, bool(PathController::*callback)(Slider,float) )
67 Dali::TextActor textActor = TextActor::New(label);
68 textActor.SetColor( Vector4(0.0f,0.0f,0.0f,1.0f));
69 textActor.SetSize(size.y,size.y,0.0f);
71 Slider slider = Slider::New();
72 slider.SetAnchorPoint( AnchorPoint::CENTER_LEFT);
73 slider.SetParentOrigin( ParentOrigin::CENTER_RIGHT);
74 slider.SetProperty(Slider::LOWER_BOUND_PROPERTY, -1.0f );
75 slider.SetProperty(Slider::UPPER_BOUND_PROPERTY, 1.0f );
77 Property::Array marks;
79 for(unsigned short i(0); i<21; ++i )
81 marks.push_back( mark );
85 slider.SetProperty(Slider::MARKS_PROPERTY, marks);
86 slider.SetProperty(Slider::SNAP_TO_MARKS_PROPERTY, true );
88 slider.SetScale( 0.5f );
89 slider.ValueChangedSignal().Connect(this,callback);
90 textActor.Add( slider );
95 * Crate all the GUI controls
99 Stage stage = Stage::GetCurrent();
102 Dali::Layer controlsLayer = Dali::Layer::New();
103 controlsLayer.SetSize( stage.GetSize().x, stage.GetSize().y*0.3f, 0.0 );
104 controlsLayer.SetPosition( 0.0f, stage.GetSize().y*0.8f, 0.0f );
105 controlsLayer.SetAnchorPoint( AnchorPoint::TOP_LEFT);
106 controlsLayer.SetParentOrigin( ParentOrigin::TOP_LEFT);
107 controlsLayer.TouchedSignal().Connect(this, &PathController::OnTouchGuiLayer);
108 stage.Add( controlsLayer );
110 Vector3 textInputSize( stage.GetSize().x, stage.GetSize().y*0.04f, 0.0f );
111 Actor control0 = CreateVectorComponentControl("x:", textInputSize, &PathController::OnSliderXValueChange );
112 control0.SetY( stage.GetSize().y*0.05f );
113 control0.SetAnchorPoint(AnchorPoint::TOP_LEFT);
114 controlsLayer.Add( control0 );
116 Actor control1 = CreateVectorComponentControl("y:", textInputSize, &PathController::OnSliderYValueChange );
117 control1.SetAnchorPoint(AnchorPoint::TOP_LEFT);
118 control1.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
119 control1.SetPosition(0.0f,stage.GetSize().y*0.01,0.0f);
120 control0.Add( control1 );
122 Actor control2 =CreateVectorComponentControl("z:", textInputSize, &PathController::OnSliderZValueChange );
123 control2.SetAnchorPoint(AnchorPoint::TOP_LEFT);
124 control2.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
125 control2.SetPosition(0.0f,stage.GetSize().y*0.01,0.0f);
126 control1.Add( control2 );
130 * Draws the path and the control points for the path
131 * @param[in] resolution Number of segments for the path.
133 void DrawPath( unsigned int resolution )
135 Stage stage = Dali::Stage::GetCurrent();
137 //Create path mesh actor
138 Dali::MeshData meshData = MeshFactory::NewPath( mPath, resolution );
139 Dali::Material material = Material::New("LineMaterial");
140 material.SetDiffuseColor( Vector4(0.0f,0.0f,0.0f,1.0f));
141 meshData.SetMaterial(material);
142 Dali::Mesh mesh = Dali::Mesh::New( meshData );
145 stage.Remove( mMeshPath );
147 mMeshPath = Dali::MeshActor::New( mesh );
148 mMeshPath.SetAnchorPoint( AnchorPoint::TOP_LEFT );
149 mMeshPath.SetParentOrigin( ParentOrigin::TOP_LEFT );
150 stage.Add( mMeshPath );
153 ////Create mesh connecting interpolation points and control points
154 std::vector<Dali::MeshData::Vertex> vVertex;
155 std::vector<unsigned short> vIndex;
156 size_t pointCount = mPath.GetPointCount();
157 size_t controlPointIndex = 0;
158 for( size_t i(0); i<pointCount; ++i )
160 vVertex.push_back( MeshData::Vertex(mPath.GetPoint(i),Vector2::ZERO, Vector3::ZERO ) );
163 vVertex.push_back( MeshData::Vertex(mPath.GetControlPoint(controlPointIndex),Vector2::ZERO, Vector3::ZERO ));
164 vVertex.push_back( MeshData::Vertex(mPath.GetControlPoint(controlPointIndex+1),Vector2::ZERO, Vector3::ZERO ));
166 controlPointIndex += 2;
169 size_t segmentCount = 2*(pointCount-2)+2;
170 unsigned short index=0;
171 for( size_t i(0); i<segmentCount; ++i, ++index )
173 vIndex.push_back(index);
174 vIndex.push_back(index+1);
182 meshData.SetLineData( vVertex, vIndex, material );
183 meshData.SetMaterial(material);
184 mesh = Dali::Mesh::New( meshData );
187 stage.Remove( mMeshHandlers );
189 mMeshHandlers = Dali::MeshActor::New( mesh );
190 mMeshHandlers.SetAnchorPoint( AnchorPoint::TOP_LEFT );
191 mMeshHandlers.SetParentOrigin( ParentOrigin::TOP_LEFT );
192 stage.Add( mMeshHandlers );
195 //Create actors representing interpolation points
197 for( size_t i(0); i<pointCount; ++i )
199 if( !mControlPoint[index] )
201 mControlPoint[index] = Toolkit::CreateSolidColorActor(Vector4(1.0f,1.0f,1.0f,1.0f));
202 mControlPoint[index].SetParentOrigin( ParentOrigin::TOP_LEFT);
203 mControlPoint[index].SetAnchorPoint( AnchorPoint::CENTER );
204 mControlPoint[index].SetSize( 20.0f, 20.0f );
205 mContentLayer.Add(mControlPoint[index]);
208 std::string name( "Knot");
210 mControlPoint[index].SetName( name );
211 mControlPoint[index].SetPosition( mPath.GetPoint(i) );
212 mControlPoint[index].SetColor( Vector4(0.0f,0.0f,0.0f,1.0f));
216 //Create actors representing control points
217 size_t controlPointCount=2*(pointCount-1);
218 for( size_t i(0); i<controlPointCount; ++i )
220 if( !mControlPoint[index])
222 mControlPoint[index] = Toolkit::CreateSolidColorActor(Vector4(1.0f,1.0f,1.0f,1.0f));
223 mControlPoint[index].SetParentOrigin( ParentOrigin::TOP_LEFT);
224 mControlPoint[index].SetAnchorPoint( AnchorPoint::CENTER );
225 mControlPoint[index].SetSize( 20.0f, 20.0f );
226 mContentLayer.Add(mControlPoint[index]);
228 std::string name( "ControlPoint");
230 mControlPoint[index].SetName( name );
231 mControlPoint[index].SetPosition( mPath.GetControlPoint(i) );
232 mControlPoint[index].SetColor( Vector4(1.0f,0.0f,0.0f,1.0f));
238 * Create the path animation.
240 void CreateAnimation()
244 mAnimation = Animation::New( 2.0f );
250 mActor.SetRotation( Quaternion() );
253 mAnimation.Animate( mActor, mPath, mForward );
254 mAnimation.SetLooping( true );
259 * Get closest control point.void
260 * @param[in] point Point from where the distance is computed
261 * @return The closest actor if the distance is beyond 0.5cm or an uninitialized actor otherwise
263 Actor GetClosestActor(const Vector3& point)
265 size_t pointCount = mPath.GetPointCount();
266 size_t controlPointCount = 3*pointCount - 2;
268 float minDistance = 1.0/0.0;
270 for( size_t i(0); i<controlPointCount; ++i )
272 Vector3 v = mControlPoint[i].GetCurrentPosition() - point;
273 float distance = v.LengthSquared();
274 if( distance < minDistance )
276 result = mControlPoint[i];
277 minDistance = distance;
281 Vector2 dpi = Dali::Stage::GetCurrent().GetDpi();
282 float distanceTreshold = 0.2f * dpi.x * 0.2f * dpi.x;
284 if( minDistance < distanceTreshold )
295 * Callback called when the background layer is touched
297 bool OnTouchLayer(Actor actor, const TouchEvent& event)
299 if(event.GetPointCount()>0)
301 const TouchPoint& point = event.GetPoint(0);
303 if(point.state==TouchPoint::Up)
308 else if(point.state==TouchPoint::Down)
310 Vector3 touchPoint = Vector3(event.GetPoint(0).screen.x, event.GetPoint(0).screen.y, 0.0f);
313 mDragActor = GetClosestActor( touchPoint );
314 if( !mDragActor && mPath.GetPointCount() < 10 )
317 Vector3 lastPoint = mPath.GetPoint( mPath.GetPointCount()-1);
318 mPath.AddPoint( touchPoint );
319 Vector3 displacement = (touchPoint-lastPoint)/8;
320 mPath.AddControlPoint( lastPoint + displacement );
321 mPath.AddControlPoint( touchPoint - displacement);
328 else if( mDragActor && point.state==TouchPoint::Motion )
330 Vector3 touchPoint = Vector3(event.GetPoint(0).screen.x, event.GetPoint(0).screen.y, 0.0f);
331 std::string actorName(mDragActor.GetName());
332 if( actorName.compare(0, 4, "Knot") == 0)
334 int index = actorName[4];
335 mPath.GetPoint(index) = touchPoint;
339 int index = actorName[12];
340 mPath.GetControlPoint(index) = touchPoint;
351 bool OnTouchGuiLayer(Actor actor, const TouchEvent& event)
357 * Callback called when user changes slider X
358 * @param[in] slider The slider that has generated the signal
359 * @param[in] value The new value
361 bool OnSliderXValueChange( Slider s, float value)
363 if( fabs( value ) - Math::MACHINE_EPSILON_1000 < 0.0f )
377 * Callback called when user changes slider Y
378 * @param[in] slider The slider that has generated the signal
379 * @param[in] value The new value
381 bool OnSliderYValueChange( Slider s, float value)
383 if( fabs( value ) - Math::MACHINE_EPSILON_1000 < 0.0f )
396 * Callback called when user changes slider Z
397 * @param[in] slider The slider that has generated the signal
398 * @param[in] value The new value
400 bool OnSliderZValueChange( Slider s, float value)
402 if( fabs( value ) - Math::MACHINE_EPSILON_1000 < 0.0f )
416 * Main key event handler.
417 * Quit on escape key.
419 void OnKeyEvent(const KeyEvent& event)
421 if( event.state == KeyEvent::Down )
423 if( IsKey( event, Dali::DALI_KEY_ESCAPE ) ||
424 IsKey( event, Dali::DALI_KEY_BACK ) )
432 * One-time setup in response to Application InitSignal.
434 void Create( Application& application )
436 // Get a handle to the stage:
437 Stage stage = Stage::GetCurrent();
439 // Connect to input event signals:
440 stage.KeyEventSignal().Connect(this, &PathController::OnKeyEvent);
442 // Create a default view with a default tool bar:
443 Toolkit::View view; ///< The View instance.
444 Toolkit::ToolBar toolBar; ///< The View's Toolbar.
445 mContentLayer = DemoHelper::CreateView( mApplication,
452 mContentLayer.TouchedSignal().Connect(this, &PathController::OnTouchLayer);
455 TextView title = TextView::New();
456 toolBar.AddControl( title, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Alignment::HorizontalCenter );
457 Font font = Font::New();
458 title.SetText( APPLICATION_TITLE );
459 title.SetSize( font.MeasureText( APPLICATION_TITLE ) );
460 title.SetStyleToCurrentText(DemoHelper::GetDefaultTextStyle());
463 mPath = Dali::Path::New();
464 mPath.AddPoint( Vector3( 10.0f, stage.GetSize().y*0.5f, 0.0f ));
465 mPath.AddPoint( Vector3( stage.GetSize().x*0.5f, stage.GetSize().y*0.5f, 0.0f ));
466 mPath.GenerateControlPoints(0.25f);
470 ImageAttributes attributes;
471 Image img = ResourceImage::New(ACTOR_IMAGE, attributes );
472 mActor = ImageActor::New( img );
473 mActor.SetAnchorPoint( AnchorPoint::CENTER );
474 mActor.SetSize( 100, 50, 1 );
482 Application& mApplication;
484 Layer mContentLayer; ///< The content layer
486 Path mPath; ///< The path used in the animation
487 ImageActor mActor; ///< Actor being animated
488 Vector3 mForward; ///< Current forward vector
489 Animation mAnimation; ///< Path animation
491 MeshActor mMeshPath; ///< Mesh actor for the path
492 MeshActor mMeshHandlers; ///< Mesh actor for the handlers of the path
494 Actor mControlPoint[28]; ///< ImageActors represeting control points of the path
496 Actor mDragActor; ///< Reference to the actor currently being dragged
500 void RunTest( Application& application )
502 PathController test( application );
504 application.MainLoop();
507 /** Entry point for Linux & Tizen applications */
508 int main( int argc, char **argv )
510 Application application = Application::New( &argc, &argv );
512 RunTest( application );