2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file text-memory-profiling-example.cpp
20 * @brief Memory consumption profiling for TextLabel
24 #include <dali/dali.h>
25 #include <dali-toolkit/dali-toolkit.h>
26 #include <dali-toolkit/devel-api/controls/navigation-view/navigation-view.h>
29 #include "shared/view.h"
32 using namespace Dali::Toolkit;
40 SINGLE_COLOR_TEXT_WITH_STYLE,
41 SINGLE_COLOR_TEXT_WITH_EMOJI,
42 SINGLE_COLOR_TEXT_WITH_STYLE_EMOJI,
44 MULTI_COLOR_TEXT_WITH_STYLE,
45 MULTI_COLOR_TEXT_WITH_EMOJI,
46 MULTI_COLOR_TEXT_WITH_STYLE_EMOJI,
47 SMALL_TEXT_IN_LARGE_TEXT_LABEL,
51 std::string TEXT_TYPE_STRING[ NUMBER_OF_TYPES ] =
54 "Single color text with style",
55 "Single color text with emoji",
56 "Single color text with style and emoji",
58 "Multi color text with style",
59 "Multi color text with emoji",
60 "Multi color text with style and emoji",
61 "Small text in large Text Label"
64 const int NUMBER_OF_LABELS = 500;
66 const char* BACKGROUND_IMAGE( "" );
67 const char* TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
68 const char* BACK_IMAGE( DEMO_IMAGE_DIR "icon-change.png" );
69 const char* BACK_IMAGE_SELECTED( DEMO_IMAGE_DIR "icon-change-selected.png" );
70 const char* INDICATOR_IMAGE( DEMO_IMAGE_DIR "loading.png" );
72 } // anonymous namespace
75 * @brief The main class of the demo.
77 class TextMemoryProfilingExample : public ConnectionTracker, public Toolkit::ItemFactory
81 TextMemoryProfilingExample( Application& application )
82 : mApplication( application ),
83 mCurrentTextStyle( SINGLE_COLOR_TEXT )
85 // Connect to the Application's Init signal
86 mApplication.InitSignal().Connect( this, &TextMemoryProfilingExample::Create );
89 ~TextMemoryProfilingExample()
91 // Nothing to do here.
95 * @brief Create a text label in the given type
97 TextLabel SetupTextLabel( int type )
99 TextLabel label = TextLabel::New();
100 label.SetProperty( Actor::Property::ANCHOR_POINT, ParentOrigin::TOP_LEFT );
101 label.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
102 label.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLACK );
103 label.SetProperty( TextLabel::Property::POINT_SIZE, 12.0f );
104 Property::Map shadowMap;
105 shadowMap.Insert( "color", Color::YELLOW );
106 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
107 label.SetProperty( TextLabel::Property::ENABLE_MARKUP, true );
109 Vector2 windowSize = mApplication.GetWindow().GetSize();
110 label.SetProperty( Actor::Property::POSITION, Vector3( Random::Range( 0.0f, windowSize.x ), Random::Range( 0.0f, windowSize.y ), 0.0f) );
114 case SINGLE_COLOR_TEXT:
116 label.SetProperty( TextLabel::Property::TEXT, "A Quick Brown Fox Jumps Over The Lazy Dog" );
118 shadowMap.Insert( "offset", Vector2( 0.0f, 0.0f ) );
119 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
122 case SINGLE_COLOR_TEXT_WITH_STYLE:
124 label.SetProperty( TextLabel::Property::TEXT, "A Quick Brown Fox Jumps Over The Lazy Dog" );
126 shadowMap.Insert( "offset", Vector2( 2.0f, 2.0f ) );
127 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
130 case SINGLE_COLOR_TEXT_WITH_EMOJI:
132 label.SetProperty( TextLabel::Property::TEXT, "\xF0\x9F\x98\x81 A Quick Brown Fox Jumps Over The Lazy Dog" );
134 shadowMap.Insert( "offset", Vector2( 0.0f, 0.0f ) );
135 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
138 case SINGLE_COLOR_TEXT_WITH_STYLE_EMOJI:
140 label.SetProperty( TextLabel::Property::TEXT, "\xF0\x9F\x98\x81 A Quick Brown Fox Jumps Over The Lazy Dog" );
142 shadowMap.Insert( "offset", Vector2( 2.0f, 2.0f ) );
143 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
146 case MULTI_COLOR_TEXT:
148 label.SetProperty( TextLabel::Property::TEXT, "A <color value='cyan'>Quick Brown Fox</color> Jumps Over The <color value='yellow'>Lazy Dog</color>" );
150 shadowMap.Insert( "offset", Vector2( 0.0f, 0.0f ) );
151 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
154 case MULTI_COLOR_TEXT_WITH_STYLE:
156 label.SetProperty( TextLabel::Property::TEXT, "A <color value='cyan'>Quick Brown Fox</color> Jumps Over The <color value='yellow'>Lazy Dog</color>" );
158 shadowMap.Insert( "offset", Vector2( 2.0f, 2.0f ) );
159 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
162 case MULTI_COLOR_TEXT_WITH_EMOJI:
164 label.SetProperty( TextLabel::Property::TEXT, " \xF0\x9F\x98\x81 A <color value='cyan'>Quick Brown Fox</color> Jumps Over The <color value='yellow'>Lazy Dog</color>" );
166 shadowMap.Insert( "offset", Vector2( 0.0f, 0.0f ) );
167 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
170 case MULTI_COLOR_TEXT_WITH_STYLE_EMOJI:
172 label.SetProperty( TextLabel::Property::TEXT, " \xF0\x9F\x98\x81 A <color value='cyan'>Quick Brown Fox</color> Jumps Over The <color value='yellow'>Lazy Dog</color>" );
174 shadowMap.Insert( "offset", Vector2( 2.0f, 2.0f ) );
175 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
178 case SMALL_TEXT_IN_LARGE_TEXT_LABEL:
180 label.SetProperty( TextLabel::Property::TEXT, "A Quick Brown Fox Jumps Over The Lazy Dog" );
182 shadowMap.Insert( "offset", Vector2( 0.0f, 0.0f ) );
183 label.SetProperty( TextLabel::Property::SHADOW, shadowMap );
184 label.SetProperty( Actor::Property::SIZE, Vector2(windowSize.x, windowSize.y * 0.25f) ); // Set the text label in larger size
195 * @brief Create the main menu
197 void CreateMainMenu()
199 Vector2 windowSize = mApplication.GetWindow().GetSize();
201 mTapDetector = TapGestureDetector::New();
202 mTapDetector.DetectedSignal().Connect( this, &TextMemoryProfilingExample::OnTap );
204 // Create an item view for the main menu
205 mItemView = ItemView::New( *this );
207 mItemView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
208 mItemView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
210 mLayout = DefaultItemLayout::New( DefaultItemLayout::LIST );
211 mLayout->SetItemSize( Vector3( windowSize.width, 60.0f, 0.0f ) );
213 mItemView.AddLayout( *mLayout );
215 // Activate the layout
216 mItemView.ActivateLayout( 0, Vector3( windowSize ), 0.0f );
220 * @brief Return the number of items in the main menu
222 virtual unsigned int GetNumberOfItems()
224 return NUMBER_OF_TYPES;
228 * @brief Create new item for the main menu
230 virtual Actor NewItem( unsigned int itemId )
232 TextLabel label = TextLabel::New( TEXT_TYPE_STRING[itemId] );
233 label.SetStyleName( "BuilderLabel" );
234 label.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
236 // Hook up tap detector
237 mTapDetector.Attach( label );
243 * @brief Create text labels for memory profiling
245 void CreateTextLabels( int type )
247 // Delete any existing text labels
248 unsigned int numChildren = mLayer.GetChildCount();
250 for( unsigned int i = 0; i < numChildren; ++i )
252 mLayer.Remove( mLayer.GetChildAt( 0 ) );
255 mLayer.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
256 mLayer.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER );
257 mLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
258 mLayer.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::HEIGHT );
259 mLayer.SetProperty( Actor::Property::SIZE_MODE_FACTOR, Vector3( 0.0f, -DemoHelper::DEFAULT_VIEW_STYLE.mToolBarHeight, 0.0f ) );
261 mNavigationView.Push( mLayer );
263 // Create new text labels
264 for ( int i = 0; i < NUMBER_OF_LABELS; i++ )
266 TextLabel label = SetupTextLabel( type );
270 mTitle.SetProperty( TextLabel::Property::TEXT, "Run memps on target" );
274 * @brief One-time setup in response to Application InitSignal.
276 void Create( Application& application )
278 Window window = application.GetWindow();
280 window.KeyEventSignal().Connect(this, &TextMemoryProfilingExample::OnKeyEvent);
282 Layer contents = DemoHelper::CreateView( mApplication,
289 mTitle = DemoHelper::CreateToolBarLabel( "" );
290 mTitle.SetProperty( TextLabel::Property::TEXT, "Select the type of text" );
292 // Add title to the tool bar.
293 mToolBar.AddControl( mTitle, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Alignment::HorizontalCenter );
295 // Create a layer to contain dynamically created text labels
296 mLayer = Layer::New();
298 mIndicator = Toolkit::ImageView::New(INDICATOR_IMAGE);
299 mIndicator.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
300 mIndicator.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
301 mIndicator.SetProperty( Actor::Property::VISIBLE, false );
303 // Create a back button in the left of toolbar
304 PushButton backButton = PushButton::New();
305 backButton.SetProperty( Button::Property::UNSELECTED_BACKGROUND_VISUAL, BACK_IMAGE );
306 backButton.SetProperty( Button::Property::SELECTED_BACKGROUND_VISUAL, BACK_IMAGE_SELECTED );
307 backButton.ClickedSignal().Connect( this, &TextMemoryProfilingExample::OnBackButtonPressed );
308 backButton.SetProperty( Actor::Property::LEAVE_REQUIRED, true );
309 mToolBar.AddControl( backButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Alignment::HorizontalLeft, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
311 // Create a navigation view to navigate different types of text labels
312 mNavigationView = NavigationView::New();
313 mNavigationView.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
314 mNavigationView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
315 mNavigationView.SetBackgroundColor( Color::WHITE );
316 window.Add( mNavigationView );
319 mNavigationView.Push( mItemView );
321 mItemView.Add(mIndicator);
323 PropertyNotification notification = mIndicator.AddPropertyNotification( Actor::Property::VISIBLE, GreaterThanCondition(0.01f) );
324 notification.NotifySignal().Connect( this, &TextMemoryProfilingExample::OnIndicatorVisible );
328 * @brief Main key event handler
330 void OnKeyEvent( const KeyEvent& event )
332 if( event.state == KeyEvent::Down )
334 if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
336 ReturnToPreviousScreen();
342 * @brief Tap gesture handler
344 void OnTap( Actor actor, const TapGesture& tap )
346 mCurrentTextStyle = mItemView.GetItemId( actor );
348 // Show the loading indicator
349 mIndicator.SetProperty( Actor::Property::VISIBLE, true );
357 mAnimation = Animation::New( 0.8f );
358 mAnimation.AnimateBy( Property( mIndicator, Actor::Property::ORIENTATION ), Quaternion( Radian( Degree(180.0f) ), Vector3::ZAXIS ) );
359 mAnimation.SetLooping( true );
364 * @brief Property notification handler
366 void OnIndicatorVisible( PropertyNotification& source )
368 CreateTextLabels( mCurrentTextStyle );
370 // Hide the loading indicator
372 mIndicator.SetProperty( Actor::Property::VISIBLE, false );
376 * @brief Button signal handler
378 bool OnBackButtonPressed( Toolkit::Button button )
380 ReturnToPreviousScreen();
385 * @brief Returns to the previous screen
387 void ReturnToPreviousScreen()
389 if ( mItemView.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) )
391 // Quit the application if it is in the main menu
396 // Return to the main menu
397 mNavigationView.Pop();
399 mTitle.SetProperty( TextLabel::Property::TEXT, "Select type of text to test" );
405 Application& mApplication;
407 ItemLayoutPtr mLayout;
409 NavigationView mNavigationView;
414 ImageView mIndicator;
415 Animation mAnimation;
419 TapGestureDetector mTapDetector;
421 unsigned int mCurrentTextStyle;
424 int DALI_EXPORT_API main( int argc, char **argv )
426 Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
427 TextMemoryProfilingExample test( application );
428 application.MainLoop();