Fix for TextLabel demo styling
[platform/core/uifw/dali-demo.git] / examples / logging / logging-example.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include "shared/view.h"
19 #include <dali/dali.h>
20 #include <dali-toolkit/dali-toolkit.h>
21
22 #include <sstream>
23
24 using namespace Dali;
25
26 namespace
27 {
28 // Used to produce visually same dimensions on desktop and device builds
29 float ScalePointSize( int pointSize )
30 {
31   Dali::Vector2 dpi = Dali::Stage::GetCurrent().GetDpi();
32   float meanDpi = (dpi.height + dpi.width) * 0.5f;
33   return pointSize * meanDpi / 220.0f;
34 }
35
36 } // namespace
37
38 // Define this so that it is interchangeable
39 // "DP" stands for Device independent Pixels
40 #define DP(x) ScalePointSize(x)
41
42 //enum ButtonType
43 //{
44 //  PUSH_BUTTON,
45 //  TOGGLE_BUTTON
46 //};
47 //
48 //struct ButtonItem
49 //{
50 //  ButtonType type;
51 //  const char* name;
52 //  const char* text;
53 //  const char* altText;
54 //};
55
56 namespace
57 {
58
59 const char* const BACKGROUND_IMAGE = DALI_IMAGE_DIR "background-gradient.jpg";
60 const char* const TOOLBAR_IMAGE = DALI_IMAGE_DIR "top-bar.png";
61
62 const char* const TOOLBAR_TITLE = "Logging";
63 //const int TOOLBAR_HEIGHT = 62;
64
65 const int MARGIN_SIZE = 10;
66 const int TOP_MARGIN = 85;
67
68 const int LOGGER_GROUP_HEIGHT = 84;
69 const int LOGGER_RADIO_GROUP_HEIGHT = 200;
70
71 const int LOGGER_RADIO_SPACING = 48;
72
73 const int CONSOLE_HEIGHT = 84;
74
75 const int BUTTON_WIDTH = 200;
76 const int BUTTON_HEIGHT = LOGGER_GROUP_HEIGHT - MARGIN_SIZE * 2;
77
78 const Vector4 BACKGROUND_COLOUR( 1.0f, 1.0f, 1.0f, 0.15f );
79
80 const char* const PUSHBUTTON_PRESS_IMAGE = DALI_IMAGE_DIR "button-down.9.png";
81 const char* const PUSHBUTTON_BUTTON_IMAGE = DALI_IMAGE_DIR "button-up.9.png";
82 const char* const PUSHBUTTON_DISABLED_IMAGE = DALI_IMAGE_DIR "button-disabled.9.png";
83
84 // Button IDs
85 const char* const LOGGER_1_RADIO_ID = "LOGGER_1_RADIO";
86 const char* const LOGGER_2_RADIO_ID = "LOGGER_2_RADIO";
87 const char* const LOGGER_3_RADIO_ID = "LOGGER_3_RADIO";
88
89 const char* const FREQUENCY_1_RADIO_ID = "FREQUENCY_1_RADIO";
90 const char* const FREQUENCY_2_RADIO_ID = "FREQUENCY_2_RADIO";
91 const char* const FREQUENCY_3_RADIO_ID = "FREQUENCY_3_RADIO";
92
93 const char* const CREATE_BUTTON_ID = "CREATE_BUTTON";
94 const char* const DELETE_BUTTON_ID = "DELETE_BUTTON";
95 const char* const START_BUTTON_ID = "START_BUTTON";
96 const char* const STOP_BUTTON_ID = "STOP_BUTTON";
97 const char* const HIGH_FREQ_BUTTON_ID = "INC_FREQ_BUTTON";
98 const char* const LOW_FREQ_BUTTON_ID = "DEC_FREQ_BUTTON";
99 const char* const ENABLE_BUTTON_ID = "ENABLE_BUTTON";
100 const char* const DISABLE_BUTTON_ID = "DISABLE_BUTTON";
101 const char* const VSYNC_BUTTON_ID = "VSYNC_BUTTON";
102
103 const char* const CREATE_BUTTON_TEXT = "Create";
104 const char* const DELETE_BUTTON_TEXT = "Delete";
105 const char* const START_BUTTON_TEXT = "Start";
106 const char* const STOP_BUTTON_TEXT = "Stop";
107 const char* const ENABLE_BUTTON_TEXT = "Enable";
108 const char* const DISABLE_BUTTON_TEXT = "Disable";
109 const char* const VSYNC_BUTTON_TEXT = "Vsync";
110
111 const char* const FREQUENCY_1_RADIO_TEXT = "1";
112 const char* const FREQUENCY_2_RADIO_TEXT = "2";
113 const char* const FREQUENCY_3_RADIO_TEXT = "10";
114
115 const char* const LOGGER_TEXT = "Logger:";
116 const char* const FREQUENCY_TEXT = "Frequency (sec):";
117
118 const unsigned int NUM_LOGGERS = 3;
119
120 const unsigned int HIGH_FREQUENCY = 1;   // Seconds
121 const unsigned int MEDIUM_FREQUENCY = 2;   // Seconds
122 const unsigned int LOW_FREQUENCY = 10;   // Seconds
123 const unsigned int NUM_FREQUENCIES = 3;
124
125 }  // namespace
126
127 /**
128  * This example is a test harness for performance loggers.
129  *
130  * Press one of the create buttons to create a logger. This will output on vsync at the default frequency (2 seconds).
131  * In case nothing appears in the log, force a vsync by touching anywhere on the screen. Loggers can be deleted
132  * with the delete buttons. They can be enabled or disabled in which case logging will appear or disappear in the console
133  * respectively. To record information in a logger press the start and then stop button in succession quickly in between
134  * the time period when it would print to the console. This is necessary as the logger is cleared of information when
135  * it prints. The output will contain the smallest and largest times between start and stop recorded (minimum and maximum),
136  * the total time recorded by the logger as well as the average and standard deviation of all the times recorded. The
137  * frequency of log output can be set to high frequency (every 1 second) or low frequency (every 10 seconds).
138  */
139 class LoggingController: public ConnectionTracker
140 {
141  public:
142
143   LoggingController( Application& application )
144     : mApplication( application )
145   {
146     // Connect to the Application's Init signal
147     mApplication.InitSignal().Connect( this, &LoggingController::Create );
148   }
149
150   ~LoggingController()
151   {
152     // Nothing to do here
153   }
154
155   void Create( Application& application )
156   {
157     // The Init signal is received once (only) during the Application lifetime
158
159     DemoHelper::RequestThemeChange();
160
161     mCurrentLogger = 0;
162     mPerformanceLoggers.reserve( NUM_LOGGERS );
163     mPerformanceLoggers.resize( NUM_LOGGERS );
164
165     mPerformanceLoggerNames.reserve( NUM_LOGGERS );
166     mPerformanceLoggerNames.resize( NUM_LOGGERS );
167
168     mLoggerStates.reserve( NUM_LOGGERS );
169     mLoggerStates.resize( NUM_LOGGERS );
170
171     mLogRadioButtons.reserve( NUM_LOGGERS );
172     mLogRadioButtons.resize( NUM_LOGGERS );
173
174     mFrequencyRadioButtons.reserve( NUM_FREQUENCIES );
175     mFrequencyRadioButtons.resize( NUM_FREQUENCIES );
176
177     // Respond to key events
178     Stage::GetCurrent().KeyEventSignal().Connect(this, &LoggingController::OnKeyEvent);
179
180     // Creates a default view with a default tool bar.
181     // The view is added to the stage.
182     mContentLayer = DemoHelper::CreateView( application,
183                                             mView,
184                                             mToolBar,
185                                             BACKGROUND_IMAGE,
186                                             TOOLBAR_IMAGE,
187                                             TOOLBAR_TITLE );
188
189     Vector2 stageSize = Stage::GetCurrent().GetSize();
190
191     int yPos = TOP_MARGIN + MARGIN_SIZE;
192
193     // Logger selector radio group
194     Actor radioGroupBackground = Toolkit::CreateSolidColorActor( BACKGROUND_COLOUR );
195     radioGroupBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
196     radioGroupBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
197     radioGroupBackground.SetPosition( DP(MARGIN_SIZE), DP(yPos) );
198     radioGroupBackground.SetSize( stageSize.width - 2 * DP(MARGIN_SIZE), DP(LOGGER_RADIO_GROUP_HEIGHT) );
199     mContentLayer.Add( radioGroupBackground );
200
201     // Label
202     {
203       Toolkit::TextLabel label = Toolkit::TextLabel::New( LOGGER_TEXT );
204       label.SetParentOrigin( ParentOrigin::TOP_LEFT );
205       label.SetAnchorPoint( AnchorPoint::TOP_LEFT );
206       label.SetPosition( DP(MARGIN_SIZE), DP(MARGIN_SIZE) );
207
208       radioGroupBackground.Add( label );
209     }
210
211     // Radio group
212     Actor radioButtonsGroup = Actor::New();
213     radioButtonsGroup.SetParentOrigin( ParentOrigin::TOP_LEFT );
214     radioButtonsGroup.SetAnchorPoint( AnchorPoint::TOP_LEFT );
215     radioButtonsGroup.SetPosition( DP(MARGIN_SIZE), 0 );
216
217     radioGroupBackground.Add( radioButtonsGroup );
218
219     int radioX = 0;
220     int radioY = MARGIN_SIZE + 28;
221
222     // Radio 1
223     {
224       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New();
225       radioButton.SetName( LOGGER_1_RADIO_ID );
226       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
227       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
228       radioButton.SetPosition( DP(radioX), DP(radioY) );
229       radioButton.SetSelected( true );
230
231       radioButton.StateChangedSignal().Connect( this, &LoggingController::LoggingRadioSelect );
232
233       radioButtonsGroup.Add( radioButton );
234       mLogRadioButtons[0] = radioButton;
235     }
236
237     // Radio 2
238     {
239       radioY += LOGGER_RADIO_SPACING;
240
241       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New();
242       radioButton.SetName( LOGGER_2_RADIO_ID );
243       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
244       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
245       radioButton.SetPosition( DP(radioX), DP(radioY) );
246
247       radioButton.StateChangedSignal().Connect( this, &LoggingController::LoggingRadioSelect );
248
249       radioButtonsGroup.Add( radioButton );
250       mLogRadioButtons[1] = radioButton;
251     }
252
253     // Radio 3
254     {
255       radioY += LOGGER_RADIO_SPACING;
256
257       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New();
258       radioButton.SetName( LOGGER_3_RADIO_ID );
259       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
260       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
261       radioButton.SetPosition( DP(radioX), DP(radioY) );
262
263       radioButton.StateChangedSignal().Connect( this, &LoggingController::LoggingRadioSelect );
264
265       radioButtonsGroup.Add( radioButton );
266       mLogRadioButtons[2] = radioButton;
267     }
268
269     // Create/delete/disable group
270     yPos += LOGGER_RADIO_GROUP_HEIGHT + MARGIN_SIZE;
271
272     Actor createGroupBackground = Toolkit::CreateSolidColorActor( BACKGROUND_COLOUR );
273     createGroupBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
274     createGroupBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
275     createGroupBackground.SetPosition( DP(MARGIN_SIZE), DP(yPos) );
276     createGroupBackground.SetSize( stageSize.width - 2 * DP(MARGIN_SIZE), DP(LOGGER_GROUP_HEIGHT) );
277     mContentLayer.Add( createGroupBackground );
278
279     int buttonXDP = DP(MARGIN_SIZE);
280     int buttonWidthDP = (createGroupBackground.GetTargetSize().width - DP(MARGIN_SIZE) * 3) / 2;
281
282     {
283       Toolkit::PushButton button = Toolkit::PushButton::New();
284       button.SetName( CREATE_BUTTON_ID );
285       button.SetLabel( CREATE_BUTTON_TEXT );
286       button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
287       button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
288       button.SetPosition( buttonXDP, 0 );
289       button.SetSize( buttonWidthDP, DP(BUTTON_HEIGHT) );
290
291       button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
292       button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
293       button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
294
295       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
296
297       createGroupBackground.Add( button );
298     }
299
300     {
301       buttonXDP += DP(MARGIN_SIZE) + buttonWidthDP;
302
303       Toolkit::PushButton button = Toolkit::PushButton::New();
304       button.SetName( DELETE_BUTTON_ID );
305       button.SetLabel( DELETE_BUTTON_TEXT );
306       button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
307       button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
308       button.SetPosition( buttonXDP, 0 );
309       button.SetSize( buttonWidthDP, DP(BUTTON_HEIGHT) );
310
311       button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
312       button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
313       button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
314
315       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
316
317       createGroupBackground.Add( button );
318     }
319
320     // Start/stop group
321     yPos += LOGGER_GROUP_HEIGHT + MARGIN_SIZE;
322
323     Actor timingGroupBackground = Toolkit::CreateSolidColorActor( BACKGROUND_COLOUR );
324     timingGroupBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
325     timingGroupBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
326     timingGroupBackground.SetPosition( DP(MARGIN_SIZE), DP(yPos) );
327     timingGroupBackground.SetSize( stageSize.width - 2 * DP(MARGIN_SIZE), DP(LOGGER_GROUP_HEIGHT) );
328     mContentLayer.Add( timingGroupBackground );
329
330     buttonXDP = DP(MARGIN_SIZE);
331     buttonWidthDP = (timingGroupBackground.GetTargetSize().width - DP(MARGIN_SIZE) * 3) / 2;
332
333     {
334       Toolkit::PushButton button = Toolkit::PushButton::New();
335       button.SetName( START_BUTTON_ID );
336       button.SetLabel( START_BUTTON_TEXT );
337       button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
338       button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
339       button.SetPosition( buttonXDP, 0 );
340       button.SetSize( buttonWidthDP, DP(BUTTON_HEIGHT) );
341
342       button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
343       button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
344       button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
345
346       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
347
348       timingGroupBackground.Add( button );
349     }
350
351     {
352       buttonXDP += DP(MARGIN_SIZE) + buttonWidthDP;
353
354       Toolkit::PushButton button = Toolkit::PushButton::New();
355       button.SetName( STOP_BUTTON_ID );
356       button.SetLabel( STOP_BUTTON_TEXT );
357       button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
358       button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
359       button.SetPosition( buttonXDP, 0 );
360       button.SetSize( buttonWidthDP, DP(BUTTON_HEIGHT) );
361
362       button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
363       button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
364       button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
365
366       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
367
368       timingGroupBackground.Add( button );
369     }
370
371     // Enable/disable group
372     yPos += LOGGER_GROUP_HEIGHT + MARGIN_SIZE;
373
374     Actor enableGroupBackground = Toolkit::CreateSolidColorActor( BACKGROUND_COLOUR );
375     enableGroupBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
376     enableGroupBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
377     enableGroupBackground.SetPosition( DP(MARGIN_SIZE), DP(yPos) );
378     enableGroupBackground.SetSize( stageSize.width - 2 * DP(MARGIN_SIZE), DP(LOGGER_GROUP_HEIGHT) );
379     mContentLayer.Add( enableGroupBackground );
380
381     buttonXDP = DP(MARGIN_SIZE);
382     buttonWidthDP = (enableGroupBackground.GetTargetSize().width - DP(MARGIN_SIZE) * 3) / 2;
383
384     {
385       Toolkit::PushButton button = Toolkit::PushButton::New();
386       button.SetName( ENABLE_BUTTON_ID );
387       button.SetLabel( ENABLE_BUTTON_TEXT );
388       button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
389       button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
390       button.SetPosition( buttonXDP, 0 );
391       button.SetSize( buttonWidthDP, DP(BUTTON_HEIGHT) );
392
393       button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
394       button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
395       button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
396
397       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
398
399       enableGroupBackground.Add( button );
400     }
401
402     {
403       buttonXDP += DP(MARGIN_SIZE) + buttonWidthDP;
404
405       Toolkit::PushButton button = Toolkit::PushButton::New();
406       button.SetName( DISABLE_BUTTON_ID );
407       button.SetLabel( DISABLE_BUTTON_TEXT );
408       button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
409       button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
410       button.SetPosition( buttonXDP, 0 );
411       button.SetSize( buttonWidthDP, DP(BUTTON_HEIGHT) );
412
413       button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
414       button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
415       button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
416
417       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
418
419       enableGroupBackground.Add( button );
420     }
421
422     yPos += LOGGER_GROUP_HEIGHT + MARGIN_SIZE;
423
424     // Logger selector radio group
425     unsigned int groupHeight = LOGGER_GROUP_HEIGHT + 30;
426
427     Actor frequencyRadioGroupBackground = Toolkit::CreateSolidColorActor( BACKGROUND_COLOUR );
428     frequencyRadioGroupBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
429     frequencyRadioGroupBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
430     frequencyRadioGroupBackground.SetPosition( DP(MARGIN_SIZE), DP(yPos) );
431     frequencyRadioGroupBackground.SetSize( stageSize.width - 2 * DP(MARGIN_SIZE), DP(groupHeight) );
432     mContentLayer.Add( frequencyRadioGroupBackground );
433
434     // Label
435     {
436       Toolkit::TextLabel label = Toolkit::TextLabel::New( FREQUENCY_TEXT );
437       label.SetParentOrigin( ParentOrigin::TOP_LEFT );
438       label.SetAnchorPoint( AnchorPoint::TOP_LEFT );
439       label.SetPosition( DP(MARGIN_SIZE), DP(MARGIN_SIZE) );
440
441       frequencyRadioGroupBackground.Add( label );
442     }
443
444     // Radio group
445     Actor frequencyRadioButtonsGroup = Actor::New();
446     frequencyRadioButtonsGroup.SetParentOrigin( ParentOrigin::TOP_LEFT );
447     frequencyRadioButtonsGroup.SetAnchorPoint( AnchorPoint::TOP_LEFT );
448     frequencyRadioButtonsGroup.SetPosition( DP(MARGIN_SIZE), DP(40) );
449
450     frequencyRadioGroupBackground.Add( frequencyRadioButtonsGroup );
451
452     radioX = 0;
453     radioY = 0;
454     const int frequencyRadioWidth = 100;
455
456     // Radio 1
457     {
458       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New( FREQUENCY_1_RADIO_TEXT );
459       radioButton.SetName( FREQUENCY_1_RADIO_ID );
460       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
461       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
462       radioButton.SetPosition( DP(radioX), DP(radioY) );
463
464       radioButton.StateChangedSignal().Connect( this, &LoggingController::FrequencyRadioSelect );
465
466       frequencyRadioButtonsGroup.Add( radioButton );
467       mFrequencyRadioButtons[0] = radioButton;
468     }
469
470     // Radio 2
471     {
472       radioX += frequencyRadioWidth;
473
474       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New( FREQUENCY_2_RADIO_TEXT );
475       radioButton.SetName( FREQUENCY_2_RADIO_ID );
476       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
477       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
478       radioButton.SetPosition( DP(radioX), DP(radioY) );
479       radioButton.SetSelected( true );
480
481       radioButton.StateChangedSignal().Connect( this, &LoggingController::FrequencyRadioSelect );
482
483       frequencyRadioButtonsGroup.Add( radioButton );
484       mFrequencyRadioButtons[1] = radioButton;
485     }
486
487     // Radio 3
488     {
489       radioX += frequencyRadioWidth;
490
491       Toolkit::RadioButton radioButton = Toolkit::RadioButton::New( FREQUENCY_3_RADIO_TEXT );
492       radioButton.SetName( FREQUENCY_3_RADIO_ID );
493       radioButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
494       radioButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
495       radioButton.SetPosition( DP(radioX), DP(radioY) );
496
497       radioButton.StateChangedSignal().Connect( this, &LoggingController::FrequencyRadioSelect );
498
499       frequencyRadioButtonsGroup.Add( radioButton );
500       mFrequencyRadioButtons[2] = radioButton;
501     }
502
503     // Vsync group
504     yPos += groupHeight + MARGIN_SIZE;
505
506     Actor vsyncGroupBackground = Toolkit::CreateSolidColorActor( BACKGROUND_COLOUR );
507     vsyncGroupBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
508     vsyncGroupBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
509     vsyncGroupBackground.SetPosition( DP(MARGIN_SIZE), DP(yPos) );
510     vsyncGroupBackground.SetSize( stageSize.width - 2 * DP(MARGIN_SIZE), DP(LOGGER_GROUP_HEIGHT) );
511     mContentLayer.Add( vsyncGroupBackground );
512
513     buttonXDP = DP(MARGIN_SIZE);
514     buttonWidthDP = vsyncGroupBackground.GetTargetSize().width - DP(MARGIN_SIZE) * 2;
515
516     {
517       Toolkit::PushButton button = Toolkit::PushButton::New();
518       button.SetName( VSYNC_BUTTON_ID );
519       button.SetLabel( VSYNC_BUTTON_TEXT );
520       button.SetParentOrigin( ParentOrigin::CENTER_LEFT );
521       button.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
522       button.SetPosition( buttonXDP, 0 );
523       button.SetSize( buttonWidthDP, DP(BUTTON_HEIGHT) );
524
525       button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
526       button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
527       button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
528
529       button.ClickedSignal().Connect( this, &LoggingController::OnButtonClicked );
530
531       vsyncGroupBackground.Add( button );
532     }
533
534     WriteConsole();
535   }
536
537   void WriteConsole()
538   {
539     for( unsigned int i = 0; i < NUM_LOGGERS; ++i)
540     {
541       std::stringstream ss;
542       ss << (i + 1) << ") " << ((mPerformanceLoggers[i]) ? "Created" : "Deleted")
543          << ", " << ((mLoggerStates[i].isTiming) ? "Started" : "Stopped")
544          << ", " << ((mLoggerStates[i].isEnabled) ? "Enabled" : "Disabled");
545
546       Toolkit::TextLabel textLabel = Toolkit::TextLabel::New( ss.str() );
547
548       mLogRadioButtons[i].SetLabel( textLabel );
549     }
550   }
551
552   bool LoggingRadioSelect( Toolkit::Button button )
553   {
554     if( button.GetName() == LOGGER_1_RADIO_ID && button.IsSelected() == true )
555     {
556       mCurrentLogger = 0;
557     }
558     else if( button.GetName() == LOGGER_2_RADIO_ID && button.IsSelected() == true )
559     {
560       mCurrentLogger = 1;
561     }
562     else if( button.GetName() == LOGGER_3_RADIO_ID && button.IsSelected() == true )
563     {
564       mCurrentLogger = 2;
565     }
566
567     UpdateState();
568
569     return true;
570   }
571
572   void UpdateState()
573   {
574     DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
575     const unsigned int frequency = mLoggerStates[mCurrentLogger].frequency;
576     if( frequency == HIGH_FREQUENCY )
577     {
578       mFrequencyRadioButtons[0].SetSelected( true );
579     }
580     else if( frequency == MEDIUM_FREQUENCY )
581     {
582       mFrequencyRadioButtons[1].SetSelected( true );
583     }
584     else if( frequency == LOW_FREQUENCY )
585     {
586       mFrequencyRadioButtons[2].SetSelected( true );
587     }
588   }
589
590   bool FrequencyRadioSelect( Toolkit::Button button )
591   {
592     if( button.GetName() == FREQUENCY_1_RADIO_ID && button.IsSelected() == true )
593     {
594       if( mPerformanceLoggers[mCurrentLogger] )
595       {
596         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
597         mPerformanceLoggers[mCurrentLogger].SetLoggingFrequency( HIGH_FREQUENCY );
598
599         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
600         mLoggerStates[mCurrentLogger].frequency = HIGH_FREQUENCY;
601       }
602     }
603     else if( button.GetName() == FREQUENCY_2_RADIO_ID && button.IsSelected() == true )
604     {
605       if( mPerformanceLoggers[mCurrentLogger] )
606       {
607         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
608         mPerformanceLoggers[mCurrentLogger].SetLoggingFrequency( MEDIUM_FREQUENCY );
609
610         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
611         mLoggerStates[mCurrentLogger].frequency = MEDIUM_FREQUENCY;
612       }
613     }
614     else if( button.GetName() == FREQUENCY_3_RADIO_ID && button.IsSelected() == true )
615     {
616       if( mPerformanceLoggers[mCurrentLogger] )
617       {
618         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
619         mPerformanceLoggers[mCurrentLogger].SetLoggingFrequency( LOW_FREQUENCY );
620
621         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
622         mLoggerStates[mCurrentLogger].frequency = LOW_FREQUENCY;
623       }
624     }
625
626     return true;
627   }
628
629   void OnKeyEvent( const KeyEvent& event )
630   {
631     if( event.state == KeyEvent::Down )
632     {
633       if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
634       {
635         // Exit application when click back or escape.
636         mApplication.Quit();
637       }
638     }
639   }
640
641   bool OnButtonClicked(Toolkit::Button button)
642   {
643     if( button.GetName() == CREATE_BUTTON_ID )
644     {
645       std::stringstream ss;
646       ss << "Test logger " << (mCurrentLogger + 1);
647
648       DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggerNames.size() );
649       mPerformanceLoggerNames[mCurrentLogger] = ss.str();
650
651       DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
652       mPerformanceLoggers[mCurrentLogger] = Dali::PerformanceLogger::New( mPerformanceLoggerNames[mCurrentLogger].c_str() );
653
654       DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
655       mLoggerStates[mCurrentLogger].isTiming = false;
656       mLoggerStates[mCurrentLogger].isEnabled = true;
657       mLoggerStates[mCurrentLogger].frequency = MEDIUM_FREQUENCY;
658
659       UpdateState();
660     }
661     else if ( button.GetName() == DELETE_BUTTON_ID )
662     {
663       DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
664       mPerformanceLoggers[mCurrentLogger].Reset();
665
666       DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
667       mLoggerStates[mCurrentLogger].isTiming = false;
668       mLoggerStates[mCurrentLogger].isEnabled = true;
669       mLoggerStates[mCurrentLogger].frequency = MEDIUM_FREQUENCY;
670
671       UpdateState();
672     }
673     else if ( button.GetName() == START_BUTTON_ID )
674     {
675       if( mPerformanceLoggers[mCurrentLogger] )
676       {
677         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
678         mPerformanceLoggers[mCurrentLogger].AddMarker( Dali::PerformanceLogger::START_EVENT );
679
680         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
681         mLoggerStates[mCurrentLogger].isTiming = true;
682       }
683     }
684     else if ( button.GetName() == STOP_BUTTON_ID )
685     {
686       if( mPerformanceLoggers[mCurrentLogger] )
687       {
688         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
689         mPerformanceLoggers[mCurrentLogger].AddMarker( Dali::PerformanceLogger::END_EVENT );
690
691         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
692         mLoggerStates[mCurrentLogger].isTiming = false;
693       }
694     }
695     else if ( button.GetName() == ENABLE_BUTTON_ID )
696     {
697       if( mPerformanceLoggers[mCurrentLogger] )
698       {
699         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
700         mPerformanceLoggers[mCurrentLogger].EnableLogging( true );
701
702         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
703         mLoggerStates[mCurrentLogger].isEnabled = true;
704       }
705     }
706     else if ( button.GetName() == DISABLE_BUTTON_ID )
707     {
708       if( mPerformanceLoggers[mCurrentLogger] )
709       {
710         DALI_ASSERT_DEBUG( mCurrentLogger < mPerformanceLoggers.size() );
711         mPerformanceLoggers[mCurrentLogger].EnableLogging( false );
712
713         DALI_ASSERT_DEBUG( mCurrentLogger < mLoggerStates.size() );
714         mLoggerStates[mCurrentLogger].isEnabled = false;
715       }
716     }
717
718     WriteConsole();
719
720     return true;
721   }
722
723  private:
724
725   struct LoggerState
726   {
727     LoggerState() : frequency( 0 ), isTiming( false ), isEnabled( true ) {}
728
729     unsigned int frequency;
730     bool isTiming;
731     bool isEnabled;
732   };
733
734   Application&      mApplication;
735   Toolkit::View     mView;                   ///< The View instance.
736   Toolkit::ToolBar  mToolBar;                ///< The View's Toolbar.
737   Layer             mContentLayer;           ///< Content layer
738
739   typedef std::vector< std::string > Strings;
740   Strings mPerformanceLoggerNames;
741
742   typedef std::vector< Dali::PerformanceLogger > PerformanceLoggers;
743   PerformanceLoggers mPerformanceLoggers;
744   unsigned int mCurrentLogger;
745
746   typedef std::vector< LoggerState > LoggerStates;
747   LoggerStates mLoggerStates;
748
749   typedef std::vector< Toolkit::RadioButton > RadioButtons;
750   RadioButtons mLogRadioButtons;
751   RadioButtons mFrequencyRadioButtons;
752 };
753
754 void RunTest( Application& application )
755 {
756   LoggingController test( application );
757
758   application.MainLoop();
759 }
760
761 // Entry point for Linux & Tizen applications
762 //
763 int main( int argc, char **argv )
764 {
765   Application application = Application::New( &argc, &argv );
766
767   RunTest( application );
768
769   return 0;
770 }