Further Setter/Getter public API removal from Dali::Actor
[platform/core/uifw/dali-demo.git] / examples / image-policies / image-policies-example.cpp
1 /*
2  * Copyright (c) 2019 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
18 #include <string>
19 #include "shared/view.h"
20 #include <dali/dali.h>
21 #include <dali-toolkit/dali-toolkit.h>
22 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
23 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
24 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
25 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
26
27 using namespace Dali;
28 using namespace Toolkit;
29
30 namespace
31 {
32 const char* NEXT_BUTTON_IMAGE( DEMO_IMAGE_DIR "DarkStyleGreenArrowButton.png" );
33 const char* NEXT_BUTTON_PRESSED_IMAGE( DEMO_IMAGE_DIR "DarkStyleGreyArrowButton.png" );
34 const char* NEXT_BUTTON_DISABLED_IMAGE( DEMO_IMAGE_DIR "DarkStyleDisabledArrowButton.png" );
35 const char* OK_IMAGE_IMAGE( DEMO_IMAGE_DIR "FontStyleButton_OK_02.png" );
36 const char* LOADING_IMAGE( DEMO_IMAGE_DIR "animatedLoading.gif" );
37
38 const char* IMAGE_PATH[] = {
39     DEMO_IMAGE_DIR "gallery-small-23.jpg",
40     DEMO_IMAGE_DIR "woodEffect.jpg",
41     DEMO_IMAGE_DIR "heartsframe.9.png",
42     DEMO_IMAGE_DIR "keyboard-Landscape.jpg",
43     DEMO_IMAGE_DIR "keyboard-LandscapeCopy.jpg",
44 };
45
46 /**
47  * Enums that refer to the row in the main table view.
48  * Aids in placement of content so easy to see which type of content belongs to each row.
49  */
50 enum TableRowPlacement
51 {
52   TITLE,
53   INSTRUCTIONS,
54   IMAGE,
55   NEXT_BUTTON,
56   LOADING_STATUS,
57   NUMBER_OF_ROWS
58 };
59
60 }  // namespace
61
62 /**
63  * Examples showing the various polices of ImageVisual in use.
64  * image release polcy, image loading policy and exif data are currently demonstrated.
65  * Large images are used to cause loading time to be long enough to show differences.
66  * If hardware causes loading time improve then remote images or larger images may be required in future.
67  */
68 class ImagePolicies: public ConnectionTracker
69 {
70  public:
71
72   /**
73    * Constructor
74    */
75   ImagePolicies( Application& application )
76     : mApplication( application ),
77       mExampleIndex( 0 )
78   {
79     // Connect to the Application's Init signal
80     mApplication.InitSignal().Connect( this, &ImagePolicies::Create );
81   }
82
83   /**
84    * To prevent the next button being pressed before an Image has loaded the Button can br disabled.
85    * This function allows the control (Image view in this case) to attached to the Image loading signal
86    * and re-enable the button after Image has loaded.
87    */
88   void ResourceReadySignal( Control control )
89   {
90     mNextButton.SetProperty( Button::Property::DISABLED, false );
91   }
92
93   /**
94    * Helper function to create ImageViews used by this example, preventing the duplication of code.
95    * param[in] correctionEnabled  Set true if Exif orientation correction should be applied.
96    * param[in] loadPolicy Which LoadPolicy to use.
97    * param[in] releasePolicy Which ReleasePolicy to use
98    * param[in] synchronousLoading If the Image should be loaded synchronously
99    * param[in] imageFilenameId Which image to load, referring to the array of filenames for this example.
100    * return An ImageView with the required set up
101    */
102   ImageView CreateImageView( bool correctionEnabled, ImageVisual::LoadPolicy::Type loadPolicy, ImageVisual::ReleasePolicy::Type releasePolicy, bool synchronousLoading, unsigned int imageFilenameId )
103   {
104     ImageView imageView = ImageView::New( );
105     Property::Map imagePropertyMap;
106     imagePropertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
107     imagePropertyMap.Insert( ImageVisual::Property::URL,  IMAGE_PATH[imageFilenameId ]  );
108     imagePropertyMap.Insert( ImageVisual::Property::ORIENTATION_CORRECTION, correctionEnabled  );
109     imagePropertyMap.Insert( ImageVisual::Property::LOAD_POLICY,  loadPolicy  );
110     imagePropertyMap.Insert( ImageVisual::Property::RELEASE_POLICY,  releasePolicy  );
111     if( synchronousLoading )
112     {
113       imagePropertyMap.Insert( DevelImageVisual::Property::SYNCHRONOUS_LOADING,  true  );
114     }
115     imageView.SetProperty(ImageView::Property::IMAGE , imagePropertyMap );
116
117     imageView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
118     imageView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
119     imageView.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
120
121     return imageView;
122   }
123
124
125   /**
126    * To prevent the next button being pressed before an Image has loaded the Button can br disabled.
127    * This function will disable the next button.
128    * Connecting to the ResourceReady signal with ( ResourceReadySignal( Control control ) ) will allow enabling of the button again.
129    */
130
131   void DisableButtonWhilstLoading()
132   {
133     mNextButton.SetProperty( Button::Property::DISABLED, true );
134   }
135
136   /**
137    * Example shows loading an Image with exif orientation data but not applying automatic orientation correction
138    */
139   void OrientationCorrectionExampleNoCorrection()
140   {
141
142     mTitle.SetProperty( Toolkit::TextLabel::Property::TEXT,  "Orientation Correction" );
143     mInstructions.SetProperty( TextLabel::Property::TEXT, "Orientation Correction not applied");
144     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
145     DisableButtonWhilstLoading();
146     ImageView imageView01 = CreateImageView( false, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
147     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
148
149     mTable.AddChild( imageView01, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
150   }
151
152   /**
153    * Example shows loading an Image with exif orientation data and automatically correcting the orientation to match the exif data.
154    */
155   void OrientationCorrectionExampleWithCorrection()
156   {
157     mInstructions.SetProperty( TextLabel::Property::TEXT, "Orientation Correction applied based on Exif data, now shown in landscape");
158     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
159     DisableButtonWhilstLoading();
160     ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
161     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
162     mTable.AddChild( imageView01, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
163   }
164
165   /**
166    * Part One of the Immediate loading example, displays instructions on what will be shown and starts loading of the Immediate image before it
167    * is staged.
168    */
169   void LoadPolicyImmediateExampleInstructions()
170   {
171     mTitle.SetProperty( Toolkit::TextLabel::Property::TEXT,  "Immediate Loading Policy");
172     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
173     mInstructions.SetProperty( TextLabel::Property::TEXT, "Loading Image before staging, press next to see it in right column");
174     TableView dualImageViewTable = TableView::New( 1, 2 );
175     dualImageViewTable.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
176     dualImageViewTable.SetProperty( Dali::Actor::Property::NAME,"dualTable");
177     dualImageViewTable.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
178     dualImageViewTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
179     dualImageViewTable.SetCellPadding( Vector2( 6.0f, 0.0f ) );
180     TextLabel attached = TextLabel::New("ATTACHED loaded image \nWill appear here");
181     attached.SetProperty( TextLabel::Property::MULTI_LINE, true );
182     TextLabel immediate = TextLabel::New("IMMEDIATE loaded image \nWill appear here");
183     immediate.SetProperty( TextLabel::Property::MULTI_LINE, true );
184
185     dualImageViewTable.AddChild( attached, TableView::CellPosition( 0, 0 ) );
186     dualImageViewTable.AddChild( immediate, TableView::CellPosition( 0, 1 ) );
187     mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
188
189     DisableButtonWhilstLoading();
190     mPersistantImageView = CreateImageView( true, ImageVisual::LoadPolicy::IMMEDIATE, ImageVisual::ReleasePolicy::DESTROYED, false, 4 );
191     mPersistantImageView.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
192   }
193
194   /**
195    * Part Two of the Immediate loading example and here the Image is staged, shown to be instant (if previously step gave enough time to load).
196    */
197   void LoadPolicyImmediateExample()
198   {
199     mInstructions.SetProperty( TextLabel::Property::TEXT, "Immediate loading policy on only second column hence image load was almost instant.");
200     DisableButtonWhilstLoading();
201     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
202
203     TableView dualImageViewTable = TableView::New( 2, 2 );
204     dualImageViewTable.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
205     dualImageViewTable.SetProperty( Dali::Actor::Property::NAME,"dualTable");
206     dualImageViewTable.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
207     dualImageViewTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
208     dualImageViewTable.SetCellPadding( Vector2( 6.0f, 0.0f ) );
209
210     TextLabel attached = TextLabel::New("ATTACHED");
211     TextLabel immediate = TextLabel::New("IMMEDIATE");
212     dualImageViewTable.AddChild( attached, TableView::CellPosition( 1, 0 ) );
213     dualImageViewTable.AddChild( immediate, TableView::CellPosition( 1, 1 ) );
214     dualImageViewTable.SetFitHeight( 1 );
215
216     mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
217
218     ImageView imageView02 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
219     imageView02.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
220     dualImageViewTable.AddChild( imageView02, TableView::CellPosition( 0, 0 ) );
221     dualImageViewTable.AddChild( mPersistantImageView, TableView::CellPosition( 0, 1 ) );
222   }
223
224   /**
225    * Part one of an example of loading time when an Image is destroyed with the ReleasePolicy DESTROYED.
226    */
227   void LoadPolicyDestroyedExample()
228   {
229     mTitle.SetProperty( Toolkit::TextLabel::Property::TEXT, "Release Policy DESTROYED");
230     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
231     mPersistantImageView.Reset();
232     mInstructions.SetProperty( TextLabel::Property::TEXT, "ReleasePolicy::DESTROYED shown in first column, press next to destroy it.");
233     DisableButtonWhilstLoading();
234     TableView dualImageViewTable = TableView::New( 1, 2 );
235     dualImageViewTable.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
236     dualImageViewTable.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
237     dualImageViewTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
238     dualImageViewTable.SetCellPadding( Vector2( 6.0f, 0.0f ) );
239
240     mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
241
242     ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
243     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
244
245     dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 0 ) );
246   }
247
248   /**
249    * Part two of the Destroyed example, the image is staged again but to the second column, it shows the loading takes the same amount of time as
250    * when first loaded.
251    */
252   void LoadPolicyDestroyedExample02()
253   {
254     mInstructions.SetProperty( TextLabel::Property::TEXT, "Destroyed first image and reloaded in second column (loading took some time)");
255     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
256     DisableButtonWhilstLoading();
257     TableView dualImageViewTable = TableView::New( 1, 2 );
258     dualImageViewTable.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
259     dualImageViewTable.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
260     dualImageViewTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
261     dualImageViewTable.SetCellPadding( Vector2( 6.0f, 0.0f ) );
262
263     mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
264
265     ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
266     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
267
268     dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 1 ) );
269   }
270
271   /**
272    * Part one the second Release policy example showing detachment of a visual with the Destroyed policy and loading instantly when re-used.
273    */
274   void ReleasePolicyDestroyedExample03()
275   {
276     mTitle.SetProperty( Toolkit::TextLabel::Property::TEXT, "Detaching with DESTROYED Policy");
277     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
278     mInstructions.SetProperty( TextLabel::Property::TEXT, "Image with ReleasePolicy::DESTROYED shown in first column, Image will be detached, reusing it will be fast");
279     DisableButtonWhilstLoading();
280     TableView dualImageViewTable = TableView::New( 1, 2 );
281     dualImageViewTable.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
282     dualImageViewTable.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
283     dualImageViewTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
284     dualImageViewTable.SetCellPadding( Vector2( 6.0f, 0.0f ) );
285
286     mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
287
288     ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
289     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
290
291     dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 0 ) );
292   }
293
294   /**
295    * Second part of the second Release policy example, the detached visual is used again in the second column and shown nearly instantly.
296    */
297   void ReleasePolicyDestroyedExample04()
298   {
299     mInstructions.SetProperty( TextLabel::Property::TEXT, "Detached first image and reloaded in second column, loading should have seemed instant");
300     DisableButtonWhilstLoading();
301     TableView dualImageViewTable = TableView::DownCast( mTable.GetChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ) );
302     ImageView imageViewDetached = ImageView::DownCast( dualImageViewTable.GetChildAt( TableView::CellPosition( 0, 0 ) ) );
303     dualImageViewTable.RemoveChildAt( TableView::CellPosition( 0, 0 ) );
304
305     ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
306     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
307
308     dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 1 ) );
309   }
310
311   /**
312    * Part one of an example of loading time when an Image is detached with the ReleasePolicy Detached.
313    */
314   void ReleasePolicyDestroyedExample05()
315   {
316     mTitle.SetProperty( Toolkit::TextLabel::Property::TEXT, "Detaching with DETACHED Policy");
317     mTable.RemoveChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
318     mInstructions.SetProperty( TextLabel::Property::TEXT, "Image with ReleasePolicy::DETACHED shown in first column, will be detached and reloaded");
319     DisableButtonWhilstLoading();
320     TableView dualImageViewTable = TableView::New( 1, 2 );
321     dualImageViewTable.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
322     dualImageViewTable.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
323     dualImageViewTable.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
324     dualImageViewTable.SetCellPadding( Vector2( 6.0f, 0.0f ) );
325
326     mTable.AddChild( dualImageViewTable, TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) );
327
328     ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DETACHED, false, 3 );
329     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
330
331     dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 0 ) );
332   }
333
334   /**
335    * Part two of the Detached example, the image is staged again but to the second column, it shows the loading takes the same amount of time as
336    * when first loaded.
337    */
338   void ReleasePolicyDestroyedExample06()
339   {
340     mInstructions.SetProperty( TextLabel::Property::TEXT, "Detached first image and reloaded in second column, loading took some time");
341     DisableButtonWhilstLoading();
342     TableView dualImageViewTable = TableView::DownCast( mTable.GetChildAt( TableView::CellPosition( TableRowPlacement::IMAGE, 0 ) ) );
343     ImageView imageViewDetached = ImageView::DownCast( dualImageViewTable.GetChildAt( TableView::CellPosition( 0, 0 ) ) );
344     dualImageViewTable.RemoveChildAt( TableView::CellPosition( 0, 0 ) );
345
346     ImageView imageView01 = CreateImageView( true, ImageVisual::LoadPolicy::ATTACHED, ImageVisual::ReleasePolicy::DESTROYED, false, 3 );
347     imageView01.ResourceReadySignal().Connect( this, &ImagePolicies::ResourceReadySignal );
348
349     dualImageViewTable.AddChild( imageView01, TableView::CellPosition( 0, 1 ) );
350   }
351
352   /**
353    * Created a gradient property map that will produce a Gradient Visual
354    * param[out] gradientMap the output property map
355    */
356   void CreateGradient( Property::Map& gradientMap )
357   {
358     gradientMap.Insert( Toolkit::Visual::Property::TYPE,  Visual::GRADIENT );
359
360     Property::Array stopOffsets;
361     stopOffsets.PushBack( 0.0f );
362     stopOffsets.PushBack( 0.6f );
363     stopOffsets.PushBack( 1.0f );
364     gradientMap.Insert( GradientVisual::Property::STOP_OFFSET, stopOffsets );
365
366     Property::Array stopColors;
367     stopColors.PushBack( Vector4( 54.f, 140.f, 207.f, 223.f )/255.f );
368     stopColors.PushBack( Vector4( 54.f, 170.f, 207.f, 123.f )/255.f );
369     stopColors.PushBack( Vector4( 54.f, 189.f, 207.f, 123.f )/255.f );
370     gradientMap.Insert( GradientVisual::Property::STOP_COLOR, stopColors );
371
372     gradientMap.Insert( GradientVisual::Property::START_POSITION, Vector2(  0.5f,  0.5f ) );
373     gradientMap.Insert( GradientVisual::Property::END_POSITION,  Vector2( -0.5f, -0.5f ) );
374   }
375
376   /**
377    * Start of this example, called once when the application is initiated
378    */
379   void Create( Application& application )
380   {
381     Property::Map gradientBackground;
382     CreateGradient( gradientBackground );
383
384     // Get a handle to the stage
385     Stage stage = Stage::GetCurrent();
386
387     // Create default View.
388     Toolkit::Control view = Toolkit::Control::New();
389     view.SetProperty( Actor::Property::ANCHOR_POINT, Dali::AnchorPoint::CENTER );
390     view.SetProperty( Actor::Property::PARENT_ORIGIN, Dali::ParentOrigin::CENTER );
391     view.SetResizePolicy( Dali::ResizePolicy::FILL_TO_PARENT, Dali::Dimension::ALL_DIMENSIONS );
392     view.SetProperty( Toolkit::Control::Property::BACKGROUND , gradientBackground );
393     stage.Add( view );
394
395     // Create a table view to show a pair of buttons above each image.
396     mTable = TableView::New( TableRowPlacement::NUMBER_OF_ROWS, 1 );
397     mTable.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
398     mTable.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
399     mTable.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
400     Vector3 offset( 0.9f, 0.90f, 0.0f );
401     mTable.SetProperty( Actor::Property::SIZE_MODE_FACTOR, offset );
402     mTable.SetFitHeight( TableRowPlacement::NEXT_BUTTON );
403     mTable.SetFitHeight( TableRowPlacement::LOADING_STATUS );
404     view.Add( mTable );
405
406     // Create Next button
407     mNextButton = PushButton::New();
408     Property::Map imagePropertyMap;
409     imagePropertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
410     imagePropertyMap.Insert( ImageVisual::Property::URL, NEXT_BUTTON_IMAGE );
411     mNextButton.SetProperty( Button::Property::UNSELECTED_BACKGROUND_VISUAL, imagePropertyMap );
412     imagePropertyMap.Clear();
413     imagePropertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
414     imagePropertyMap.Insert( ImageVisual::Property::URL, NEXT_BUTTON_PRESSED_IMAGE );
415     mNextButton.SetProperty( Button::Property::SELECTED_BACKGROUND_VISUAL, imagePropertyMap );
416     mNextButton.SetProperty( Button::Property::DISABLED_UNSELECTED_BACKGROUND_VISUAL, LOADING_IMAGE );
417     mNextButton.SetProperty( Button::Property::DISABLED_SELECTED_BACKGROUND_VISUAL, NEXT_BUTTON_DISABLED_IMAGE );
418     mNextButton.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
419     mNextButton.SetProperty( Actor::Property::POSITION_Y,  -50.0f );
420     mNextButton.SetProperty( Actor::Property::SIZE, Vector2( 100.0f, 100.0f ) );
421     mNextButton.ClickedSignal().Connect( this, &ImagePolicies::ChangeImageClicked );
422     mTable.AddChild( mNextButton, TableView::CellPosition( TableRowPlacement::NEXT_BUTTON, 0 ) );
423     mTable.SetCellPadding( Vector2( 2.0f, 2.0f ) );
424
425     Stage::GetCurrent().KeyEventSignal().Connect(this, &ImagePolicies::OnKeyEvent);
426
427     // Outline Map for Labels
428     Property::Map outlineMap;
429     outlineMap["color"] = Color::BLACK;
430     outlineMap["width"] = 1.0f;
431
432     // Create Title Label
433     mTitle  = TextLabel::New("Image Polices");
434     mTitle.SetProperty( TextLabel::Property::TEXT_COLOR, Color::CYAN );
435     mTable.AddChild( mTitle, TableView::CellPosition( TableRowPlacement::TITLE, 0 ) );
436     mTable.SetFitHeight( TableRowPlacement::TITLE );
437
438     // Create Instructions label
439     mInstructions = TextLabel::New("This is an explaination of each example");
440     mInstructions.SetProperty( TextLabel::Property::MULTI_LINE, true );
441     mInstructions.SetProperty( TextLabel::Property::TEXT_COLOR, Color::WHITE );
442     mInstructions.SetProperty( TextLabel::Property::OUTLINE, outlineMap );
443     mInstructions.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
444     mTable.AddChild( mInstructions, TableView::CellPosition( TableRowPlacement::INSTRUCTIONS, 0 ) );
445     float value = mInstructions.GetProperty<float>( TextLabel::Property::PIXEL_SIZE );
446     mTable.SetFixedHeight( TableRowPlacement::INSTRUCTIONS, value * 5 ); // Space allocated for example instructions
447
448     ChangeImageClicked( mNextButton );  // Start examples ( 0 )
449   }
450
451 private:
452
453   /**
454    * Callback to the button clicked signal and starts the next example.
455    */
456   bool ChangeImageClicked( Button button )
457   {
458     switch ( mExampleIndex++ )
459     {
460       case 0 :
461       {
462         OrientationCorrectionExampleNoCorrection();
463         break;
464       }
465       case 1 :
466       {
467         OrientationCorrectionExampleWithCorrection();
468         break;
469       }
470       case 2 :
471       {
472         LoadPolicyImmediateExampleInstructions();
473         break;
474       }
475       case 3 :
476       {
477         LoadPolicyImmediateExample();
478         break;
479       }
480       case 4 :
481       {
482         LoadPolicyDestroyedExample();
483         break;
484       }
485       case 5 :
486       {
487         LoadPolicyDestroyedExample02();
488         break;
489       }
490       case 6 :
491       {
492         ReleasePolicyDestroyedExample03();
493         break;
494       }
495       case 7 :
496       {
497         ReleasePolicyDestroyedExample04();
498         break;
499       }
500       case 8 :
501       {
502         ReleasePolicyDestroyedExample05();
503         break;
504       }
505       case 9 :
506       {
507         ReleasePolicyDestroyedExample06();
508         // Change Next button to complete button ( will quit app once pressed )
509         button.SetProperty( Button::Property::UNSELECTED_BACKGROUND_VISUAL, OK_IMAGE_IMAGE );
510         button.SetProperty( Button::Property::SELECTED_BACKGROUND_VISUAL, OK_IMAGE_IMAGE );
511         break;
512       }
513       default:
514       {
515         mApplication.Quit();
516         break;
517       }
518     }
519     return true;
520   }
521
522   /**
523    * Main key event handler
524    */
525   void OnKeyEvent(const KeyEvent& event)
526   {
527     if(event.state == KeyEvent::Down)
528     {
529       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
530       {
531         mApplication.Quit();
532       }
533     }
534   }
535
536 private:
537   Application& mApplication;
538
539   TableView    mTable;
540   TextLabel    mInstructions;
541   TextLabel    mTitle;
542   PushButton   mNextButton;
543   ImageView    mPersistantImageView;
544
545   unsigned int mExampleIndex;
546 };
547
548 int DALI_EXPORT_API main( int argc, char **argv )
549 {
550   Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
551   ImagePolicies test( application );
552   application.MainLoop();
553   return 0;
554 }