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