Changes after TouchedSignal changes
[platform/core/uifw/dali-demo.git] / examples / homescreen-benchmark / homescreen-benchmark.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 // EXTERNAL INCLUDES
19 #include <dali-toolkit/dali-toolkit.h>
20 #include <dali/devel-api/actors/actor-devel.h>
21 #include <sstream>
22 #include <iostream>
23
24 #include <dali-toolkit/devel-api/controls/table-view/table-view.h>
25 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
26
27 using namespace Dali;
28 using Dali::Toolkit::TextLabel;
29
30 namespace
31 {
32 enum IconType
33 {
34   IMAGEVIEW,
35   CHECKBOX
36 };
37
38 const char* IMAGE_PATH_PREFIX               ( DEMO_IMAGE_DIR "application-icon-" );
39 const char* IMAGE_PATH_POSTFIX              ( ".png" );
40 const int   TOTAL_ICON_DEFINITIONS          ( 147 );
41
42 const char* BACKGROUND_IMAGE                ( DEMO_IMAGE_DIR "background-3.jpg" );
43 const float PAGE_SCALE_FACTOR_X             ( 0.95f );
44 const float PAGE_SCALE_FACTOR_Y             ( 0.95f );
45 const float PAGE_DURATION_SCALE_FACTOR      ( 10.0f ); ///< Time-scale factor, larger = animation is slower
46
47 const float DEFAULT_OPT_ROW_COUNT           ( 5 );
48 const float DEFAULT_OPT_COL_COUNT           ( 4 );
49 const float DEFAULT_OPT_PAGE_COUNT          ( 10 );
50 const bool  DEFAULT_OPT_USE_TABLEVIEW       ( true );
51 const bool  DEFAULT_OPT_ICON_LABELS         ( true );
52 const IconType  DEFAULT_OPT_ICON_TYPE       ( IMAGEVIEW );
53 const bool  DEFAULT_OPT_USE_TEXT_LABEL      ( false );
54
55 // The image/label area tries to make sure the positioning will be relative to previous sibling
56 const float IMAGE_AREA                      ( 0.60f );
57 const float LABEL_AREA                      ( 0.50f );
58
59
60
61 /**
62  * Random words used as unique application names.
63  * The number matches the value of TOTAL_ICON_DEFINITIONS.
64  */
65 const char* DEMO_APPS_NAMES[] =
66 {
67   "Achdyer",   "Aughm",       "Cerl",       "Daril",      "Emgha",     "Ghatan",     "Issum",     "Lertan",    "Mosorrad",
68   "Achtortor", "Aughtheryer", "Certin",     "Darpban",    "Emiton",    "Gibanis",    "Itenthbel", "Liadem",    "Mosraye",
69   "Ackirlor",  "Awitad",      "Checerper",  "Dasrad",     "Emworeng",  "Hatdyn",     "K'ackves",  "Liathar",   "Mosth",
70   "Ackptin",   "Banengon",    "Chegit",     "Deeqskel",   "Endnys",    "Heesban",    "Kagdra",    "Liephden",  "Neabar",
71   "Aighte",    "Banhinat",    "Cheirat",    "Delurnther", "Enessray",  "Hesub",      "Kalbankim", "Likellor",  "Neerdem",
72   "Akala",     "Belrisash",   "Che'rak",    "Denalda",    "Engyer",    "Hinkelenth", "Kal'enda",  "Loightmos", "Nichqua",
73   "Alealdny",  "Bilorm",      "Cheves",     "Derynkel",   "En'rady",   "Hirryer",    "Kimest",    "Loromum",   "Nudraough",
74   "Angash",    "Bleustcer",   "Chiperath",  "Deurnos",    "Enthount",  "Ideinta",    "Kimundeng", "Lorr",      "Nuyim",
75   "Anglor",    "Bliagelor",   "Chralerack", "Doyaryke",   "Enundem",   "Im'eld",     "Koachlor",  "Lortas",    "Nycha",
76   "Anveraugh", "Blorynton",   "Chram",      "Draithon",   "Essina",    "Ina'ir",     "Kuren",     "Lyerr",     "Nyia",
77   "Ardangas",  "Booten",      "Clyimen",    "Drantess",   "Faughald",  "Ing'moro",   "Kygver",    "Maustbur",  "Nyjac",
78   "Ardug",     "Bripolqua",   "Coqueang",   "Druardny",   "Fiummos",   "Ingormess",  "Kyning",    "Menvor",    "Nystondar",
79   "Ardworu",   "Bryray",      "Craennther", "Dynsaytor",  "Garash",    "Ingshy",     "Laiyach",   "Meusten",   "Okine",
80   "Ascerald",  "Burust",      "Cykage",     "Dytinris",   "Garight",   "Issath",     "Lasuzu",    "Mirodskel", "Oldit",
81   "Ash'ach",   "Cataikel",    "Dalek",      "Eeni",       "Garrynath", "Issendris",  "Lekew",     "Morhatrod", "Om'mose",
82   "Athiund",   "Cerilwar",    "Darhkel",    "Elmryn",     "Ghalora",   "Issey",      "Lerengom",  "Moserbel",  "Onye",
83   "Ososrak",   "Pecertin",    "Perrd"
84 };
85
86 // This code comes from command-line-options.cpp. the reason it's here is to
87 // keep consistent the extra-help formatting when '--help' used.
88 void PrintHelp( const char * const opt, const char * const optDescription)
89 {
90   const std::ios_base::fmtflags flags = std::cout.flags();
91   std::cout << std::left << "  -";
92   std::cout.width( 18 );
93   std::cout << opt;
94   std::cout << optDescription;
95   std::cout << std::endl;
96   std::cout.flags( flags );
97 }
98
99 }
100
101 /**
102  * @brief This example is a benchmark that mimics the paged applications list of the homescreen application.
103  */
104 class HomescreenBenchmark : public ConnectionTracker
105 {
106 public:
107
108   // Config structure passed to the constructor. It makes easier to increase number
109   // of setup parameters if needed.
110   struct Config
111   {
112     Config() :
113       mRows( DEFAULT_OPT_ROW_COUNT ),
114       mCols( DEFAULT_OPT_COL_COUNT ),
115       mPageCount( DEFAULT_OPT_PAGE_COUNT ),
116       mTableViewEnabled( DEFAULT_OPT_USE_TABLEVIEW ),
117       mIconLabelsEnabled( DEFAULT_OPT_ICON_LABELS ),
118       mIconType( DEFAULT_OPT_ICON_TYPE ),
119       mUseTextLabel( DEFAULT_OPT_USE_TEXT_LABEL )
120     {
121     }
122
123     int  mRows;
124     int  mCols;
125     int  mPageCount;
126     bool mTableViewEnabled;
127     bool mIconLabelsEnabled;
128     IconType mIconType;
129     bool mUseTextLabel;
130   };
131
132   // animation script data
133   struct ScriptData
134   {
135     ScriptData( int pages, float duration, bool flick )
136     : mPages( pages ),
137       mDuration( duration ),
138       mFlick( flick )
139     {
140     }
141
142     int   mPages;    ///< Number of pages to scroll
143     float mDuration; ///< Duration
144     bool  mFlick;    ///< Use flick or 'one-by-one' scroll
145   };
146
147   HomescreenBenchmark( Application& application, const Config& config )
148   : mApplication( application ),
149     mConfig( config ),
150     mScriptFrame( 0 ),
151     mCurrentPage( 0 )
152   {
153     // Connect to the Application's Init signal.
154     mApplication.InitSignal().Connect( this, &HomescreenBenchmark::Create );
155   }
156
157   ~HomescreenBenchmark()
158   {
159   }
160
161   // The Init signal is received once (only) during the Application lifetime.
162   void Create( Application& application )
163   {
164     // Create benchmark script
165     CreateScript();
166
167     // Get a handle to the window
168     Window window = application.GetWindow();
169
170     mScrollParent = Actor::New();
171     mScrollParent.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
172     mScrollParent.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
173     mScrollParent.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
174
175     // create background
176     Toolkit::ImageView background = Toolkit::ImageView::New( BACKGROUND_IMAGE );
177     window.Add( background );
178     background.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
179     background.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
180     background.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
181
182     PopulatePages();
183
184     window.Add( mScrollParent );
185
186     // Respond to a click anywhere on the window.
187     window.GetRootLayer().TouchedSignal().Connect( this, &HomescreenBenchmark::OnTouch );
188
189     // Respond to key events
190     window.KeyEventSignal().Connect( this, &HomescreenBenchmark::OnKeyEvent );
191   }
192
193   bool OnTouch( Actor actor, const TouchEvent& touch )
194   {
195     // Quit the application.
196     mApplication.Quit();
197     return true;
198   }
199
200   Actor AddPage()
201   {
202     // Create root page actor.
203     Toolkit::Control pageActor;
204
205     if( mConfig.mTableViewEnabled )
206     {
207       pageActor = Toolkit::TableView::New( mConfig.mRows, mConfig.mCols );
208     }
209     else
210     {
211       pageActor = Toolkit::Control::New();
212     }
213
214     pageActor.SetBackgroundColor( Vector4( 0.0f, 0.0f, 0.0f, 0.5f ) );
215     pageActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
216     pageActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
217     pageActor.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
218     pageActor.SetProperty( Actor::Property::SIZE_MODE_FACTOR, Vector3( PAGE_SCALE_FACTOR_X, PAGE_SCALE_FACTOR_Y, 1.0f ) );
219     return pageActor;
220   }
221
222   Toolkit::ImageView CreateImageView( const unsigned int currentIconIndex )
223   {
224     // Create empty image to avoid early renderer creation
225     Toolkit::ImageView imageView = Toolkit::ImageView::New();
226
227     // Auto-generate the Icons image URL.
228     Property::Map map;
229     std::stringstream imagePath;
230     imagePath << IMAGE_PATH_PREFIX << currentIconIndex << IMAGE_PATH_POSTFIX;
231     map[ Dali::Toolkit::ImageVisual::Property::URL ] = imagePath.str();
232
233     imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, map );
234     imageView.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
235     imageView.SetProperty( Actor::Property::SIZE_SCALE_POLICY, SizeScalePolicy::FIT_WITH_ASPECT_RATIO );
236     imageView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
237     imageView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
238     imageView.SetProperty( Actor::Property::SIZE_MODE_FACTOR, Vector3( IMAGE_AREA, IMAGE_AREA, 1.0f ) );
239
240     return imageView;
241   }
242
243   Toolkit::Button CreateButton( const unsigned int currentIconIndex )
244   {
245     Toolkit::CheckBoxButton button = Toolkit::CheckBoxButton::New();
246     button.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
247     button.SetProperty( Actor::Property::SIZE_SCALE_POLICY, SizeScalePolicy::FIT_WITH_ASPECT_RATIO );
248     button.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
249     button.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
250     button.SetProperty( Toolkit::Button::Property::SELECTED, ( currentIconIndex % 2 == 0 ) ); // Select half the button
251
252     return button;
253   }
254
255   void AddIconsToPage( Actor page, bool useTextLabel )
256   {
257     Window window = mApplication.GetWindow();
258
259     Size windowSize( window.GetSize() );
260     const float scaledHeight = windowSize.y * PAGE_SCALE_FACTOR_Y;
261     const float scaledWidth = windowSize.x * PAGE_SCALE_FACTOR_X;
262     const float PADDING = windowSize.y / 64.0f;
263     const float ROW_HEIGHT = ( scaledHeight - (PADDING*2.0f) ) / static_cast<float>( mConfig.mRows );
264     const float COL_WIDTH = ( scaledWidth - (PADDING*2.0f) ) / static_cast<float>( mConfig.mCols );
265
266     Vector2 dpi = window.GetDpi();
267
268     static int currentIconIndex = 0;
269
270     for( int y = 0; y < mConfig.mRows; ++y )
271     {
272       for( int x = 0; x < mConfig.mCols; ++x )
273       {
274         // Create parent icon view
275         Toolkit::Control iconView = Toolkit::Control::New();
276         iconView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
277         iconView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
278
279         if( !mConfig.mTableViewEnabled )
280         {
281           float rowX = x * COL_WIDTH + PADDING;
282           float rowY = y * ROW_HEIGHT + PADDING;
283           iconView.SetProperty( Actor::Property::SIZE, Vector3( COL_WIDTH, ROW_HEIGHT, 1.0f ) );
284           iconView.SetProperty( Actor::Property::POSITION, Vector3( rowX, rowY, 0.0f ) );
285         }
286         else
287         {
288           iconView.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
289           iconView.SetProperty( Actor::Property::SIZE_SCALE_POLICY, SizeScalePolicy::FIT_WITH_ASPECT_RATIO );
290         }
291
292         Actor icon;
293
294         switch( mConfig.mIconType )
295         {
296           case CHECKBOX:
297           {
298             icon = CreateButton( currentIconIndex );
299             break;
300           }
301           case IMAGEVIEW:
302           {
303             icon = CreateImageView( currentIconIndex );
304             break;
305           }
306         }
307
308         if( mConfig.mIconLabelsEnabled )
309         {
310           // create label
311           if( useTextLabel )
312           {
313             Toolkit::TextLabel textLabel = Toolkit::TextLabel::New( DEMO_APPS_NAMES[currentIconIndex] );
314             textLabel.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER );
315             textLabel.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
316             textLabel.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
317             textLabel.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) ); // White.
318             textLabel.SetProperty( Toolkit::TextLabel::Property::POINT_SIZE, ( ( static_cast<float>( ROW_HEIGHT * LABEL_AREA ) * 72.0f )  / dpi.y ) * 0.25f );
319             textLabel.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
320             textLabel.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "TOP" );
321             icon.Add( textLabel );
322           }
323           else
324           {
325             Property::Map map;
326             map.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT ).
327               Add( Toolkit::TextVisual::Property::TEXT, DEMO_APPS_NAMES[currentIconIndex] ).
328               Add( Toolkit::TextVisual::Property::TEXT_COLOR, Color::WHITE ).
329               Add( Toolkit::TextVisual::Property::POINT_SIZE, ( ( static_cast<float>( ROW_HEIGHT * LABEL_AREA ) * 72.0f )  / dpi.y ) * 0.25f ).
330               Add( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, "CENTER" ).
331               Add( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, "TOP" );
332
333             Toolkit::Control control = Toolkit::Control::New();
334             control.SetProperty( Toolkit::Control::Property::BACKGROUND, map );
335             control.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER );
336             control.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
337             icon.Add( control );
338           }
339         }
340
341         iconView.Add( icon );
342         page.Add( iconView );
343
344         // We only have images and names for a certain number of icons.
345         // Wrap around if we have used them all.
346         if( ++currentIconIndex == TOTAL_ICON_DEFINITIONS )
347         {
348           currentIconIndex = 0;
349         }
350       }
351     }
352   }
353
354   void CreateScript()
355   {
356     const int lastPage = mConfig.mPageCount - 1;
357     const int halfA = lastPage / 2;
358     const int halfB = lastPage / 2 + lastPage % 2;
359     mScriptFrameData.push_back( ScriptData( lastPage,  1.5f, true  ) );
360     mScriptFrameData.push_back( ScriptData( -lastPage, 1.5f, true  ) );
361     mScriptFrameData.push_back( ScriptData( halfA,     1.0f, true  ) );
362     mScriptFrameData.push_back( ScriptData( halfB,     1.0f, true  ) );
363     mScriptFrameData.push_back( ScriptData( -lastPage, 0.5f, false ) );
364     mScriptFrameData.push_back( ScriptData( halfA,     0.5f, false ) );
365     mScriptFrameData.push_back( ScriptData( halfB,     1.0f, true  ) );
366     mScriptFrameData.push_back( ScriptData( -halfA,    1.0f, true  ) );
367     mScriptFrameData.push_back( ScriptData( 1,         0.1f, true  ) );
368     mScriptFrameData.push_back( ScriptData( -1,        0.1f, true  ) );
369     mScriptFrameData.push_back( ScriptData( 1,         0.1f, true  ) );
370     mScriptFrameData.push_back( ScriptData( -1,        0.1f, true  ) );
371     mScriptFrameData.push_back( ScriptData( 1,         0.1f, true  ) );
372     mScriptFrameData.push_back( ScriptData( -1,        0.1f, true  ) );
373     mScriptFrameData.push_back( ScriptData( halfA,     1.0f, true  ) );
374   }
375
376   void PopulatePages()
377   {
378     Vector3 windowSize( mApplication.GetWindow().GetSize() );
379
380     for( int i = 0; i < mConfig.mPageCount; ++i )
381     {
382       // Create page.
383       Actor page = AddPage();
384
385       // Populate icons.
386       AddIconsToPage( page, mConfig.mUseTextLabel );
387
388       // Move page 'a little bit up'.
389       page.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
390       page.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
391       page.SetProperty( Actor::Property::POSITION, Vector3( windowSize.x * i, 0.0f, 0.0f ) );
392       mScrollParent.Add( page );
393     }
394
395     mScrollParent.SetProperty( Actor::Property::OPACITY, 1.0f );
396     mScrollParent.SetProperty( Actor::Property::SCALE, Vector3::ONE );
397
398     // Fade in.
399     ShowAnimation();
400   }
401
402   void ShowAnimation()
403   {
404     mShowAnimation = Animation::New( 1.0f );
405     mShowAnimation.AnimateTo( Property( mScrollParent, Actor::Property::COLOR_ALPHA ), 1.0f, AlphaFunction::EASE_IN_OUT );
406     mShowAnimation.AnimateTo( Property( mScrollParent, Actor::Property::SCALE ), Vector3::ONE, AlphaFunction::EASE_IN_OUT );
407     mShowAnimation.FinishedSignal().Connect( this, &HomescreenBenchmark::OnAnimationEnd );
408     mShowAnimation.Play();
409   }
410
411   void ScrollPages(int pages, float duration, bool flick)
412   {
413     duration *= PAGE_DURATION_SCALE_FACTOR;
414     Vector3 windowSize( mApplication.GetWindow().GetSize() );
415     mScrollAnimation = Animation::New( duration );
416     if( flick )
417     {
418       mScrollAnimation.AnimateBy( Property( mScrollParent, Actor::Property::POSITION ), Vector3( -windowSize.x * pages, 0.0f, 0.0f ), AlphaFunction::EASE_IN_OUT );
419     }
420     else
421     {
422       int totalPages = abs( pages );
423       for( int i = 0; i < totalPages; ++i )
424       {
425         mScrollAnimation.AnimateBy( Property( mScrollParent, Actor::Property::POSITION ), Vector3( pages < 0 ? windowSize.x : -windowSize.x, 0.0f, 0.0f ), AlphaFunction::EASE_IN_OUT, TimePeriod( duration * i, duration ) );
426       }
427     }
428     mScrollAnimation.FinishedSignal().Connect( this, &HomescreenBenchmark::OnAnimationEnd );
429     mScrollAnimation.Play();
430     mCurrentPage += pages;
431   }
432
433   void OnAnimationEnd( Animation& source )
434   {
435     if( mScriptFrame < mScriptFrameData.size() )
436     {
437       ScriptData& frame = mScriptFrameData[mScriptFrame];
438       ScrollPages( frame.mPages, frame.mDuration, frame.mFlick );
439       ++mScriptFrame;
440     }
441     else
442     {
443       mApplication.Quit();
444     }
445   }
446
447   void OnKeyEvent( const KeyEvent& event )
448   {
449     if( event.GetState() == KeyEvent::DOWN )
450     {
451       if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
452       {
453         mApplication.Quit();
454       }
455     }
456   }
457
458 private:
459
460   Application&                mApplication;
461   Actor                       mScrollParent;
462   Animation                   mShowAnimation;
463   Animation                   mScrollAnimation;
464   Config                      mConfig;
465   std::vector<ScriptData>     mScriptFrameData;
466   size_t                      mScriptFrame;
467   int                         mCurrentPage;
468 };
469
470 int DALI_EXPORT_API main( int argc, char **argv )
471 {
472   // Default settings.
473   HomescreenBenchmark::Config config;
474
475   bool printHelpAndExit = false;
476
477   for( int i = 1 ; i < argc; ++i )
478   {
479     std::string arg( argv[i] );
480     if( arg.compare( 0, 2, "-r" ) == 0 )
481     {
482       config.mRows = atoi( arg.substr( 2 ).c_str() );
483     }
484     else if( arg.compare( 0, 2, "-c" ) == 0 )
485     {
486       config.mCols = atoi( arg.substr( 2 ).c_str() );
487     }
488     else if( arg.compare( 0, 2, "-p" ) == 0 )
489     {
490       config.mPageCount = atoi( arg.substr( 2 ).c_str() );
491     }
492     else if( arg.compare( "--disable-tableview" ) == 0 )
493     {
494       config.mTableViewEnabled = false;
495     }
496     else if( arg.compare( "--disable-icon-labels" ) == 0 )
497     {
498       config.mIconLabelsEnabled = false;
499     }
500     else if( arg.compare( "--use-checkbox" ) == 0 )
501     {
502       config.mIconType = CHECKBOX;
503     }
504     else if( arg.compare("--use-text-label" ) == 0)
505     {
506       config.mUseTextLabel = true;
507     }
508     else if( arg.compare( "--help" ) == 0 )
509     {
510       printHelpAndExit = true;
511     }
512   }
513
514   Application application = Application::New( &argc, &argv );
515   HomescreenBenchmark test( application, config );
516
517   if( printHelpAndExit )
518   {
519     PrintHelp( "c<num>",               " Number of columns" );
520     PrintHelp( "r<num>",               " Number of rows" );
521     PrintHelp( "p<num>",               " Number of pages ( must be greater than 1 )" );
522     PrintHelp( "-disable-tableview",   " Disables the use of TableView for layouting" );
523     PrintHelp( "-disable-icon-labels", " Disables labels for each icon" );
524     PrintHelp( "-use-checkbox",        " Uses checkboxes for icons" );
525     PrintHelp( "-use-text-label",      " Uses TextLabel instead of a TextVisual" );
526     return 0;
527   }
528
529   application.MainLoop();
530
531   return 0;
532 }