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 #include "shared/view.h"
21 #include <dali/dali.h>
22 #include <dali-toolkit/dali-toolkit.h>
26 using namespace Dali::Toolkit;
28 using namespace DemoHelper;
32 const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-default.png" );
33 const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
35 const char* APPLICATION_TITLE_PAN_LIGHT( "Lighting: Pan Light" );
36 const char* APPLICATION_TITLE_PAN_OBJECT( "Lighting: Pan Object" );
37 const char* APPLICATION_TITLE_PAN_SCENE( "Lighting: Pan Scene" );
38 const char* APPLICATION_TITLE_ROTATE_SCENE( "Lighting: Rotate Scene" );
39 const char* CHANGE_EFFECT_IMAGE( DALI_IMAGE_DIR "icon-change.png" );
40 const char* RESET_ICON( DALI_IMAGE_DIR "icon-reset.png" );
42 const char* SCENE_IMAGE_1( DALI_IMAGE_DIR "gallery-small-10.jpg");
43 const char* SCENE_IMAGE_2( DALI_IMAGE_DIR "gallery-small-42.jpg");
44 const char* SCENE_IMAGE_3( DALI_IMAGE_DIR "gallery-small-48.jpg");
46 const Quaternion JAUNTY_ROTATION(Math::PI/5.0f, Math::PI/5.0f, 0.0f); // Euler angles
47 const float MIN_PINCH_SCALE( 0.3f );
48 const float MAX_PINCH_SCALE( 2.05f );
50 const float R3_2(0.8660254);
51 const Vector3 TOP_POINT( 0.0f, -1.0f, 0.0f);
52 const Vector3 LEFT_POINT( -R3_2, 0.5f, 0.0f);
53 const Vector3 RIGHT_POINT( R3_2, 0.5f, 0.0f);
54 const Vector3 FRONT_POINT( 0.0f, 0.0f, 20.0f);
56 const Vector2 DEFAULT_STAGE_SIZE( 480.0f, 800.0f );
61 * This example shows a fixed point light onto an animating set of images
62 * casting a shadow onto a wall. The whole scene can be rotated.
65 class TestApp : public ConnectionTracker
71 * @param application class, stored as reference
73 TestApp(Application &app)
76 mTranslation(Vector3::ZERO),
79 mLightLongitudinal(0.0f),
81 mObjectLongitudinal(0.0f),
82 mObjectAxisTilt(0.0f),
84 mScaleAtPinchStart(0.5f),
87 app.InitSignal().Connect(this, &TestApp::Create);
88 app.TerminateSignal().Connect(this, &TestApp::Terminate);
93 // Nothing to do here; All the members of this class get deleted automatically and they delete their children
97 struct PositionInFrontOf
103 Vector3 operator()( const Vector3& current, const PropertyInput& property )
105 Vector3 position = property.GetVector3();
111 struct QuaternionEqualToConstraint
113 QuaternionEqualToConstraint()
117 Quaternion operator()( const Quaternion& current, const PropertyInput& property )
119 return property.GetQuaternion();
123 struct RotationConstraint
125 RotationConstraint(float sign)
130 Quaternion operator()( const Quaternion& current, const PropertyInput& property )
132 Degree angle(property.GetFloat());
133 return Quaternion( Radian(angle) * mSign, Vector3::YAXIS );
140 * This method gets called once the main loop of application is up and running
142 void Create(Application& app)
144 srand(0); // Want repeatable path
146 Stage::GetCurrent().KeyEventSignal().Connect(this, &TestApp::OnKeyEvent);
148 CreateToolbarAndView(app);
149 CreateShadowViewAndLights();
153 void CreateToolbarAndView(Application& app)
155 // Creates a default view with a default tool bar.
156 // The view is added to the stage.
157 Toolkit::ToolBar toolBar;
158 mContents = DemoHelper::CreateView( app,
165 // Add an effect-changing button on the right of the tool bar.
166 Image imageChangeEffect = ResourceImage::New( CHANGE_EFFECT_IMAGE );
167 Toolkit::PushButton effectChangeButton = Toolkit::PushButton::New();
168 effectChangeButton.SetBackgroundImage(imageChangeEffect);
169 effectChangeButton.ClickedSignal().Connect( this, &TestApp::OnEffectButtonClicked );
170 toolBar.AddControl( effectChangeButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
172 // Add title to the tool bar.
173 mTitleActor = Toolkit::TextView::New();
174 toolBar.AddControl( mTitleActor, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Toolkit::Alignment::HorizontalCenter );
177 mTitleActor.SetText( APPLICATION_TITLE_PAN_SCENE );
178 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_SCENE ) );
179 mTitleActor.SetStyleToCurrentText( DemoHelper::GetDefaultTextStyle() );
182 Image resetImage = ResourceImage::New( RESET_ICON );
183 Toolkit::PushButton resetButton = Toolkit::PushButton::New();
184 resetButton.SetBackgroundImage( resetImage );
185 resetButton.ClickedSignal().Connect( this, &TestApp::OnResetPressed );
186 toolBar.AddControl( resetButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalCenter, DemoHelper::DEFAULT_PLAY_PADDING );
189 mView.SetPosition(Vector3(0.0f, 0.0f, -50));
191 mContents.SetPosition(mTranslation);
192 mContents.SetRotation(CalculateWorldRotation(Radian(mLongitudinal), Radian(mAxisTilt)));
193 mContents.SetScale(mPinchScale, mPinchScale, mPinchScale);
195 mPanGestureDetector = PanGestureDetector::New();
196 mPanGestureDetector.Attach( mView );
197 mPanGestureDetector.DetectedSignal().Connect(this, &TestApp::OnPan);
199 mPinchGestureDetector = PinchGestureDetector::New();
200 mPinchGestureDetector.Attach( mView );
201 mPinchGestureDetector.DetectedSignal().Connect(this, &TestApp::OnPinch);
203 mTapGestureDetector = TapGestureDetector::New(1, 1);
204 mTapGestureDetector.Attach( mView );
205 mTapGestureDetector.DetectedSignal().Connect(this, &TestApp::OnTap);
210 void CreateShadowViewAndLights()
212 mShadowView = Toolkit::ShadowView::New();
213 mShadowView.SetName("Container");
214 mShadowView.SetParentOrigin(ParentOrigin::CENTER);
215 mShadowView.SetAnchorPoint(AnchorPoint::CENTER);
216 mShadowView.SetSizeMode( SIZE_EQUAL_TO_PARENT );
217 mShadowView.SetPointLightFieldOfView( Math::PI / 2.0f);
218 mContents.Add(mShadowView);
220 Image brickWall = ResourceImage::New(DALI_IMAGE_DIR "brick-wall.jpg");
221 mShadowPlaneBg = ImageActor::New(brickWall);
222 mShadowPlaneBg.SetParentOrigin(ParentOrigin::CENTER);
223 mShadowPlaneBg.SetAnchorPoint(AnchorPoint::CENTER);
224 mShadowPlaneBg.SetName("Plane");
225 mShadowPlaneBg.SetSize(1000.0f, 1000.0f);
226 mContents.Add(mShadowPlaneBg);
227 mShadowPlaneBg.SetPosition(Vector3(50.0f, 50.0f, -200.0f));
229 mShadowView.SetShadowPlane(mShadowPlaneBg);
230 mShadowView.Activate();
232 mLightAnchor = Actor::New();
233 mLightAnchor.SetParentOrigin(ParentOrigin::CENTER);
234 mLightAnchor.SetAnchorPoint(AnchorPoint::CENTER);
235 mLightAnchor.SetRotation(CalculateWorldRotation(Radian(mLightLongitudinal), Radian(mLightAxisTilt)));
237 // Work out a scaling factor as the initial light position was calculated for desktop
238 // Need to scale light position as scene actor size is based on stage size (i.e. much bigger on device)
239 Vector2 stageSize( Stage::GetCurrent().GetSize() );
240 float scaleFactor = stageSize.x / DEFAULT_STAGE_SIZE.x;
242 mCastingLight = Actor::New();
243 mCastingLight.SetParentOrigin(ParentOrigin::CENTER);
244 mCastingLight.SetAnchorPoint(AnchorPoint::CENTER);
245 mCastingLight.SetPosition( Vector3( 0.0f, 0.0f, 800.0f ) * scaleFactor );
248 style.SetFontPointSize( PointSize(DemoHelper::ScalePointSize(20.0f)) );
249 style.SetFontName("Times New Roman");
250 style.SetFontStyle("Book");
252 TextActorParameters parameters( style, TextActorParameters::FONT_DETECTION_ON );
253 TextActor text = TextActor::New("Light", parameters);
254 text.SetColor(Color::BLUE);
256 mCastingLight.Add(text);
257 mLightAnchor.Add(mCastingLight);
258 mShadowPlaneBg.Add(mLightAnchor);
260 text.SetParentOrigin(ParentOrigin::CENTER);
261 mShadowView.SetPointLight(mCastingLight);
266 mSceneActor = Actor::New();
267 mSceneActor.SetParentOrigin(ParentOrigin::CENTER);
269 // Create and add images to the scene actor:
270 mImageActor1 = ImageActor::New( ResourceImage::New(SCENE_IMAGE_1) );
271 mImageActor2 = ImageActor::New( ResourceImage::New(SCENE_IMAGE_2) );
272 mImageActor3 = ImageActor::New( ResourceImage::New(SCENE_IMAGE_3) );
275 mImageActor2.SetParentOrigin(ParentOrigin::CENTER);
277 mImageActor1.SetParentOrigin(ParentOrigin::CENTER_LEFT);
278 mImageActor1.SetAnchorPoint(AnchorPoint::CENTER_RIGHT);
280 mImageActor3.SetParentOrigin(ParentOrigin::CENTER_RIGHT);
281 mImageActor3.SetAnchorPoint(AnchorPoint::CENTER_LEFT);
283 mSceneActor.Add(mImageActor2);
284 mImageActor2.Add(mImageActor1);
285 mImageActor2.Add(mImageActor3);
287 Property::Index angleIndex = mImageActor2.RegisterProperty("angle", Property::Value(30.0f));
288 Source angleSrc( mImageActor2, angleIndex );
289 mImageActor1.ApplyConstraint(Constraint::New<Quaternion>( Actor::Property::Rotation, angleSrc,
290 RotationConstraint(-1.0f)));
291 mImageActor3.ApplyConstraint(Constraint::New<Quaternion>( Actor::Property::Rotation, angleSrc,
292 RotationConstraint(+1.0f)));
294 mSceneAnimation = Animation::New(2.5f);
296 // Want to animate angle from 30 => -30 and back again smoothly.
298 mSceneAnimation.AnimateTo( Property( mImageActor2, angleIndex ), Property::Value(-30.0f), AlphaFunctions::Sin );
300 mSceneAnimation.SetLooping(true);
301 mSceneAnimation.Play();
303 mSceneActor.SetSize(250.0f, 250.0f);
304 mSceneActor.SetPosition(0.0f, 0.0f, 130.0f);
305 mShadowView.Add(mSceneActor);
309 Quaternion CalculateWorldRotation(Radian longitude, Radian axisTilt )
311 Quaternion q(longitude, Vector3::YAXIS);
312 Quaternion p(axisTilt, Vector3::XAXIS);
316 void OnTap(Dali::Actor actor, const TapGesture& gesture)
318 if( mSceneAnimation )
322 mSceneAnimation.Pause();
327 mSceneAnimation.Play();
333 void OnPan(Actor actor, const PanGesture& gesture)
335 switch (gesture.state)
337 case Gesture::Continuing:
343 mLightLongitudinal += gesture.displacement.x/4.0f;
344 mLightAxisTilt -= gesture.displacement.y/6.0f;
345 mLightAxisTilt = Clamp<float>(mLightAxisTilt, -90.0f, 90.0f);
346 mLightAnchor.SetRotation(CalculateWorldRotation(Radian(mLightLongitudinal), Radian(mLightAxisTilt)));
352 mTranslation += Vector3(gesture.displacement.x, gesture.displacement.y, 0.f);
353 mContents.SetPosition(mTranslation);
359 mLongitudinal += gesture.displacement.x/4.0f;
360 mAxisTilt -= gesture.displacement.y/6.0f;
361 mAxisTilt = Clamp<float>(mAxisTilt, -90.0f, 90.0f);
362 mContents.SetRotation(CalculateWorldRotation(Radian(mLongitudinal), Radian(mAxisTilt)));
368 mObjectLongitudinal += gesture.displacement.x/4.0f;
369 mObjectAxisTilt -= gesture.displacement.y/6.0f;
370 mObjectAxisTilt = Clamp<float>(mObjectAxisTilt, -90.0f, 90.0f);
371 mSceneActor.SetRotation(CalculateWorldRotation(Radian(mObjectLongitudinal), Radian(mObjectAxisTilt)));
378 case Gesture::Finished:
379 // Start animation at last known speed
387 void OnPinch(Actor actor, const PinchGesture& gesture)
389 if (gesture.state == Gesture::Started)
391 mScaleAtPinchStart = mContents.GetCurrentScale().x;
393 mPinchScale = Clamp(mScaleAtPinchStart * gesture.scale, MIN_PINCH_SCALE, MAX_PINCH_SCALE);
395 mContents.SetScale(mPinchScale, mPinchScale, mPinchScale);
398 void Terminate(Application& app)
402 Stage::GetCurrent().Remove(mSceneActor);
406 Stage::GetCurrent().Remove(mView);
410 void OnKeyEvent(const KeyEvent& event)
412 if(event.state == KeyEvent::Down)
414 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
421 bool OnEffectButtonClicked( Toolkit::Button button )
426 mPanState = ROTATE_SCENE;
427 mTitleActor.SetText( APPLICATION_TITLE_ROTATE_SCENE );
428 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_ROTATE_SCENE ) );
431 mPanState = PAN_LIGHT;
432 mTitleActor.SetText( APPLICATION_TITLE_PAN_LIGHT );
433 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_LIGHT ) );
436 mPanState = PAN_OBJECT;
437 mTitleActor.SetText( APPLICATION_TITLE_PAN_OBJECT );
438 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_OBJECT ) );
441 mPanState = PAN_SCENE;
442 mTitleActor.SetText( APPLICATION_TITLE_PAN_SCENE );
443 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_SCENE ) );
449 mTitleActor.SetStyleToCurrentText(DemoHelper::GetDefaultTextStyle());
454 bool OnResetPressed( Toolkit::Button button )
457 mTranslation = Vector3::ZERO;
458 mContents.SetPosition(mTranslation);
460 // Align scene so that light anchor orientation is Z Axis
461 mAxisTilt = -mLightAxisTilt;
462 mLongitudinal = -mLightLongitudinal;
463 mContents.SetRotation(CalculateWorldRotation(Radian(mLongitudinal), Radian(mAxisTilt)));
473 Animation mAnimation;
474 Animation mSceneAnimation;
476 Toolkit::ShadowView mShadowView;
477 ImageActor mShadowPlaneBg;
478 ImageActor mShadowPlane;
481 ImageActor mImageActor1;
482 ImageActor mImageActor2;
483 ImageActor mImageActor3;
484 PanGestureDetector mPanGestureDetector;
485 PinchGestureDetector mPinchGestureDetector;
486 TapGestureDetector mTapGestureDetector;
487 Vector3 mTranslation;
488 Degree mLongitudinal;
490 Degree mLightLongitudinal;
491 Degree mLightAxisTilt;
492 Degree mObjectLongitudinal;
493 Degree mObjectAxisTilt;
495 float mScaleAtPinchStart;
497 Property::Index mAngle1Index;
498 Property::Index mAngle3Index;
500 Toolkit::TextView mTitleActor;
513 /*****************************************************************************/
516 RunTest(Application& app)
522 /*****************************************************************************/
525 main(int argc, char **argv)
527 Application app = Application::New(&argc, &argv);