Prepare for Tizen 4.0 Build
[platform/core/uifw/dali-demo.git] / examples / new-window / new-window-example.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 // EXTERNAL INCLUDES
18 #include <dali/devel-api/images/texture-set-image.h>
19 #include <dali/public-api/rendering/renderer.h>
20 #include <dali-toolkit/dali-toolkit.h>
21 #include <dali-toolkit/devel-api/controls/bubble-effect/bubble-emitter.h>
22 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
23 #include <dali-toolkit/devel-api/controls/gaussian-blur-view/gaussian-blur-view.h>
24
25 #include <cstdio>
26 #include <iostream>
27
28 // INTERNAL INCLUDES
29 #include "shared/view.h"
30 #include "shared/utility.h"
31
32 using namespace Dali;
33 using namespace Dali::Toolkit;
34
35 class NewWindowController;
36
37 namespace
38 {
39 const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" );
40 const char * const TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
41 const char * const LOSE_CONTEXT_IMAGE( DEMO_IMAGE_DIR "icon-cluster-wobble.png" );
42 const char * const LOSE_CONTEXT_IMAGE_SELECTED( DEMO_IMAGE_DIR "icon-cluster-wobble-selected.png" );
43 const char * const BASE_IMAGE( DEMO_IMAGE_DIR "gallery-large-14.jpg" );
44 const char * const EFFECT_IMAGE( DEMO_IMAGE_DIR "gallery-large-18.jpg" );
45 const char * const LOGO_IMAGE(DEMO_IMAGE_DIR "dali-logo.png");
46
47 const float EXPLOSION_DURATION(1.2f);
48 const unsigned int EMIT_INTERVAL_IN_MS(40);
49 const float TRACK_DURATION_IN_MS(970);
50
51 Application gApplication;
52 NewWindowController* gNewWindowController(NULL);
53
54 #define MAKE_SHADER(A)#A
55
56 const char* VERTEX_COLOR_MESH = MAKE_SHADER(
57 attribute mediump vec3  aPosition;\n
58 attribute lowp    vec3  aColor;\n
59 uniform   mediump mat4  uMvpMatrix;\n
60 uniform   mediump vec3  uSize;\n
61 varying   lowp    vec3  vColor;\n
62 \n
63 void main()\n
64 {\n
65   gl_Position = uMvpMatrix * vec4( aPosition*uSize, 1.0 );\n
66   vColor = aColor;\n
67 }\n
68 );
69
70 const char* FRAGMENT_COLOR_MESH = MAKE_SHADER(
71 uniform lowp vec4  uColor;\n
72 varying lowp vec3  vColor;\n
73 \n
74 void main()\n
75 {\n
76   gl_FragColor = vec4(vColor,1.0)*uColor;
77 }\n
78 );
79
80 const char* VERTEX_TEXTURE_MESH = MAKE_SHADER(
81 attribute mediump vec3  aPosition;\n
82 attribute highp   vec2  aTexCoord;\n
83 uniform   mediump mat4  uMvpMatrix;\n
84 uniform   mediump vec3  uSize;\n
85 varying   mediump vec2  vTexCoord;\n
86 \n
87 void main()\n
88 {\n
89   gl_Position = uMvpMatrix * vec4( aPosition*uSize, 1.0 );\n
90   vTexCoord = aTexCoord;\n
91 }\n
92 );
93
94 const char* FRAGMENT_TEXTURE_MESH = MAKE_SHADER(
95 varying mediump vec2  vTexCoord;\n
96 uniform lowp    vec4  uColor;\n
97 uniform sampler2D     sTexture;\n
98 \n
99 void main()\n
100 {\n
101   gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
102 }\n
103 );
104
105 const char* FRAGMENT_BLEND_SHADER = MAKE_SHADER(
106 varying mediump vec2  vTexCoord;\n
107 uniform sampler2D sTexture;\n
108 uniform sampler2D sEffect;\n
109 uniform mediump float alpha;\n
110 \n
111 void main()\n
112 {\n
113   mediump vec4 fragColor = texture2D(sTexture, vTexCoord);\n
114   mediump vec4 fxColor   = texture2D(sEffect, vTexCoord);\n
115   gl_FragColor = mix(fragColor,fxColor, alpha);\n
116 }\n
117 );
118
119 }; // anonymous namespace
120
121
122 class NewWindowController : public ConnectionTracker
123 {
124 public:
125   NewWindowController( Application& app );
126   void Create( Application& app );
127   void Destroy( Application& app );
128
129   void AddBubbles( Actor& parentActor, const Vector2& stageSize);
130   void AddMeshActor( Actor& parentActor );
131   void AddBlendingImageActor( Actor& parentActor );
132   void AddTextLabel( Actor& parentActor );
133
134   ImageView CreateBlurredMirrorImage(const char* imageName);
135   FrameBufferImage CreateFrameBufferForImage( const char* imageName, Property::Map& shaderEffect, const Vector3& rgbDelta );
136   void SetUpBubbleEmission( const Vector2& emitPosition, const Vector2& direction );
137   Geometry CreateMeshGeometry();
138   Dali::Property::Map CreateColorModifierer();
139
140   static void NewWindow(void);
141
142   bool OnTrackTimerTick();
143   void OnKeyEvent(const KeyEvent& event);
144   bool OnLoseContextButtonClicked( Toolkit::Button button );
145   void OnContextLost();
146   void OnContextRegained();
147
148 private:
149   Application                mApplication;
150   TextLabel                  mTextActor;
151
152   Toolkit::Control           mView;                              ///< The View instance.
153   Toolkit::ToolBar           mToolBar;                           ///< The View's Toolbar.
154   TextLabel                  mTitleActor;                        ///< The Toolbar's Title.
155   Layer                      mContentLayer;                      ///< Content layer (scrolling cluster content)
156   Toolkit::PushButton        mLoseContextButton;
157
158   Toolkit::BubbleEmitter     mEmitter;
159   Timer                      mEmitTrackTimer;
160   bool                       mNeedNewAnimation;
161   unsigned int               mAnimateComponentCount;
162   Animation                  mEmitAnimation;
163 };
164
165
166 NewWindowController::NewWindowController( Application& application )
167 : mApplication(application),
168   mNeedNewAnimation(true),
169   mAnimateComponentCount( 0 )
170 {
171   mApplication.InitSignal().Connect(this, &NewWindowController::Create);
172   mApplication.TerminateSignal().Connect(this, &NewWindowController::Destroy);
173 }
174
175 void NewWindowController::Create( Application& app )
176 {
177   Stage stage = Stage::GetCurrent();
178   stage.SetBackgroundColor(Color::YELLOW);
179
180   stage.KeyEventSignal().Connect(this, &NewWindowController::OnKeyEvent);
181
182   // The Init signal is received once (only) during the Application lifetime
183
184   // Hide the indicator bar
185   mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
186
187   mContentLayer = DemoHelper::CreateView( app,
188                                           mView,
189                                           mToolBar,
190                                           "",
191                                           TOOLBAR_IMAGE,
192                                           "Context recovery" );
193
194   Size stageSize = stage.GetSize();
195   ImageView backgroundActor = ImageView::New( BACKGROUND_IMAGE, Dali::ImageDimensions( stageSize.x, stageSize.y ) );
196   backgroundActor.SetParentOrigin( ParentOrigin::CENTER );
197   mContentLayer.Add(backgroundActor);
198
199   // Point the default render task at the view
200   RenderTaskList taskList = stage.GetRenderTaskList();
201   RenderTask defaultTask = taskList.GetTask( 0u );
202   if ( defaultTask )
203   {
204     defaultTask.SetSourceActor( mView );
205   }
206
207   mLoseContextButton = Toolkit::PushButton::New();
208   mLoseContextButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, LOSE_CONTEXT_IMAGE );
209   mLoseContextButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, LOSE_CONTEXT_IMAGE_SELECTED );
210   mLoseContextButton.ClickedSignal().Connect( this, &NewWindowController::OnLoseContextButtonClicked );
211   mToolBar.AddControl( mLoseContextButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
212
213   Actor logoLayoutActor = Actor::New();
214   logoLayoutActor.SetParentOrigin(ParentOrigin::CENTER);
215   logoLayoutActor.SetPosition(0.0f, -200.0f, 0.0f);
216   logoLayoutActor.SetScale(0.5f);
217   backgroundActor.Add(logoLayoutActor);
218
219   ImageView imageView = ImageView::New( LOGO_IMAGE );
220   imageView.SetName("daliLogo");
221   imageView.SetParentOrigin(ParentOrigin::CENTER);
222   imageView.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
223   logoLayoutActor.Add(imageView);
224
225   ImageView mirrorImageView = CreateBlurredMirrorImage(LOGO_IMAGE);
226   mirrorImageView.SetParentOrigin(ParentOrigin::TOP_CENTER);
227   mirrorImageView.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
228   logoLayoutActor.Add(mirrorImageView);
229
230   AddBubbles( backgroundActor, stage.GetSize());
231   AddMeshActor( backgroundActor );
232   AddBlendingImageActor( backgroundActor );
233   AddTextLabel( backgroundActor );
234
235   stage.ContextLostSignal().Connect(this, &NewWindowController::OnContextLost);
236   stage.ContextRegainedSignal().Connect(this, &NewWindowController::OnContextRegained);
237 }
238
239 void NewWindowController::Destroy( Application& app )
240 {
241   UnparentAndReset(mTextActor);
242 }
243
244 void NewWindowController::AddBubbles( Actor& parentActor, const Vector2& stageSize)
245 {
246   mEmitter = Toolkit::BubbleEmitter::New( stageSize,
247                                           DemoHelper::LoadTexture( DEMO_IMAGE_DIR "bubble-ball.png" ),
248                                           200, Vector2( 5.0f, 5.0f ) );
249
250   Texture background = DemoHelper::LoadTexture(BACKGROUND_IMAGE);
251   mEmitter.SetBackground( background, Vector3(0.5f, 0.f,0.5f) );
252   mEmitter.SetBubbleDensity( 9.f );
253   Actor bubbleRoot = mEmitter.GetRootActor();
254   parentActor.Add( bubbleRoot );
255   bubbleRoot.SetParentOrigin(ParentOrigin::CENTER);
256   bubbleRoot.SetZ(0.1f);
257
258   mEmitTrackTimer = Timer::New( EMIT_INTERVAL_IN_MS );
259   mEmitTrackTimer.TickSignal().Connect(this, &NewWindowController::OnTrackTimerTick);
260   mEmitTrackTimer.Start();
261 }
262
263 void NewWindowController::AddMeshActor( Actor& parentActor )
264 {
265   Geometry meshGeometry = CreateMeshGeometry();
266
267   // Create a coloured mesh
268   Shader shaderColorMesh = Shader::New( VERTEX_COLOR_MESH, FRAGMENT_COLOR_MESH );
269   Renderer colorMeshRenderer = Renderer::New( meshGeometry, shaderColorMesh );
270
271   Actor colorMeshActor = Actor::New();
272   colorMeshActor.AddRenderer( colorMeshRenderer );
273   colorMeshActor.SetSize( 175.f,175.f, 175.f );
274   colorMeshActor.SetParentOrigin( ParentOrigin::CENTER );
275   colorMeshActor.SetAnchorPoint(AnchorPoint::TOP_CENTER);
276   colorMeshActor.SetPosition(Vector3(0.0f, 50.0f, 0.0f));
277   colorMeshActor.SetOrientation( Degree(75.f), Vector3::XAXIS );
278   colorMeshActor.SetName("ColorMeshActor");
279
280  // Create a textured mesh
281   Texture effectTexture = DemoHelper::LoadTexture(EFFECT_IMAGE);
282   Shader shaderTextureMesh = Shader::New( VERTEX_TEXTURE_MESH, FRAGMENT_TEXTURE_MESH );
283   TextureSet textureSet = TextureSet::New();
284   textureSet.SetTexture( 0u, effectTexture );
285   Renderer textureMeshRenderer = Renderer::New( meshGeometry, shaderTextureMesh );
286   textureMeshRenderer.SetTextures( textureSet );
287
288   Actor textureMeshActor = Actor::New();
289   textureMeshActor.AddRenderer( textureMeshRenderer );
290   textureMeshActor.SetSize( 175.f,175.f, 175.f );
291   textureMeshActor.SetParentOrigin( ParentOrigin::CENTER );
292   textureMeshActor.SetAnchorPoint(AnchorPoint::TOP_CENTER);
293   textureMeshActor.SetPosition(Vector3(0.0f, 200.0f, 0.0f));
294   textureMeshActor.SetOrientation( Degree(75.f), Vector3::XAXIS );
295   textureMeshActor.SetName("TextureMeshActor");
296
297   Layer layer3d = Layer::New();
298   layer3d.SetParentOrigin( ParentOrigin::CENTER );
299   layer3d.SetAnchorPoint( AnchorPoint::CENTER );
300   layer3d.SetBehavior(Layer::LAYER_3D);
301
302   layer3d.Add( colorMeshActor );
303   layer3d.Add( textureMeshActor );
304   parentActor.Add(layer3d);
305 }
306
307 void NewWindowController::AddBlendingImageActor( Actor& parentActor )
308 {
309   Property::Map colorModifier = CreateColorModifierer();
310
311   FrameBufferImage fb2 = CreateFrameBufferForImage( EFFECT_IMAGE, colorModifier, Vector3( 0.5f, 0.5f, 0.5f ) );
312
313   ImageView tmpActor = ImageView::New(fb2);
314   parentActor.Add(tmpActor);
315   tmpActor.SetParentOrigin(ParentOrigin::CENTER_RIGHT);
316   tmpActor.SetAnchorPoint(AnchorPoint::TOP_RIGHT);
317   tmpActor.SetPosition(Vector3(0.0f, 150.0f, 0.0f));
318   tmpActor.SetScale(0.25f);
319
320   // create blending shader effect
321   Property::Map customShader;
322   customShader[ "fragmentShader" ] = FRAGMENT_BLEND_SHADER;
323   Property::Map map;
324   map[ "shader" ] = customShader;
325
326   ImageView blendActor = ImageView::New( BASE_IMAGE );
327   blendActor.SetProperty( ImageView::Property::IMAGE, map );
328   blendActor.RegisterProperty( "alpha", 0.5f );
329
330   blendActor.SetParentOrigin(ParentOrigin::CENTER_RIGHT);
331   blendActor.SetAnchorPoint(AnchorPoint::BOTTOM_RIGHT);
332   blendActor.SetPosition(Vector3(0.0f, 100.0f, 0.0f));
333   blendActor.SetSize(140, 140);
334   parentActor.Add(blendActor);
335
336   TextureSet textureSet = blendActor.GetRendererAt(0u).GetTextures();
337   TextureSetImage( textureSet, 1u, fb2 );
338 }
339
340 void NewWindowController::AddTextLabel( Actor& parentActor )
341 {
342   mTextActor = TextLabel::New("Some text");
343   mTextActor.SetParentOrigin(ParentOrigin::CENTER);
344   mTextActor.SetColor(Color::RED);
345   mTextActor.SetName("PushMe text");
346   parentActor.Add( mTextActor );
347 }
348
349 ImageView NewWindowController::CreateBlurredMirrorImage(const char* imageName)
350 {
351   Image image = DemoHelper::LoadImage(imageName);
352
353   Vector2 FBOSize = Vector2( image.GetWidth(), image.GetHeight() );
354   FrameBufferImage fbo = FrameBufferImage::New( FBOSize.width, FBOSize.height, Pixel::RGBA8888);
355
356   GaussianBlurView gbv = GaussianBlurView::New(5, 2.0f, Pixel::RGBA8888, 0.5f, 0.5f, true);
357   gbv.SetBackgroundColor(Color::TRANSPARENT);
358   gbv.SetUserImageAndOutputRenderTarget( image, fbo );
359   gbv.SetSize(FBOSize);
360   Stage::GetCurrent().Add(gbv);
361   gbv.ActivateOnce();
362
363   ImageView blurredActor = ImageView::New(fbo);
364   blurredActor.SetSize(FBOSize);
365   blurredActor.SetScale(1.0f, -1.0f, 1.0f);
366   return blurredActor;
367 }
368
369 FrameBufferImage NewWindowController::CreateFrameBufferForImage(const char* imageName, Property::Map& shaderEffect, const Vector3& rgbDelta )
370 {
371   Stage stage = Stage::GetCurrent();
372   Uint16Pair intFboSize = ResourceImage::GetImageSize( imageName );
373   Vector2 FBOSize = Vector2(intFboSize.GetWidth(), intFboSize.GetHeight());
374
375   FrameBufferImage framebuffer = FrameBufferImage::New(FBOSize.x, FBOSize.y );
376
377   RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
378
379   ImageView imageView = ImageView::New( imageName );
380   imageView.SetName("Source image actor");
381   imageView.SetProperty( ImageView::Property::IMAGE, shaderEffect );
382   imageView.RegisterProperty( "uRGBDelta", rgbDelta );
383
384   imageView.SetParentOrigin(ParentOrigin::CENTER);
385   imageView.SetAnchorPoint(AnchorPoint::CENTER);
386   imageView.SetScale(1.0f, -1.0f, 1.0f);
387   stage.Add(imageView); // Not in default image view
388
389   CameraActor cameraActor = CameraActor::New(FBOSize);
390   cameraActor.SetParentOrigin(ParentOrigin::CENTER);
391   cameraActor.SetFieldOfView(Math::PI*0.25f);
392   cameraActor.SetNearClippingPlane(1.0f);
393   cameraActor.SetAspectRatio(FBOSize.width / FBOSize.height);
394   cameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
395   cameraActor.SetPosition(0.0f, 0.0f, ((FBOSize.height * 0.5f) / tanf(Math::PI * 0.125f)));
396   stage.Add(cameraActor);
397
398   renderTask.SetSourceActor(imageView);
399   renderTask.SetInputEnabled(false);
400   renderTask.SetTargetFrameBuffer(framebuffer);
401   renderTask.SetCameraActor( cameraActor );
402   renderTask.SetClearColor( Color::TRANSPARENT );
403   renderTask.SetClearEnabled( true );
404   renderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
405
406   return framebuffer;
407 }
408
409 void NewWindowController::SetUpBubbleEmission( const Vector2& emitPosition, const Vector2& direction)
410 {
411   if( mNeedNewAnimation )
412   {
413     float duration = Random::Range(1.f, 1.5f);
414     mEmitAnimation = Animation::New( duration );
415     mNeedNewAnimation = false;
416     mAnimateComponentCount = 0;
417   }
418
419   mEmitter.EmitBubble( mEmitAnimation, emitPosition, direction, Vector2(10,10) );
420
421   mAnimateComponentCount++;
422
423   if( mAnimateComponentCount % 6 ==0 )
424   {
425     mEmitAnimation.Play();
426     mNeedNewAnimation = true;
427   }
428 }
429
430 Geometry NewWindowController::CreateMeshGeometry()
431 {
432   // Create vertices and specify their color
433   struct Vertex
434   {
435     Vector3 position;
436     Vector2 textureCoordinates;
437     Vector3 color;
438   };
439
440   Vertex vertexData[5] = {
441     { Vector3(  0.0f,  0.0f, 0.5f ), Vector2(0.5f, 0.5f), Vector3(1.0f, 1.0f, 1.0f) },
442     { Vector3( -0.5f, -0.5f, 0.0f ), Vector2(0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f) },
443     { Vector3(  0.5f, -0.5f, 0.0f ), Vector2(1.0f, 0.0f), Vector3(1.0f, 1.0f, 0.0f) },
444     { Vector3( -0.5f,  0.5f, 0.0f ), Vector2(0.0f, 1.0f), Vector3(0.0f, 1.0f, 0.0f) },
445     { Vector3(  0.5f,  0.5f, 0.0f ), Vector2(1.0f, 1.0f), Vector3(0.0f, 0.0f, 1.0f) }  };
446
447   Property::Map vertexFormat;
448   vertexFormat["aPosition"] = Property::VECTOR3;
449   vertexFormat["aTexCoord"] = Property::VECTOR2;
450   vertexFormat["aColor"] = Property::VECTOR3;
451   PropertyBuffer vertices = PropertyBuffer::New( vertexFormat );
452   vertices.SetData( vertexData, 5 );
453
454   // Specify all the faces
455   unsigned short indexData[12] = { 0,1,3,0,2,4,0,3,4,0,2,1 };
456
457   // Create the geometry object
458   Geometry geometry = Geometry::New();
459   geometry.AddVertexBuffer( vertices );
460   geometry.SetIndexBuffer( &indexData[0], 12 );
461
462   return geometry;
463 }
464
465 Dali::Property::Map NewWindowController::CreateColorModifierer()
466 {
467  const char* fragmentShader ( DALI_COMPOSE_SHADER (
468    precision highp float;\n
469    uniform vec3 uRGBDelta;\n
470    uniform float uIgnoreAlpha;\n
471    \n
472    varying mediump vec2 vTexCoord;\n
473    uniform sampler2D sTexture;\n
474    \n
475    float rand(vec2 co) \n
476    {\n
477      return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n}
478    \n
479    void main() {\n
480      vec4 color = texture2D(sTexture, vTexCoord); \n
481      // modify the hsv Value
482      color.rgb += uRGBDelta * rand(vTexCoord); \n
483      // if the new vale exceeds one, then decrease it
484      color.rgb -= max(color.rgb*2.0 - vec3(2.0), 0.0);\n
485      // if the new vale drops below zero, then increase it
486      color.rgb -= min(color.rgb*2.0, 0.0);\n
487      gl_FragColor = color; \n
488    }\n
489  ) );
490
491  Property::Map map;
492  Property::Map customShader;
493  customShader[ "fragmentShader" ] = fragmentShader;
494  map[ "shader" ] = customShader;
495
496  return map;
497 }
498
499 void NewWindowController::NewWindow(void)
500 {
501   PositionSize posSize(0, 0, 720, 1280);
502   gApplication.ReplaceWindow(posSize, "NewWindow"); // Generates a new window
503 }
504
505 bool NewWindowController::OnLoseContextButtonClicked( Toolkit::Button button )
506 {
507   // Add as an idle callback to avoid ProcessEvents being recursively called.
508   mApplication.AddIdle( MakeCallback( NewWindowController::NewWindow ) );
509   return true;
510 }
511
512 bool NewWindowController::OnTrackTimerTick()
513 {
514   static int time=0;
515   const float radius(250.0f);
516
517   time += EMIT_INTERVAL_IN_MS;
518   float modTime = time / TRACK_DURATION_IN_MS;
519   float angle = 2.0f*Math::PI*modTime;
520
521   Vector2 position(radius*cosf(angle), radius*-sinf(angle));
522   Vector2 aimPos(radius*2*sinf(angle), radius*2*-cosf(angle));
523   Vector2 direction = aimPos-position;
524   Vector2 stageSize = Stage::GetCurrent().GetSize();
525
526   SetUpBubbleEmission( stageSize*0.5f+position, direction );
527   SetUpBubbleEmission( stageSize*0.5f+position*0.75f, direction );
528   SetUpBubbleEmission( stageSize*0.5f+position*0.7f, direction );
529
530   return true;
531 }
532
533 void NewWindowController::OnKeyEvent(const KeyEvent& event)
534 {
535   if(event.state == KeyEvent::Down)
536   {
537     if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
538     {
539       mApplication.Quit();
540     }
541   }
542 }
543
544 void NewWindowController::OnContextLost()
545 {
546   printf("Stage reporting context loss\n");
547 }
548
549 void NewWindowController::OnContextRegained()
550 {
551   printf("Stage reporting context regain\n");
552 }
553
554 void RunTest(Application& app)
555 {
556   gNewWindowController = new NewWindowController(app);
557   app.MainLoop(Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
558 }
559
560 // Entry point for Linux & Tizen applications
561 //
562 int DALI_EXPORT_API main(int argc, char **argv)
563 {
564   gApplication = Application::New(&argc, &argv, DEMO_THEME_PATH);
565   RunTest(gApplication);
566
567   return 0;
568 }