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