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-scrolling-example.cpp
20 * @brief Shows text labels with scrolling text and allows a text label and text field control to be scrolled vertically
24 #include <dali-toolkit/dali-toolkit.h>
27 using namespace Dali::Toolkit;
31 const float WINDOW_HEIGHT_MULTIPLIER(1.5f);
32 const Vector2 BOX_SIZE(Vector2(330.0f, 80.0f));
33 const Vector2 SCROLLING_BOX_SIZE(Vector2(330.0f, 40.0f));
34 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
35 const float SCREEN_BORDER = 5.0f; // Border around screen that Popups and handles will not exceed
37 const char* ALIGNMENT_TABLE[] =
42 const unsigned int ALIGNMENT_TABLE_COUNT = sizeof(ALIGNMENT_TABLE) / sizeof(ALIGNMENT_TABLE[0]);
54 * @brief The main class of the demo.
56 class TextScrollingExample : public ConnectionTracker
59 TextScrollingExample(Application& application)
60 : mApplication(application),
61 mTargetActorPosition(),
65 // Connect to the Application's Init signal
66 mApplication.InitSignal().Connect(this, &TextScrollingExample::Create);
69 ~TextScrollingExample()
71 // Nothing to do here.
74 void CreateBox(const std::string& name, Actor& box, Actor parent, const Vector2& size)
76 box.SetProperty(Dali::Actor::Property::NAME, name);
77 box.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
78 box.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
79 box.SetResizePolicy(ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT);
80 box.SetResizePolicy(ResizePolicy::FIXED, Dimension::WIDTH);
81 box.SetProperty(Actor::Property::SIZE, Vector2(size.width, 0.f));
84 Dali::Property::Map border;
85 border.Insert(Toolkit::Visual::Property::TYPE, Visual::BORDER);
86 border.Insert(BorderVisual::Property::COLOR, Color::BLUE);
87 border.Insert(BorderVisual::Property::SIZE, 1.f);
88 box.SetProperty(Control::Property::BACKGROUND, border);
91 void CreateLabel(Actor& label, const std::string text, Actor parent, bool scrollOnStart, PushButton button)
93 label = TextLabel::New(text);
94 label.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
95 label.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT);
96 label.SetProperty(Actor::Property::PADDING, Padding(1.0f, 1.0f, 1.0f, 1.0f));
97 label.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
98 label.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
103 label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, true);
106 button.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
107 button.SetProperty(Actor::Property::SIZE, Vector2(BOX_SIZE.height, BOX_SIZE.height));
108 button.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT);
109 button.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
114 * One-time setup in response to Application InitSignal.
116 void Create(Application& application)
118 Window window = application.GetWindow();
119 mWindowSize = window.GetSize();
121 window.KeyEventSignal().Connect(this, &TextScrollingExample::OnKeyEvent);
124 Actor rootActor = Actor::New();
125 rootActor.SetProperty(Dali::Actor::Property::NAME, "rootActor");
126 rootActor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
127 rootActor.SetProperty(Actor::Property::SIZE, mWindowSize);
128 rootActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
130 window.Add(rootActor);
132 mAnimation = Animation::New(1.0f);
134 const Size mTargetActorSize(mWindowSize.width, mWindowSize.height * WINDOW_HEIGHT_MULTIPLIER);
137 Control desktop = Control::New();
138 desktop.SetBackgroundColor(Color::WHITE);
139 desktop.SetProperty(Dali::Actor::Property::NAME, "desktopActor");
140 desktop.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
141 desktop.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
142 desktop.SetProperty(Actor::Property::SIZE, mTargetActorSize);
144 rootActor.Add(desktop); // Add desktop (content) to offscreen actor
147 Control boxA = Control::New();
148 Control boxB = Control::New();
149 Control boxC = Control::New();
150 Control boxD = Control::New();
151 Control boxE = Control::New();
153 CreateBox("boxA", boxA, desktop, BOX_SIZE);
154 boxA.SetProperty(Actor::Property::POSITION, Vector3(0.0f, -500.0f, 1.0f));
157 TextField field = TextField::New();
158 field.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
159 field.SetProperty(Actor::Property::PADDING, Padding(1.0f, 1.0f, 1.0f, 1.0f));
160 field.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
161 field.SetProperty(TextField::Property::PLACEHOLDER_TEXT, "Enter Folder Name");
162 field.SetProperty(TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>(SCREEN_BORDER, SCREEN_BORDER, mWindowSize.width - SCREEN_BORDER * 2, mWindowSize.height - SCREEN_BORDER * 2));
164 boxA.SetProperty(Actor::Property::SIZE, BOX_SIZE);
166 CreateBox("boxB", boxB, desktop, SCROLLING_BOX_SIZE);
167 boxB.SetProperty(Actor::Property::POSITION, Vector3(0.0f, -400.0f, 1.0f));
168 Toolkit::PushButton scrollLargeButton = Toolkit::PushButton::New();
169 scrollLargeButton.ClickedSignal().Connect(this, &TextScrollingExample::OnButtonClickedLarge);
170 CreateLabel(mLargeLabel, "A Quick Brown Fox Jumps Over The Lazy Dog", boxB, false, scrollLargeButton);
172 CreateBox("boxC", boxC, desktop, SCROLLING_BOX_SIZE);
173 boxC.SetProperty(Actor::Property::POSITION, Vector3(0.0f, -300.0f, 1.0f));
174 Toolkit::PushButton scrollSmallButton = Toolkit::PushButton::New();
175 scrollSmallButton.ClickedSignal().Connect(this, &TextScrollingExample::OnButtonClickedSmall);
176 CreateLabel(mSmallLabel, "Hello Text", boxC, true, scrollSmallButton);
177 mSmallLabel.SetProperty(TextLabel::Property::TEXT_COLOR, Color::BLACK);
178 Property::Map shadowMap;
179 shadowMap.Insert("color", Color::CYAN);
180 shadowMap.Insert("offset", Vector2(1.0f, 1.0f));
181 mSmallLabel.SetProperty(TextLabel::Property::SHADOW, shadowMap);
183 CreateBox("boxD", boxD, desktop, SCROLLING_BOX_SIZE);
184 boxD.SetProperty(Actor::Property::POSITION, Vector3(0.0f, -200.0f, 1.0f));
185 Toolkit::PushButton scrollRtlButton = Toolkit::PushButton::New();
186 scrollRtlButton.ClickedSignal().Connect(this, &TextScrollingExample::OnButtonClickedRtl);
187 CreateLabel(mRtlLabel, "مرØبا بالعالم", boxD, true, scrollRtlButton);
188 mRtlLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_STOP_MODE, TextLabel::AutoScrollStopMode::IMMEDIATE);
189 mRtlLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_LOOP_DELAY, 0.3f);
191 CreateBox("boxE", boxE, desktop, SCROLLING_BOX_SIZE);
192 boxE.SetProperty(Actor::Property::POSITION, Vector3(0.0f, -100.0f, 1.0f));
193 Toolkit::PushButton scrollRtlLongButton = Toolkit::PushButton::New();
194 scrollRtlLongButton.ClickedSignal().Connect(this, &TextScrollingExample::OnButtonClickedRtlLong);
195 CreateLabel(mRtlLongLabel, " مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم", boxE, false, scrollRtlLongButton);
196 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_SPEED, 500);
197 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_GAP, 500);
198 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3);
199 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_STOP_MODE, TextLabel::AutoScrollStopMode::FINISH_LOOP);
201 mPanGestureDetector = PanGestureDetector::New();
202 mPanGestureDetector.DetectedSignal().Connect(this, &TextScrollingExample::OnPanGesture);
203 mPanGestureDetector.Attach(desktop);
205 Toolkit::PushButton colorButton = Toolkit::PushButton::New();
206 colorButton.SetProperty(Button::Property::TOGGLABLE, true);
207 colorButton.SetProperty(Button::Property::UNSELECTED_BACKGROUND_VISUAL, Property::Map().Add(Toolkit::Visual::Property::TYPE, Visual::COLOR).Add(ColorVisual::Property::MIX_COLOR, Color::RED));
208 colorButton.SetProperty(Button::Property::SELECTED_BACKGROUND_VISUAL, Property::Map().Add(Toolkit::Visual::Property::TYPE, Visual::COLOR).Add(ColorVisual::Property::MIX_COLOR, Color::BLACK));
209 colorButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
210 colorButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
211 colorButton.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
212 colorButton.SetProperty(Actor::Property::SIZE, Vector2(BOX_SIZE.height, BOX_SIZE.height));
213 colorButton.ClickedSignal().Connect(this, &TextScrollingExample::OnColorButtonClicked);
214 rootActor.Add(colorButton);
216 for(unsigned int i = 0; i < ALIGNMENT_TABLE_COUNT; ++i)
218 Toolkit::RadioButton alignButton = Toolkit::RadioButton::New(ALIGNMENT_TABLE[i]);
219 alignButton.ClickedSignal().Connect(this, &TextScrollingExample::OnAlignButtonClicked);
220 alignButton.SetProperty(Dali::Actor::Property::NAME, ALIGNMENT_TABLE[i]);
222 // Place first button to left aligned, second center aligned and third right aligned
223 alignButton.SetProperty(Actor::Property::ANCHOR_POINT, Vector3(i * 0.5f, 0.0f, 0.5f));
224 alignButton.SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(i * 0.5f, 0.0f, 0.5f));
226 rootActor.Add(alignButton);
230 // Set the first button as selected
231 alignButton.SetProperty(Button::Property::SELECTED, true);
236 void EnableScrolling(Labels labels)
258 label = mRtlLongLabel;
269 Property::Value value = label.GetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL);
270 if(value.Get<bool>())
272 label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, false);
276 label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, true);
281 bool OnButtonClickedSmall(Toolkit::Button button)
283 EnableScrolling(SMALL);
287 bool OnButtonClickedLarge(Toolkit::Button button)
289 EnableScrolling(LARGE);
293 bool OnButtonClickedRtl(Toolkit::Button button)
295 EnableScrolling(RTL);
299 bool OnButtonClickedRtlLong(Toolkit::Button button)
301 EnableScrolling(RTL_LONG);
305 bool OnColorButtonClicked(Toolkit::Button button)
307 Vector4 color = Color::RED;
311 color = Color::BLACK;
312 mToggleColor = false;
319 Property::Map shadowMap;
320 shadowMap.Insert("color", Color::BLACK);
321 mSmallLabel.SetProperty(TextLabel::Property::SHADOW, shadowMap);
322 mSmallLabel.SetProperty(TextLabel::Property::TEXT_COLOR, color);
323 mRtlLabel.SetProperty(TextLabel::Property::TEXT_COLOR, color);
324 mLargeLabel.SetProperty(TextLabel::Property::TEXT_COLOR, color);
325 mRtlLongLabel.SetProperty(TextLabel::Property::TEXT_COLOR, color);
330 bool OnAlignButtonClicked(Toolkit::Button button)
332 for(unsigned int index = 0; index < ALIGNMENT_TABLE_COUNT; ++index)
334 const std::string& buttonName = button.GetProperty<std::string>(Dali::Actor::Property::NAME);
335 if(buttonName == ALIGNMENT_TABLE[index])
337 mSmallLabel.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[index]);
338 mRtlLabel.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[index]);
339 mLargeLabel.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[index]);
340 mRtlLongLabel.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[index]);
349 * Main key event handler
351 void OnKeyEvent(const KeyEvent& event)
353 if(event.GetState() == KeyEvent::DOWN)
355 if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
361 if(event.GetKeyName() == "2")
363 mAnimation.AnimateTo(Property(mSmallLabel, Actor::Property::SCALE), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod(1.0f, 1.0f));
364 mAnimation.AnimateTo(Property(mLargeLabel, Actor::Property::SCALE), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod(1.0f, 1.0f));
365 mAnimation.AnimateTo(Property(mRtlLabel, Actor::Property::SCALE), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod(1.0f, 1.0f));
366 mAnimation.AnimateTo(Property(mRtlLongLabel, Actor::Property::SCALE), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod(1.0f, 1.0f));
374 void OnPanGesture(Actor actor, const PanGesture& gesture)
376 if(gesture.GetState() == GestureState::CONTINUING)
378 mTargetActorPosition.y = mTargetActorPosition.y + gesture.GetDisplacement().y;
379 mTargetActorPosition.y = std::min(mTargetActorPosition.y, -mTargetActorSize.height);
380 mTargetActorPosition.y = std::max(mTargetActorPosition.y, (mTargetActorSize.height - mWindowSize.height * 0.25f));
381 actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, mTargetActorPosition.y));
386 Application& mApplication;
387 PanGestureDetector mPanGestureDetector;
389 Vector2 mTargetActorPosition;
390 Vector2 mTargetActorSize;
393 TextLabel mLargeLabel;
394 TextLabel mSmallLabel;
396 TextLabel mRtlLongLabel;
398 Animation mAnimation;
403 int DALI_EXPORT_API main(int argc, char** argv)
405 Application application = Application::New(&argc, &argv, DEMO_THEME_PATH);
406 TextScrollingExample test(application);
407 application.MainLoop();