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