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