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