Added ELLIPSIS_MODE to automatically support auto scroll.
In case of Ellipsize::AUTO_SCROLL,
when the text exceeds the layout, it will automatically scroll with animation.
Below are some limitations:
Ellipsize::AUTO_SCROLL shares the properties of AUTO_SCROLL Animation:
AUTO_SCROLL_SPEED, AUTO_SCROLL_LOOP_COUNT, AUTO_SCROLL_GAP, AUTO_SCROLL_LOOP_DELAY
Ellipsize::AUTO_SCROLL forces the setting of AUTO_SCROLL_STOP_MODE to IMMEDIATE.
To dynamically turn off Ellipsize::AUTO_SCROLL, set Ellipsize::TRUNCATE.
Cannot be used simultaneously with ENABLE_AUTO_SCROLL.
Change-Id: I0473f774505378273a05f07f6ee864ecae79abff
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
DALI_TEST_EQUALS(expectedHeight, gAsyncTextRenderedHeight, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
DALI_TEST_EQUALS(true, label.GetProperty<bool>(DevelTextLabel::Property::MANUAL_RENDERED), TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliToolkitTextLabelAsyncTextEllipsisMode(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextLabelAsyncTextEllipsisMode");
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE);
+
+ // Set the dpi of AsyncTextLoader and FontClient to be identical.
+ TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+ // Set short text.
+ TextLabel label = TextLabel::New("H");
+ DALI_TEST_CHECK(label);
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE);
+
+ application.GetScene().Add(label);
+
+ label.SetProperty(DevelTextLabel::Property::RENDER_MODE, DevelTextLabel::Render::ASYNC_AUTO);
+ label.SetProperty(TextLabel::Property::ELLIPSIS, true);
+ label.SetProperty(TextLabel::Property::MULTI_LINE, false);
+ label.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ label.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ label.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 40.f));
+
+ // Set ellipsis mode to auto scroll, but auto scroll does not work because the text is short.
+ label.SetProperty(DevelTextLabel::Property::ELLIPSIS_MODE, Toolkit::DevelText::Ellipsize::AUTO_SCROLL);
+ try
+ {
+ application.SendNotification();
+ application.Render();
+ }
+ catch(...)
+ {
+ tet_result(TET_FAIL);
+ }
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, ASYNC_TEXT_THREAD_TIMEOUT), true, TEST_LOCATION);
+ DALI_TEST_CHECK(!label.GetProperty<bool>(DevelTextLabel::Property::IS_SCROLLING));
+
+ // Set long text to scroll.
+ label.SetProperty(TextLabel::Property::TEXT, "Hello world Hello world Hello world Hello world");
+ label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, false);
+ try
+ {
+ application.SendNotification();
+ application.Render();
+ }
+ catch(...)
+ {
+ tet_result(TET_FAIL);
+ }
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, ASYNC_TEXT_THREAD_TIMEOUT), true, TEST_LOCATION);
+ DALI_TEST_CHECK(label.GetProperty<bool>(DevelTextLabel::Property::IS_SCROLLING));
+
END_TEST;
}
\ No newline at end of file
const char* const PROPERTY_NAME_RENDER_MODE = "renderMode";
const char* const PROPERTY_NAME_MANUAL_RENDERED = "manualRendered";
const char* const PROPERTY_NAME_ASYNC_LINE_COUNT = "asyncLineCount";
+const char* const PROPERTY_NAME_ELLIPSIS_MODE = "ellipsisMode";
const std::string DEFAULT_FONT_DIR("/resources/fonts");
const unsigned int EMOJI_FONT_SIZE = 3840u; // 60 * 64
DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_RENDER_MODE) == DevelTextLabel::Property::RENDER_MODE);
DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_MANUAL_RENDERED) == DevelTextLabel::Property::MANUAL_RENDERED);
DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_ASYNC_LINE_COUNT) == DevelTextLabel::Property::ASYNC_LINE_COUNT);
+ DALI_TEST_CHECK(label.GetPropertyIndex(PROPERTY_NAME_ELLIPSIS_MODE) == DevelTextLabel::Property::ELLIPSIS_MODE);
END_TEST;
}
label.SetProperty(DevelTextLabel::Property::RENDER_MODE, 3);
DALI_TEST_EQUALS(label.GetProperty<int>(DevelTextLabel::Property::RENDER_MODE), static_cast<int>(DevelTextLabel::Render::SYNC), TEST_LOCATION);
+ // Check ellipsis mode property
+ label.SetProperty(DevelTextLabel::Property::ELLIPSIS_MODE, Toolkit::DevelText::Ellipsize::TRUNCATE);
+ DALI_TEST_EQUALS(label.GetProperty<int>(DevelTextLabel::Property::ELLIPSIS_MODE), static_cast<int>(Toolkit::DevelText::Ellipsize::TRUNCATE), TEST_LOCATION);
+
+ label.SetProperty(DevelTextLabel::Property::ELLIPSIS_MODE, Toolkit::DevelText::Ellipsize::AUTO_SCROLL);
+ DALI_TEST_EQUALS(label.GetProperty<int>(DevelTextLabel::Property::ELLIPSIS_MODE), static_cast<int>(Toolkit::DevelText::Ellipsize::AUTO_SCROLL), TEST_LOCATION);
+
application.SendNotification();
application.Render();
END_TEST;
}
+int UtcDaliToolkitTextlabelEllipsisMode(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextlabelEllipsisMode");
+
+ // Set short text.
+ TextLabel label = TextLabel::New("H");
+ DALI_TEST_CHECK(label);
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult(GL_FRAMEBUFFER_COMPLETE);
+
+ application.GetScene().Add(label);
+
+ label.SetProperty(TextLabel::Property::ELLIPSIS, true);
+ label.SetProperty(TextLabel::Property::MULTI_LINE, false);
+ label.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ label.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ label.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 40.f));
+
+ // Set ellipsis mode to auto scroll, but auto scroll does not work because the text is short.
+ label.SetProperty(DevelTextLabel::Property::ELLIPSIS_MODE, Toolkit::DevelText::Ellipsize::AUTO_SCROLL);
+
+ // When ellipsis mode is auto scroll, enable auto scroll does not work.
+ label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, true);
+ try
+ {
+ application.SendNotification();
+ application.Render();
+ }
+ catch(...)
+ {
+ tet_result(TET_FAIL);
+ }
+ DALI_TEST_CHECK(!label.GetProperty<bool>(TextLabel::Property::ENABLE_AUTO_SCROLL));
+ DALI_TEST_CHECK(!label.GetProperty<bool>(DevelTextLabel::Property::IS_SCROLLING));
+
+ // Set long text to scroll.
+ label.SetProperty(TextLabel::Property::TEXT, "Hello world Hello world Hello world Hello world");
+ label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, false);
+ try
+ {
+ application.SendNotification();
+ application.Render();
+ }
+ catch(...)
+ {
+ tet_result(TET_FAIL);
+ }
+ DALI_TEST_CHECK(label.GetProperty<bool>(DevelTextLabel::Property::IS_SCROLLING));
+
+ // Auto scroll does not work in multi line.
+ label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+ label.SetProperty(DevelTextLabel::Property::ELLIPSIS_MODE, Toolkit::DevelText::Ellipsize::TRUNCATE);
+ try
+ {
+ application.SendNotification();
+ application.Render();
+ }
+ catch(...)
+ {
+ tet_result(TET_FAIL);
+ }
+ DALI_TEST_CHECK(!label.GetProperty<bool>(DevelTextLabel::Property::IS_SCROLLING));
+
+ END_TEST;
+}
+
int UtcDaliToolkitTextlabelTextWrapMode(void)
{
ToolkitTestApplication application;
* @note This property is read-only.
*/
ASYNC_LINE_COUNT,
+
+ /**
+ * @brief Ellipsis mode.
+ * @details Name "ellipsisMode", type Property::INTERGER.
+ */
+ ELLIPSIS_MODE,
+
+ /**
+ * @brief Whether the auto scroll animation is playing or not.
+ * @details Name "isScrolling", type Property::BOOLEAN.
+ * @note This property is read-only.
+ */
+ IS_SCROLLING,
};
} // namespace Property
} // namespace EllipsisPosition
+namespace Ellipsize
+{
+/**
+ * @brief Enumerations specifying ellipsize mode.
+ * @see EllipsisMode.
+ */
+enum Mode
+{
+ TRUNCATE = 0, ///< If the text exceeds the layout, it will be truncated with an ellipsis.
+ AUTO_SCROLL ///< If the text exceeds the layout, it will be auto scroll animated.
+};
+
+} // namespace EllipsisMode
+
} // namespace DevelText
} // namespace Toolkit
DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "renderMode", INTEGER, RENDER_MODE )
DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "manualRendered", BOOLEAN, MANUAL_RENDERED )
DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "asyncLineCount", INTEGER, ASYNC_LINE_COUNT )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "ellipsisMode", INTEGER, ELLIPSIS_MODE )
+DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "isScrolling", BOOLEAN, IS_SCROLLING )
DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, TextLabel, "textColor", Color::BLACK, TEXT_COLOR )
DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit, TextLabel, "textColorRed", TEXT_COLOR_RED, TEXT_COLOR, 0)
}
case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
{
- const bool enableAutoScroll = value.Get<bool>();
- impl.mLastAutoScrollEnabled = enableAutoScroll;
- // If request to auto scroll is the same as current state then do nothing.
- if(enableAutoScroll != impl.mController->IsAutoScrollEnabled())
+ if(impl.mController->IsTextElideEnabled() && impl.mController->GetEllipsisMode() == DevelText::Ellipsize::AUTO_SCROLL)
{
- // If request is disable (false) and auto scrolling is enabled then need to stop it
- if(enableAutoScroll == false)
+ DALI_LOG_WARNING("Tried to autoscroll while in ellipsize auto scroll mode, request ignored.\n");
+ }
+ else
+ {
+ const bool enableAutoScroll = value.Get<bool>();
+ impl.mLastAutoScrollEnabled = enableAutoScroll;
+ // If request to auto scroll is the same as current state then do nothing.
+ if(enableAutoScroll != impl.mController->IsAutoScrollEnabled())
{
- if(impl.mTextScroller)
+ // If request is disable (false) and auto scrolling is enabled then need to stop it
+ if(enableAutoScroll == false)
{
- impl.mTextScroller->StopScrolling();
+ if(impl.mTextScroller)
+ {
+ impl.mTextScroller->StopScrolling();
+ }
}
+ // If request is enable (true) then start autoscroll as not already running
+ else
+ {
+ impl.mController->SetAutoScrollEnabled(enableAutoScroll);
+ }
+ impl.mIsAsyncRenderNeeded = true;
}
- // If request is enable (true) then start autoscroll as not already running
- else
- {
- impl.mController->SetAutoScrollEnabled(enableAutoScroll);
- }
- impl.mIsAsyncRenderNeeded = true;
}
break;
}
impl.mController->SetTextElideEnabled(ellipsis);
impl.mIsAsyncRenderNeeded = true;
+ impl.RequestTextRelayout();
break;
}
case Toolkit::TextLabel::Property::LINE_WRAP_MODE:
if(!Equals(impl.mController->GetFontSizeScale(), scale))
{
impl.mController->SetFontSizeScale(scale);
- impl.mIsAsyncRenderNeeded = true;
+ impl.mTextUpdateNeeded = true;
}
break;
}
if(!Equals(impl.mController->IsFontSizeScaleEnabled(), enableFontSizeScale))
{
impl.mController->SetFontSizeScaleEnabled(enableFontSizeScale);
- impl.mIsAsyncRenderNeeded = true;
+ impl.mTextUpdateNeeded = true;
}
break;
}
DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel %p EllipsisPosition::Type %d\n", impl.mController.Get(), ellipsisPositionType);
impl.mController->SetEllipsisPosition(ellipsisPositionType);
impl.mIsAsyncRenderNeeded = true;
+ impl.RequestTextRelayout();
}
break;
}
}
break;
}
+ case Toolkit::DevelTextLabel::Property::ELLIPSIS_MODE:
+ {
+ DevelText::Ellipsize::Mode ellipsisMode = static_cast<DevelText::Ellipsize::Mode>(value.Get<int>());
+ if(impl.mController->GetEllipsisMode() != ellipsisMode)
+ {
+ impl.mController->SetEllipsisMode(ellipsisMode);
+ Text::TextScrollerPtr textScroller = impl.GetTextScroller();
+ if(textScroller)
+ {
+ textScroller->SetStopMode(Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE);
+ textScroller->StopScrolling();
+ }
+ impl.mIsAsyncRenderNeeded = true;
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
}
// Request relayout when text update is needed. It's necessary to call it
value = impl.mAsyncLineCount;
break;
}
+ case Toolkit::DevelTextLabel::Property::ELLIPSIS_MODE:
+ {
+ value = impl.mController->GetEllipsisMode();
+ break;
+ }
+ case Toolkit::DevelTextLabel::Property::IS_SCROLLING:
+ {
+ value = impl.mTextScroller && impl.mTextScroller->IsScrolling() ? true : false;
+ break;
+ }
}
}
mController->SetTextFitContentSize(contentSize);
}
+ if(mController->IsTextElideEnabled() && mController->GetEllipsisMode() == DevelText::Ellipsize::AUTO_SCROLL)
+ {
+ if(mController->IsMultiLineEnabled())
+ {
+ DALI_LOG_WARNING("Attempted ellipsize auto scroll on a non SINGLE_LINE_BOX, request ignored\n");
+ }
+ else
+ {
+ const Size naturalSize = GetNaturalSize().GetVectorXY();
+ bool autoScrollEnabled = contentSize.width < naturalSize.width ? true : false;
+ bool requestRelayout = false;
+
+ if(autoScrollEnabled != mController->IsAutoScrollEnabled())
+ {
+ mController->SetAutoScrollEnabled(autoScrollEnabled, requestRelayout);
+ }
+ }
+ }
+
const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection);
if((Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType)) || mTextUpdateNeeded)
parameters.isTextFitArrayEnabled = mController->IsTextFitArrayEnabled();
parameters.textFitArray = mController->GetTextFitArray();
parameters.isAutoScrollEnabled = mController->IsAutoScrollEnabled();
- if(parameters.isAutoScrollEnabled)
+ parameters.ellipsisMode = mController->GetEllipsisMode();
+ if(parameters.isAutoScrollEnabled || parameters.ellipsisMode == DevelText::Ellipsize::AUTO_SCROLL)
{
parameters.autoScrollStopMode = GetTextScroller()->GetStopMode();
parameters.autoScrollSpeed = GetTextScroller()->GetSpeed();
layoutDirection{Dali::LayoutDirection::LEFT_TO_RIGHT},
layoutDirectionPolicy{DevelText::MatchLayoutDirection::INHERIT},
ellipsisPosition{DevelText::EllipsisPosition::END},
+ ellipsisMode{DevelText::Ellipsize::TRUNCATE},
isUnderlineEnabled{false},
underlineType{Text::Underline::SOLID},
underlineColor{Color::BLACK},
Dali::LayoutDirection::Type layoutDirection; ///< The layout direction: one of {LEFT_TO_RIGHT, RIGHT_TO_LEFT}.
DevelText::MatchLayoutDirection layoutDirectionPolicy; ///< The policy used to set the text layout direction : one of {INHERIT, LOCALE, CONTENTS}.
DevelText::EllipsisPosition::Type ellipsisPosition; ///< The position of the ellipsis glyph: one of {END, START, MIDDLE}.
+ DevelText::Ellipsize::Mode ellipsisMode; ///< The mode of the ellipsis: one of {TRUNCATE, AUTO_SCROLL}.
bool isUnderlineEnabled : 1; ///< Underline properties
Text::Underline::Type underlineType;
case Text::Async::RENDER_FIXED_WIDTH:
case Text::Async::RENDER_CONSTRAINT:
{
- if(mParameters.isAutoScrollEnabled && !mParameters.isMultiLine)
+ if(mParameters.ellipsis && !mParameters.isMultiLine && mParameters.ellipsisMode == DevelText::Ellipsize::AUTO_SCROLL)
+ {
+ Text::AsyncTextRenderInfo naturalSizeInfo;
+ naturalSizeInfo = mLoader.GetNaturalSize(mParameters);
+ if(mParameters.textWidth < naturalSizeInfo.renderedSize.width)
+ {
+#ifdef TRACE_ENABLED
+ if(gTraceFilter && gTraceFilter->IsTraceEnabled())
+ {
+ DALI_LOG_RELEASE_INFO("RenderAutoScroll, Ellipsize::AUTO_SCROLL\n");
+ }
+#endif
+ mParameters.isAutoScrollEnabled = true;
+ mRenderInfo = mLoader.RenderAutoScroll(mParameters);
+ }
+ else
+ {
+#ifdef TRACE_ENABLED
+ if(gTraceFilter && gTraceFilter->IsTraceEnabled())
+ {
+ DALI_LOG_RELEASE_INFO("RenderText, Ellipsize::AUTO_SCROLL\n");
+ }
+#endif
+ mRenderInfo = mLoader.RenderText(mParameters);
+ }
+ }
+ else if(mParameters.isAutoScrollEnabled && !mParameters.isMultiLine)
{
#ifdef TRACE_ENABLED
if(gTraceFilter && gTraceFilter->IsTraceEnabled())
mModel->mLogicalModel->mCharacterSpacingRunsUpdated = false;
}
-void Controller::Impl::SetAutoScrollEnabled(bool enable)
+void Controller::Impl::SetAutoScrollEnabled(bool enable, bool requestRelayout)
{
if(mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
{
}
mIsAutoScrollEnabled = enable;
- RequestRelayout();
+ if(requestRelayout)
+ {
+ RequestRelayout();
+ }
}
else
{
mIsUserInteractionEnabled(true),
mProcessorRegistered(false),
mTextCutout(false),
- mRenderMode(DevelTextLabel::Render::SYNC)
+ mRenderMode(DevelTextLabel::Render::SYNC),
+ mEllipsisMode(DevelText::Ellipsize::TRUNCATE)
{
mModel = Model::New();
/**
* @copydoc Controller::SetAutoScrollEnabled()
*/
- void SetAutoScrollEnabled(bool enable);
+ void SetAutoScrollEnabled(bool enable, bool requestRelayout);
/**
* @copydoc Controller::SetEnableCursorBlink()
bool mProcessorRegistered : 1; ///< Whether the text controller registered into processor or not.
bool mTextCutout : 1; ///< Whether the text cutout enabled.
- DevelTextLabel::Render::Mode mRenderMode; ///< Render mode of the text. (SYNC, ASYNC_AUTO, ASYNC_MANUAL)
+ DevelTextLabel::Render::Mode mRenderMode; ///< Render mode of the text. (SYNC, ASYNC_AUTO, ASYNC_MANUAL)
+ DevelText::Ellipsize::Mode mEllipsisMode; ///< Ellipsis mode of the text. (TRUNCATE, AUTO_SCROLL)
private:
friend ControllerImplEventHandler;
return (mImpl->mMarkupProcessorEnabled && mImpl->mModel->mLogicalModel->mAnchors.Count() && mImpl->IsShowingRealText());
}
-void Controller::SetAutoScrollEnabled(bool enable)
+void Controller::SetAutoScrollEnabled(bool enable, bool requestRelayout)
{
DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable) ? "true" : "false", (mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX) ? "true" : "false", this);
- mImpl->SetAutoScrollEnabled(enable);
+ mImpl->SetAutoScrollEnabled(enable, requestRelayout);
}
void Controller::SetAutoScrollMaxTextureExceeded(bool exceed)
mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
}
+Toolkit::DevelText::Ellipsize::Mode Controller::GetEllipsisMode() const
+{
+ return mImpl->mEllipsisMode;
+}
+
+void Controller::SetEllipsisMode(Toolkit::DevelText::Ellipsize::Mode ellipsisMode)
+{
+ mImpl->mEllipsisMode = ellipsisMode;
+}
+
void Controller::SetCharacterSpacing(float characterSpacing)
{
mImpl->mModel->mVisualModel->SetCharacterSpacing(characterSpacing);
* By default is disabled.
*
* @param[in] enable Whether to enable the auto scrolling
+ * @param[in] requestRelayout Whether to request the relayout
*/
- void SetAutoScrollEnabled(bool enable);
+ void SetAutoScrollEnabled(bool enable, bool requestRelayout = true);
/**
* @brief Whether the auto scrolling texture exceed max texture.
*/
void SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition);
+ /**
+ * @brief Retrieves ellipsis mode
+ * @return The ellipsis mode
+ */
+ Toolkit::DevelText::Ellipsize::Mode GetEllipsisMode() const;
+
+ /**
+ * @brief Sets ellipsis mode
+ * @param[in] ellipsisMode The ellipsis mode for the text
+ */
+ void SetEllipsisMode(Toolkit::DevelText::Ellipsize::Mode ellipsisMode);
+
/**
* @brief Retrieves ignoreSpaceAfterText value from model
* @return The value of ignoreSpaceAfterText