Commit b2c5f02685b93169c34b127a3b2c7cd1a19bb373
Committed by
Gerrit Code Review
Merge "Path animation enhancement for easier control" into tizen
Showing
1 changed file
with
288 additions
and
237 deletions
examples/path-animation/path-animation.cpp
| @@ -34,7 +34,7 @@ namespace | @@ -34,7 +34,7 @@ namespace | ||
| 34 | const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-default.png" ); | 34 | const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-default.png" ); |
| 35 | const char* ACTOR_IMAGE( DALI_IMAGE_DIR "dali-logo.png" ); | 35 | const char* ACTOR_IMAGE( DALI_IMAGE_DIR "dali-logo.png" ); |
| 36 | const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" ); | 36 | const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" ); |
| 37 | -const char* APPLICATION_TITLE( "Path Example" ); | 37 | +const char* APPLICATION_TITLE( "Path Animation Example" ); |
| 38 | }; //Unnamed namespace | 38 | }; //Unnamed namespace |
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| @@ -45,169 +45,85 @@ class PathController : public ConnectionTracker | @@ -45,169 +45,85 @@ class PathController : public ConnectionTracker | ||
| 45 | public: | 45 | public: |
| 46 | 46 | ||
| 47 | PathController( Application& application ) | 47 | PathController( Application& application ) |
| 48 | - : mApplication( application ) | ||
| 49 | - { | 48 | +: mApplication( application ) |
| 49 | +{ | ||
| 50 | // Connect to the Application's Init signal | 50 | // Connect to the Application's Init signal |
| 51 | mApplication.InitSignal().Connect( this, &PathController::Create ); | 51 | mApplication.InitSignal().Connect( this, &PathController::Create ); |
| 52 | - } | 52 | +} |
| 53 | 53 | ||
| 54 | ~PathController() | 54 | ~PathController() |
| 55 | { | 55 | { |
| 56 | // Nothing to do here. | 56 | // Nothing to do here. |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | - /** | ||
| 60 | - * One-time setup in response to Application InitSignal. | ||
| 61 | - */ | ||
| 62 | - void Create( Application& application ) | 59 | + /* |
| 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 | ||
| 64 | + */ | ||
| 65 | + Actor CreateVectorComponentControl( const std::string& label, const Vector3& size, bool(PathController::*callback)(Slider,float) ) | ||
| 63 | { | 66 | { |
| 64 | - // Get a handle to the stage: | ||
| 65 | - Stage stage = Stage::GetCurrent(); | ||
| 66 | - | ||
| 67 | - // Connect to input event signals: | ||
| 68 | - stage.KeyEventSignal().Connect(this, &PathController::OnKeyEvent); | ||
| 69 | - | ||
| 70 | - // Create a default view with a default tool bar: | ||
| 71 | - Toolkit::View view; ///< The View instance. | ||
| 72 | - Toolkit::ToolBar toolBar; ///< The View's Toolbar. | ||
| 73 | - mContentLayer = DemoHelper::CreateView( mApplication, | ||
| 74 | - view, | ||
| 75 | - toolBar, | ||
| 76 | - BACKGROUND_IMAGE, | ||
| 77 | - TOOLBAR_IMAGE, | ||
| 78 | - "" ); | ||
| 79 | - | ||
| 80 | - mContentLayer.TouchedSignal().Connect(this, &PathController::OnTouchLayer); | ||
| 81 | - | ||
| 82 | - //Title | ||
| 83 | - TextView title = TextView::New(); | ||
| 84 | - toolBar.AddControl( title, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Alignment::HorizontalCenter ); | ||
| 85 | - Font font = Font::New(); | ||
| 86 | - title.SetText( APPLICATION_TITLE ); | ||
| 87 | - title.SetSize( font.MeasureText( APPLICATION_TITLE ) ); | ||
| 88 | - title.SetStyleToCurrentText(DemoHelper::GetDefaultTextStyle()); | ||
| 89 | - | ||
| 90 | - //Path | ||
| 91 | - mPath = Dali::Path::New(); | ||
| 92 | - mPath.AddPoint( Vector3( 10.0f, stage.GetSize().y*0.5f, 0.0f )); | ||
| 93 | - mPath.AddPoint( Vector3( stage.GetSize().x*0.5f, stage.GetSize().y*0.3f, 0.0f )); | ||
| 94 | - mPath.GenerateControlPoints(0.25f); | ||
| 95 | - DrawPath( 200u ); | ||
| 96 | - | ||
| 97 | - //Actor | ||
| 98 | - ImageAttributes attributes; | ||
| 99 | - Image img = ResourceImage::New(ACTOR_IMAGE, attributes ); | ||
| 100 | - mActor = ImageActor::New( img ); | ||
| 101 | - mActor.SetPosition( Vector3( 10.0f, stage.GetSize().y*0.5f, 0.0f ) ); | ||
| 102 | - mActor.SetAnchorPoint( AnchorPoint::CENTER ); | ||
| 103 | - mActor.SetSize( 100, 50, 1 ); | ||
| 104 | - stage.Add( mActor ); | ||
| 105 | - | ||
| 106 | - mForward = Vector3::XAXIS; | ||
| 107 | - CreateAnimation(); | ||
| 108 | - | ||
| 109 | - Dali::TextActor forwardLabel = TextActor::New("Forward Vector"); | ||
| 110 | - forwardLabel.SetPosition( 10.0f, stage.GetSize().y - 60.0f, 0.0f ); | ||
| 111 | - forwardLabel.SetColor( Vector4(0.0f,0.0f,0.0f,1.0f)); | ||
| 112 | - forwardLabel.SetAnchorPoint( AnchorPoint::CENTER_LEFT); | ||
| 113 | - mContentLayer.Add( forwardLabel ); | 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); | ||
| 70 | + | ||
| 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 ); | ||
| 76 | + | ||
| 77 | + Property::Array marks; | ||
| 78 | + float mark = -1.0f; | ||
| 79 | + for(unsigned short i(0); i<21; ++i ) | ||
| 80 | + { | ||
| 81 | + marks.push_back( mark ); | ||
| 82 | + mark += 0.1f; | ||
| 83 | + } | ||
| 114 | 84 | ||
| 115 | - //TextInput | ||
| 116 | - Dali::Layer textInputLayer = Dali::Layer::New(); | ||
| 117 | - textInputLayer.SetSize( 400.0f, 30.0f, 0.0 ); | ||
| 118 | - textInputLayer.SetPosition( 0.0f, stage.GetSize().y - 30.0f, 0.0f ); | ||
| 119 | - textInputLayer.SetAnchorPoint( AnchorPoint::TOP_LEFT); | ||
| 120 | - textInputLayer.SetParentOrigin( ParentOrigin::TOP_LEFT); | ||
| 121 | - stage.Add( textInputLayer ); | ||
| 122 | - Dali::TextActor label = TextActor::New("X:"); | ||
| 123 | - label.SetPosition( 10.0f, 0.0f, 0.0f ); | ||
| 124 | - label.SetColor( Vector4(0.0f,0.0f,0.0f,1.0f)); | ||
| 125 | - label.SetAnchorPoint( AnchorPoint::CENTER_LEFT); | ||
| 126 | - textInputLayer.Add( label ); | ||
| 127 | - TextStyle style; | ||
| 128 | - style.SetTextColor( Vector4( 0.0f, 0.0f ,0.0f, 1.0f )); | ||
| 129 | - mTextInput[0] = TextInput::New(); | ||
| 130 | - mTextInput[0].SetInitialText("1.0"); | ||
| 131 | - mTextInput[0].SetColor( Vector4(0.0f,0.0f,0.0f,1.0f)); | ||
| 132 | - mTextInput[0].SetAnchorPoint( AnchorPoint::CENTER_LEFT); | ||
| 133 | - mTextInput[0].SetParentOrigin( ParentOrigin::CENTER_RIGHT); | ||
| 134 | - mTextInput[0].SetPosition( 10.0f, 0.0f, 0.0f ); | ||
| 135 | - mTextInput[0].SetSize( 70.0f, 0.0f, 0.0f ); | ||
| 136 | - mTextInput[0].SetTextAlignment(Alignment::HorizontalCenter ); | ||
| 137 | - mTextInput[0].SetMaxCharacterLength( 5 ); | ||
| 138 | - mTextInput[0].SetNumberOfLinesLimit(1); | ||
| 139 | - mTextInput[0].ApplyStyleToAll( style ); | ||
| 140 | - mTextInput[0].SetProperty( mTextInput[0].GetPropertyIndex("cursor-color"), Vector4(0.0f,0.0f,0.0f,1.0f) ); | ||
| 141 | - mTextInput[0].SetBackgroundColor( Vector4(0.8f,1.0f,0.8f, 0.4f)); | ||
| 142 | - mTextInput[0].InputFinishedSignal().Connect(this, &PathController::OnTextInputEnd); | ||
| 143 | - mTextInput[0].SetEditOnTouch(); | ||
| 144 | - label.Add( mTextInput[0]); | ||
| 145 | - label = TextActor::New("Y:"); | ||
| 146 | - label.SetPosition( 160.0f,0.0f, 0.0f ); | ||
| 147 | - label.SetColor( Vector4(0.0f,0.0f,0.0f,1.0f)); | ||
| 148 | - label.SetAnchorPoint( AnchorPoint::CENTER_LEFT); | ||
| 149 | - textInputLayer.Add( label ); | ||
| 150 | - mTextInput[1] = TextInput::New(); | ||
| 151 | - mTextInput[1].SetInitialText("0.0"); | ||
| 152 | - mTextInput[1].SetColor( Vector4(0.0f,0.0f,0.0f,1.0f)); | ||
| 153 | - mTextInput[1].SetAnchorPoint( AnchorPoint::CENTER_LEFT); | ||
| 154 | - mTextInput[1].SetParentOrigin( ParentOrigin::CENTER_RIGHT); | ||
| 155 | - mTextInput[1].SetPosition( 10.0f, 0.0f, 0.0f ); | ||
| 156 | - mTextInput[1].SetSize( 70.0f, 0.0f, 0.0f ); | ||
| 157 | - mTextInput[1].SetTextAlignment(Alignment::HorizontalCenter ); | ||
| 158 | - mTextInput[1].SetMaxCharacterLength( 5 ); | ||
| 159 | - mTextInput[1].SetNumberOfLinesLimit(1); | ||
| 160 | - mTextInput[1].ApplyStyleToAll( style ); | ||
| 161 | - mTextInput[1].SetProperty( mTextInput[1].GetPropertyIndex("cursor-color"), Vector4(0.0f,0.0f,0.0f,1.0f) ); | ||
| 162 | - mTextInput[1].SetBackgroundColor( Vector4(0.8f,1.0f,0.8f, 0.4f)); | ||
| 163 | - mTextInput[1].InputFinishedSignal().Connect(this, &PathController::OnTextInputEnd); | ||
| 164 | - label.Add( mTextInput[1]); | ||
| 165 | - label = TextActor::New("Z:"); | ||
| 166 | - label.SetPosition( 310.0f, 0.0f, 0.0f ); | ||
| 167 | - label.SetColor( Vector4(0.0f,0.0f,0.0f,1.0f)); | ||
| 168 | - label.SetAnchorPoint( AnchorPoint::CENTER_LEFT); | ||
| 169 | - textInputLayer.Add( label ); | ||
| 170 | - mTextInput[2] = TextInput::New(); | ||
| 171 | - mTextInput[2].SetInitialText("0.0"); | ||
| 172 | - mTextInput[2].SetColor( Vector4(0.0f,0.0f,0.0f,1.0f)); | ||
| 173 | - mTextInput[2].SetAnchorPoint( AnchorPoint::CENTER_LEFT); | ||
| 174 | - mTextInput[2].SetParentOrigin( ParentOrigin::CENTER_RIGHT); | ||
| 175 | - mTextInput[2].SetPosition( 10.0f, 0.0f, 0.0f ); | ||
| 176 | - mTextInput[2].SetSize( 70.0f, 0.0f, 0.0f ); | ||
| 177 | - mTextInput[2].SetTextAlignment(Alignment::HorizontalCenter ); | ||
| 178 | - mTextInput[2].SetMaxCharacterLength( 5 ); | ||
| 179 | - mTextInput[2].SetNumberOfLinesLimit(1); | ||
| 180 | - mTextInput[2].ApplyStyleToAll( style ); | ||
| 181 | - mTextInput[2].SetProperty( mTextInput[2].GetPropertyIndex("cursor-color"), Vector4(0.0f,0.0f,0.0f,1.0f) ); | ||
| 182 | - mTextInput[2].SetBackgroundColor( Vector4(0.8f,1.0f,0.8f, 0.4f)); | ||
| 183 | - mTextInput[2].InputFinishedSignal().Connect(this, &PathController::OnTextInputEnd); | ||
| 184 | - label.Add( mTextInput[2]); | 85 | + slider.SetProperty(Slider::MARKS_PROPERTY, marks); |
| 86 | + slider.SetProperty(Slider::SNAP_TO_MARKS_PROPERTY, true ); | ||
| 87 | + slider.SetSize(size); | ||
| 88 | + slider.SetScale( 0.5f ); | ||
| 89 | + slider.ValueChangedSignal().Connect(this,callback); | ||
| 90 | + textActor.Add( slider ); | ||
| 91 | + return textActor; | ||
| 185 | } | 92 | } |
| 186 | 93 | ||
| 187 | /** | 94 | /** |
| 188 | - * Create an actor representing a control point of the curve | ||
| 189 | - * @param[in] name Name of the actor | ||
| 190 | - * @param[in] size Size of the containing actor | ||
| 191 | - * @param[in] imageSize Size of the imageActor | ||
| 192 | - * @param[in] color Color of the imageActor | 95 | + * Crate all the GUI controls |
| 193 | */ | 96 | */ |
| 194 | - Actor CreateControlPoint(const std::string& name, const Vector3& size, const Vector3& imageSize, const Vector4& color ) | 97 | + void CreateControls() |
| 195 | { | 98 | { |
| 196 | - Actor actor = Actor::New(); | ||
| 197 | - actor.SetParentOrigin( ParentOrigin::TOP_LEFT); | ||
| 198 | - actor.SetAnchorPoint( AnchorPoint::CENTER ); | ||
| 199 | - actor.SetSize( size ); | ||
| 200 | - actor.SetName( name ); | ||
| 201 | - actor.TouchedSignal().Connect(this, &PathController::OnTouchPoint); | ||
| 202 | - | ||
| 203 | - ImageActor imageActor = Toolkit::CreateSolidColorActor(color); | ||
| 204 | - imageActor.SetColor(Vector4(1.0f,0.0f,0.0f,1.0f)); | ||
| 205 | - imageActor.SetParentOrigin( ParentOrigin::CENTER); | ||
| 206 | - imageActor.SetAnchorPoint( AnchorPoint::CENTER ); | ||
| 207 | - imageActor.SetSize( imageSize ); | ||
| 208 | - actor.Add(imageActor ); | ||
| 209 | - | ||
| 210 | - return actor; | 99 | + Stage stage = Stage::GetCurrent(); |
| 100 | + | ||
| 101 | + //TextInput | ||
| 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 ); | ||
| 109 | + | ||
| 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 ); | ||
| 115 | + | ||
| 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 ); | ||
| 121 | + | ||
| 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 ); | ||
| 211 | } | 127 | } |
| 212 | 128 | ||
| 213 | /** | 129 | /** |
| @@ -277,50 +193,107 @@ public: | @@ -277,50 +193,107 @@ public: | ||
| 277 | 193 | ||
| 278 | 194 | ||
| 279 | //Create actors representing interpolation points | 195 | //Create actors representing interpolation points |
| 196 | + index = 0; | ||
| 280 | for( size_t i(0); i<pointCount; ++i ) | 197 | for( size_t i(0); i<pointCount; ++i ) |
| 281 | { | 198 | { |
| 282 | - if( !mKnot[i] ) | 199 | + if( !mControlPoint[index] ) |
| 283 | { | 200 | { |
| 284 | - std::string name( "Knot"); | ||
| 285 | - name.push_back(i); | ||
| 286 | - mKnot[i] = CreateControlPoint( name, Vector3(150.0f,150.0f,0.0f), Vector3(20.0f,20.0f,0.0f), Vector4(0.0f,0.0f,0.0f,1.0f) ); | ||
| 287 | - mContentLayer.Add(mKnot[i] ); | 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]); | ||
| 288 | } | 206 | } |
| 289 | 207 | ||
| 290 | - mKnot[i].SetPosition( mPath.GetPoint(i) ); | 208 | + std::string name( "Knot"); |
| 209 | + name.push_back(i); | ||
| 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)); | ||
| 213 | + ++index; | ||
| 291 | } | 214 | } |
| 292 | 215 | ||
| 293 | //Create actors representing control points | 216 | //Create actors representing control points |
| 294 | size_t controlPointCount=2*(pointCount-1); | 217 | size_t controlPointCount=2*(pointCount-1); |
| 295 | for( size_t i(0); i<controlPointCount; ++i ) | 218 | for( size_t i(0); i<controlPointCount; ++i ) |
| 296 | { | 219 | { |
| 297 | - if( !mControlPoint[i]) | 220 | + if( !mControlPoint[index]) |
| 298 | { | 221 | { |
| 299 | - std::string name( "ControlPoint"); | ||
| 300 | - name.push_back(i); | ||
| 301 | - mControlPoint[i] = CreateControlPoint( name, Vector3(150.0f,150.0f,0.0f), Vector3(20.0f,20.0f,0.0f), Vector4(1.0f,0.0f,0.0f,1.0f) ); | ||
| 302 | - mContentLayer.Add(mControlPoint[i] ); | 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]); | ||
| 303 | } | 227 | } |
| 304 | - | ||
| 305 | - mControlPoint[i].SetPosition( mPath.GetControlPoint(i) ); | 228 | + std::string name( "ControlPoint"); |
| 229 | + name.push_back(i); | ||
| 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)); | ||
| 233 | + ++index; | ||
| 306 | } | 234 | } |
| 307 | } | 235 | } |
| 308 | 236 | ||
| 309 | - bool OnTouchPoint(Actor actor, const TouchEvent& event) | 237 | + /** |
| 238 | + * Create the path animation. | ||
| 239 | + */ | ||
| 240 | + void CreateAnimation() | ||
| 310 | { | 241 | { |
| 311 | - if(event.GetPointCount()>0) | 242 | + if( !mAnimation ) |
| 312 | { | 243 | { |
| 313 | - const TouchPoint& point = event.GetPoint(0); | 244 | + mAnimation = Animation::New( 2.0f ); |
| 245 | + } | ||
| 246 | + else | ||
| 247 | + { | ||
| 248 | + mAnimation.Pause(); | ||
| 249 | + mAnimation.Clear(); | ||
| 250 | + mActor.SetRotation( Quaternion() ); | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + mAnimation.Animate( mActor, mPath, mForward ); | ||
| 254 | + mAnimation.SetLooping( true ); | ||
| 255 | + mAnimation.Play(); | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + /** | ||
| 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 | ||
| 262 | + */ | ||
| 263 | + Actor GetClosestActor(const Vector3& point) | ||
| 264 | + { | ||
| 265 | + size_t pointCount = mPath.GetPointCount(); | ||
| 266 | + size_t controlPointCount = 3*pointCount - 2; | ||
| 267 | + Actor result; | ||
| 268 | + float minDistance = 1.0/0.0; | ||
| 314 | 269 | ||
| 315 | - if(point.state==TouchPoint::Down) | 270 | + for( size_t i(0); i<controlPointCount; ++i ) |
| 271 | + { | ||
| 272 | + Vector3 v = mControlPoint[i].GetCurrentPosition() - point; | ||
| 273 | + float distance = v.LengthSquared(); | ||
| 274 | + if( distance < minDistance ) | ||
| 316 | { | 275 | { |
| 317 | - // Start dragging | ||
| 318 | - mDragActor = actor; | 276 | + result = mControlPoint[i]; |
| 277 | + minDistance = distance; | ||
| 319 | } | 278 | } |
| 320 | } | 279 | } |
| 321 | - return false; | 280 | + |
| 281 | + Vector2 dpi = Dali::Stage::GetCurrent().GetDpi(); | ||
| 282 | + float distanceTreshold = 0.2f * dpi.x * 0.2f * dpi.x; | ||
| 283 | + | ||
| 284 | + if( minDistance < distanceTreshold ) | ||
| 285 | + { | ||
| 286 | + return result; | ||
| 287 | + } | ||
| 288 | + else | ||
| 289 | + { | ||
| 290 | + return Actor(); | ||
| 291 | + } | ||
| 322 | } | 292 | } |
| 323 | 293 | ||
| 294 | + /** | ||
| 295 | + * Callback called when the background layer is touched | ||
| 296 | + */ | ||
| 324 | bool OnTouchLayer(Actor actor, const TouchEvent& event) | 297 | bool OnTouchLayer(Actor actor, const TouchEvent& event) |
| 325 | { | 298 | { |
| 326 | if(event.GetPointCount()>0) | 299 | if(event.GetPointCount()>0) |
| @@ -332,99 +305,177 @@ public: | @@ -332,99 +305,177 @@ public: | ||
| 332 | //Stop dragging | 305 | //Stop dragging |
| 333 | mDragActor.Reset(); | 306 | mDragActor.Reset(); |
| 334 | } | 307 | } |
| 335 | - else if(!mDragActor && point.state==TouchPoint::Down && mPath.GetPointCount()<10 ) | 308 | + else if(point.state==TouchPoint::Down) |
| 336 | { | 309 | { |
| 337 | - // Add new point | ||
| 338 | - const TouchPoint& point = event.GetPoint(0); | ||
| 339 | - Vector3 newPoint = Vector3(point.screen.x, point.screen.y, 0.0f); | ||
| 340 | - | ||
| 341 | - size_t pointCount = mPath.GetPointCount(); | ||
| 342 | - Vector3 lastPoint = mPath.GetPoint( pointCount-1); | ||
| 343 | - mPath.AddPoint( newPoint ); | ||
| 344 | - | ||
| 345 | - Vector3 displacement = (newPoint-lastPoint)/8; | ||
| 346 | - | ||
| 347 | - mPath.AddControlPoint( lastPoint + displacement ); | ||
| 348 | - mPath.AddControlPoint( newPoint - displacement); | ||
| 349 | - | ||
| 350 | - DrawPath( 200u ); | ||
| 351 | - CreateAnimation(); | ||
| 352 | - } | ||
| 353 | - else | ||
| 354 | - { | ||
| 355 | - if( mDragActor ) | 310 | + Vector3 touchPoint = Vector3(event.GetPoint(0).screen.x, event.GetPoint(0).screen.y, 0.0f); |
| 311 | + if(!mDragActor ) | ||
| 356 | { | 312 | { |
| 357 | - const TouchPoint& point = event.GetPoint(0); | ||
| 358 | - Vector3 newPosition = Vector3(point.screen.x, point.screen.y, 0.0f); | ||
| 359 | - | ||
| 360 | - std::string actorName(mDragActor.GetName()); | ||
| 361 | - | ||
| 362 | - if( actorName.compare(0, 4, "Knot") == 0) | 313 | + mDragActor = GetClosestActor( touchPoint ); |
| 314 | + if( !mDragActor && mPath.GetPointCount() < 10 ) | ||
| 363 | { | 315 | { |
| 364 | - int index = actorName[4]; | ||
| 365 | - mPath.GetPoint(index) = newPosition; | 316 | + // Add new point |
| 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); | ||
| 322 | + | ||
| 323 | + DrawPath( 200u ); | ||
| 324 | + CreateAnimation(); | ||
| 366 | } | 325 | } |
| 367 | - else | ||
| 368 | - { | ||
| 369 | - int index = actorName[12]; | ||
| 370 | - mPath.GetControlPoint(index) = newPosition; | ||
| 371 | - } | ||
| 372 | - | ||
| 373 | - DrawPath( 200u ); | ||
| 374 | - CreateAnimation(); | ||
| 375 | } | 326 | } |
| 376 | } | 327 | } |
| 328 | + else if( mDragActor && point.state==TouchPoint::Motion ) | ||
| 329 | + { | ||
| 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) | ||
| 333 | + { | ||
| 334 | + int index = actorName[4]; | ||
| 335 | + mPath.GetPoint(index) = touchPoint; | ||
| 336 | + } | ||
| 337 | + else | ||
| 338 | + { | ||
| 339 | + int index = actorName[12]; | ||
| 340 | + mPath.GetControlPoint(index) = touchPoint; | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + DrawPath( 200u ); | ||
| 344 | + CreateAnimation(); | ||
| 345 | + } | ||
| 377 | } | 346 | } |
| 378 | - return false; | 347 | + |
| 348 | + return true; | ||
| 379 | } | 349 | } |
| 380 | 350 | ||
| 381 | - /** | ||
| 382 | - * Main key event handler. | ||
| 383 | - * Quit on escape key. | ||
| 384 | - */ | ||
| 385 | - void OnKeyEvent(const KeyEvent& event) | 351 | + bool OnTouchGuiLayer(Actor actor, const TouchEvent& event) |
| 352 | + { | ||
| 353 | + mDragActor.Reset(); | ||
| 354 | + return false; | ||
| 355 | + } | ||
| 356 | + /** | ||
| 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 | ||
| 360 | + */ | ||
| 361 | + bool OnSliderXValueChange( Slider s, float value) | ||
| 386 | { | 362 | { |
| 387 | - if( event.state == KeyEvent::Down ) | 363 | + if( fabs( value ) - Math::MACHINE_EPSILON_1000 < 0.0f ) |
| 388 | { | 364 | { |
| 389 | - if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || | ||
| 390 | - IsKey( event, Dali::DALI_KEY_BACK ) ) | ||
| 391 | - { | ||
| 392 | - mApplication.Quit(); | ||
| 393 | - } | 365 | + mForward.x = 0.0f; |
| 366 | + } | ||
| 367 | + else | ||
| 368 | + { | ||
| 369 | + mForward.x = value; | ||
| 394 | } | 370 | } |
| 371 | + | ||
| 372 | + CreateAnimation(); | ||
| 373 | + return true; | ||
| 395 | } | 374 | } |
| 396 | 375 | ||
| 397 | /** | 376 | /** |
| 398 | - * Callback called when user end to input text in any of the TextInput | ||
| 399 | - * @param[in] textInput The text input that has generated the signal | 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 | ||
| 400 | */ | 380 | */ |
| 401 | - void OnTextInputEnd( TextInput textInput) | 381 | + bool OnSliderYValueChange( Slider s, float value) |
| 402 | { | 382 | { |
| 403 | - mForward.x = (float)atof( mTextInput[0].GetText().c_str() ); | ||
| 404 | - mForward.y = (float)atof( mTextInput[1].GetText().c_str() ); | ||
| 405 | - mForward.z = (float)atof( mTextInput[2].GetText().c_str() ); | 383 | + if( fabs( value ) - Math::MACHINE_EPSILON_1000 < 0.0f ) |
| 384 | + { | ||
| 385 | + mForward.y = 0.0f; | ||
| 386 | + } | ||
| 387 | + else | ||
| 388 | + { | ||
| 389 | + mForward.y = value; | ||
| 390 | + } | ||
| 406 | CreateAnimation(); | 391 | CreateAnimation(); |
| 392 | + return true; | ||
| 407 | } | 393 | } |
| 408 | 394 | ||
| 409 | /** | 395 | /** |
| 410 | - * Create the path animation. | 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 | ||
| 411 | */ | 399 | */ |
| 412 | - void CreateAnimation() | 400 | + bool OnSliderZValueChange( Slider s, float value) |
| 413 | { | 401 | { |
| 414 | - if( !mAnimation ) | 402 | + if( fabs( value ) - Math::MACHINE_EPSILON_1000 < 0.0f ) |
| 415 | { | 403 | { |
| 416 | - mAnimation = Animation::New( 2.0f ); | 404 | + mForward.z = 0.0f; |
| 417 | } | 405 | } |
| 418 | else | 406 | else |
| 419 | { | 407 | { |
| 420 | - mAnimation.Pause(); | ||
| 421 | - mAnimation.Clear(); | ||
| 422 | - mActor.SetRotation( Quaternion() ); | 408 | + mForward.z = value; |
| 423 | } | 409 | } |
| 424 | 410 | ||
| 425 | - mAnimation.Animate( mActor, mPath, mForward ); | ||
| 426 | - mAnimation.SetLooping( true ); | ||
| 427 | - mAnimation.Play(); | 411 | + CreateAnimation(); |
| 412 | + return true; | ||
| 413 | + } | ||
| 414 | + | ||
| 415 | + /** | ||
| 416 | + * Main key event handler. | ||
| 417 | + * Quit on escape key. | ||
| 418 | + */ | ||
| 419 | + void OnKeyEvent(const KeyEvent& event) | ||
| 420 | + { | ||
| 421 | + if( event.state == KeyEvent::Down ) | ||
| 422 | + { | ||
| 423 | + if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || | ||
| 424 | + IsKey( event, Dali::DALI_KEY_BACK ) ) | ||
| 425 | + { | ||
| 426 | + mApplication.Quit(); | ||
| 427 | + } | ||
| 428 | + } | ||
| 429 | + } | ||
| 430 | + | ||
| 431 | + /** | ||
| 432 | + * One-time setup in response to Application InitSignal. | ||
| 433 | + */ | ||
| 434 | + void Create( Application& application ) | ||
| 435 | + { | ||
| 436 | + // Get a handle to the stage: | ||
| 437 | + Stage stage = Stage::GetCurrent(); | ||
| 438 | + | ||
| 439 | + // Connect to input event signals: | ||
| 440 | + stage.KeyEventSignal().Connect(this, &PathController::OnKeyEvent); | ||
| 441 | + | ||
| 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, | ||
| 446 | + view, | ||
| 447 | + toolBar, | ||
| 448 | + BACKGROUND_IMAGE, | ||
| 449 | + TOOLBAR_IMAGE, | ||
| 450 | + "" ); | ||
| 451 | + | ||
| 452 | + mContentLayer.TouchedSignal().Connect(this, &PathController::OnTouchLayer); | ||
| 453 | + | ||
| 454 | + //Title | ||
| 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()); | ||
| 461 | + | ||
| 462 | + //Path | ||
| 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); | ||
| 467 | + DrawPath( 200u ); | ||
| 468 | + | ||
| 469 | + //Actor | ||
| 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 ); | ||
| 475 | + stage.Add( mActor ); | ||
| 476 | + | ||
| 477 | + CreateAnimation(); | ||
| 478 | + CreateControls(); | ||
| 428 | } | 479 | } |
| 429 | 480 | ||
| 430 | private: | 481 | private: |
| @@ -438,14 +489,14 @@ private: | @@ -438,14 +489,14 @@ private: | ||
| 438 | Animation mAnimation; ///< Path animation | 489 | Animation mAnimation; ///< Path animation |
| 439 | 490 | ||
| 440 | MeshActor mMeshPath; ///< Mesh actor for the path | 491 | MeshActor mMeshPath; ///< Mesh actor for the path |
| 441 | - MeshActor mMeshHandlers; ///< Mesh actor for the segments connecting points and control points | ||
| 442 | - Actor mKnot[10]; ///< ImageActors for the interpolation points | ||
| 443 | - Actor mControlPoint[18]; ///< ImageActors for the control points | 492 | + MeshActor mMeshHandlers; ///< Mesh actor for the handlers of the path |
| 493 | + | ||
| 494 | + Actor mControlPoint[28]; ///< ImageActors represeting control points of the path | ||
| 444 | 495 | ||
| 445 | Actor mDragActor; ///< Reference to the actor currently being dragged | 496 | Actor mDragActor; ///< Reference to the actor currently being dragged |
| 446 | - TextInput mTextInput[3]; ///< Text input to specify forward vector of the path animation | ||
| 447 | }; | 497 | }; |
| 448 | 498 | ||
| 499 | + | ||
| 449 | void RunTest( Application& application ) | 500 | void RunTest( Application& application ) |
| 450 | { | 501 | { |
| 451 | PathController test( application ); | 502 | PathController test( application ); |