X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Ftext-controls%2Ftext-label-impl.cpp;h=d9e413f35f3f221a52fd0e049cc1ad725815229b;hp=fad19cf16047aa2716cfcefbebea075709a5261b;hb=HEAD;hpb=77c65a709b30e63f2da9cf704cdfe44b9f99d8f0 diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index fad19cf..5af0fe1 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,7 @@ #include #include #include +#include #include #include @@ -70,7 +72,7 @@ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations). */ const float VERTICAL_ALIGNMENT_TABLE[Text::VerticalAlignment::BOTTOM + 1] = -{ + { 0.0f, // VerticalAlignment::TOP 0.5f, // VerticalAlignment::CENTER 1.0f // VerticalAlignment::BOTTOM @@ -88,7 +90,7 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT #endif const Scripting::StringEnum AUTO_SCROLL_STOP_MODE_TABLE[] = -{ + { {"IMMEDIATE", Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE}, {"FINISH_LOOP", Toolkit::TextLabel::AutoScrollStopMode::FINISH_LOOP}, }; @@ -141,6 +143,11 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "ellipsisPosition DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "strikethrough", MAP, STRIKETHROUGH ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "characterSpacing", FLOAT, CHARACTER_SPACING ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "relativeLineSize", FLOAT, RELATIVE_LINE_SIZE ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "anchorColor", VECTOR4, ANCHOR_COLOR ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "anchorClickedColor", VECTOR4, ANCHOR_CLICKED_COLOR ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "removeFrontInset", BOOLEAN, REMOVE_FRONT_INSET ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "removeBackInset", BOOLEAN, REMOVE_BACK_INSET ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "cutout", BOOLEAN, CUTOUT ) 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) @@ -206,6 +213,10 @@ void ParseTextFitProperty(Text::ControllerPtr& controller, const Property::Map* } controller->SetTextFitEnabled(enabled); + // The TextFit operation is performed based on the MinLineSize set in the TextLabel at the moment when the TextFit property is set. + // So, if you change the TextLabel's MinLineSize after setting the TextFit property, it does not affect the operation of TextFit. + // This may require a new LineSize item in TextFit. + controller->SetTextFitLineSize(controller->GetDefaultLineSize()); if(isMinSizeSet) { controller->SetTextFitMinSize(minSize, type); @@ -492,14 +503,26 @@ void TextLabel::SetProperty(BaseObject* object, Property::Index index, const Pro } case Toolkit::DevelTextLabel::Property::TEXT_FIT: { + // If TextFitArray is enabled, this should be disabled. + if(impl.mController->IsTextFitArrayEnabled()) + { + impl.mController->SetDefaultLineSize(impl.mController->GetCurrentLineSize()); + impl.mController->SetTextFitArrayEnabled(false); + } + ParseTextFitProperty(impl.mController, value.GetMap()); impl.mController->SetTextFitChanged(true); break; } case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE: { - const float lineSize = value.Get(); - impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSize(lineSize) || impl.mTextUpdateNeeded; + const float lineSize = value.Get(); + // If TextFitArray is enabled, do not update the default line size. + if(!impl.mController->IsTextFitArrayEnabled()) + { + impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSize(lineSize) || impl.mTextUpdateNeeded; + } + impl.mController->SetCurrentLineSize(lineSize); break; } case Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE: @@ -551,6 +574,51 @@ void TextLabel::SetProperty(BaseObject* object, Property::Index index, const Pro impl.mController->SetRelativeLineSize(relativeLineSize); break; } + case Toolkit::DevelTextLabel::Property::ANCHOR_COLOR: + { + const Vector4& anchorColor = value.Get(); + if(impl.mController->GetAnchorColor() != anchorColor) + { + impl.mController->SetAnchorColor(anchorColor); + impl.mTextUpdateNeeded = true; + } + break; + } + case Toolkit::DevelTextLabel::Property::ANCHOR_CLICKED_COLOR: + { + const Vector4& anchorClickedColor = value.Get(); + if(impl.mController->GetAnchorClickedColor() != anchorClickedColor) + { + impl.mController->SetAnchorClickedColor(anchorClickedColor); + impl.mTextUpdateNeeded = true; + } + break; + } + case Toolkit::DevelTextLabel::Property::REMOVE_FRONT_INSET: + { + const bool remove = value.Get(); + impl.mController->SetRemoveFrontInset(remove); + break; + } + case Toolkit::DevelTextLabel::Property::REMOVE_BACK_INSET: + { + const bool remove = value.Get(); + impl.mController->SetRemoveBackInset(remove); + break; + } + case Toolkit::DevelTextLabel::Property::CUTOUT: + { + const bool cutout = value.Get(); + + impl.mController->SetTextCutout(cutout); + + // Property doesn't affect the layout, only Visual must be updated + TextVisual::EnableRendererUpdate(impl.mVisual); + + // No need to trigger full re-layout. Instead call UpdateRenderer() directly + TextVisual::UpdateRenderer(impl.mVisual); + break; + } } // Request relayout when text update is needed. It's necessary to call it @@ -781,7 +849,8 @@ Property::Value TextLabel::GetProperty(BaseObject* object, Property::Index index } case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE: { - value = impl.mController->GetDefaultLineSize(); + // If TextFitArray is enabled, the stored value (MIN_LINE_SIZE set by the user) is retrun. + value = impl.mController->IsTextFitArrayEnabled() ? impl.mController->GetCurrentLineSize() : impl.mController->GetDefaultLineSize(); break; } case Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE: @@ -814,6 +883,31 @@ Property::Value TextLabel::GetProperty(BaseObject* object, Property::Index index value = impl.mController->GetRelativeLineSize(); break; } + case Toolkit::DevelTextLabel::Property::ANCHOR_COLOR: + { + value = impl.mController->GetAnchorColor(); + break; + } + case Toolkit::DevelTextLabel::Property::ANCHOR_CLICKED_COLOR: + { + value = impl.mController->GetAnchorClickedColor(); + break; + } + case Toolkit::DevelTextLabel::Property::REMOVE_FRONT_INSET: + { + value = impl.mController->IsRemoveFrontInset(); + break; + } + case Toolkit::DevelTextLabel::Property::REMOVE_BACK_INSET: + { + value = impl.mController->IsRemoveBackInset(); + break; + } + case Toolkit::DevelTextLabel::Property::CUTOUT: + { + value = impl.mController->IsTextCutout(); + break; + } } } @@ -870,7 +964,7 @@ void TextLabel::OnInitialize() propertyMap.Add(Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT); mVisual = Toolkit::VisualFactory::Get().CreateVisual(propertyMap); - DevelControl::RegisterVisual(*this, Toolkit::TextLabel::Property::TEXT, mVisual); + DevelControl::RegisterVisual(*this, Toolkit::TextLabel::Property::TEXT, mVisual, DepthIndex::CONTENT); TextVisual::SetAnimatableTextColorProperty(mVisual, Toolkit::TextLabel::Property::TEXT_COLOR); @@ -894,6 +988,11 @@ void TextLabel::OnInitialize() self.LayoutDirectionChangedSignal().Connect(this, &TextLabel::OnLayoutDirectionChanged); + if(Dali::Adaptor::IsAvailable()) + { + Dali::Adaptor::Get().LocaleChangedSignal().Connect(this, &TextLabel::OnLocaleChanged); + } + Layout::Engine& engine = mController->GetLayoutEngine(); engine.SetCursorWidth(0u); // Do not layout space for the cursor. @@ -1001,6 +1100,49 @@ void TextLabel::OnPropertySet(Property::Index index, const Property::Value& prop CommonTextUtils::SynchronizeTextAnchorsInParent(Self(), mController, mAnchorActors); break; } + case Toolkit::Control::Property::BACKGROUND: + { + const Vector4 backgroundColor = propertyValue.Get(); + + if(mController->IsTextCutout()) + { + DevelControl::EnableVisual(*this, Toolkit::Control::Property::BACKGROUND, false); + mController->SetBackgroundWithCutoutEnabled(true); + mController->SetBackgroundColorWithCutout(backgroundColor); + } + + break; + } + case Toolkit::DevelTextLabel::Property::CUTOUT: + { + const bool cutoutEnabled = propertyValue.Get(); + + if(cutoutEnabled) + { + Vector4 backgroundColor = Vector4::ZERO; + + const Property::Map backgroundMap = Self().GetProperty(Toolkit::Control::Property::BACKGROUND).Get(); + Property::Value* backgroundValue = backgroundMap.Find(ColorVisual::Property::MIX_COLOR); + if(backgroundValue) + { + backgroundColor = backgroundValue->Get(); + } + + DevelControl::EnableVisual(*this, Toolkit::Control::Property::BACKGROUND, false); + mController->SetBackgroundWithCutoutEnabled(true); + mController->SetBackgroundColorWithCutout(backgroundColor); + } + else + { + DevelControl::EnableVisual(*this, Toolkit::Control::Property::BACKGROUND, true); + + Property::Map backgroundMapSet; + mController->SetBackgroundWithCutoutEnabled(false); + } + + TextVisual::SetRequireRender(mVisual, cutoutEnabled); + break; + } default: { Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties @@ -1027,10 +1169,13 @@ void TextLabel::OnSceneDisconnection() mLastAutoScrollEnabled = false; } - const Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = mTextScroller->GetStopMode(); - mTextScroller->SetStopMode(Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE); - mTextScroller->StopScrolling(); - mTextScroller->SetStopMode(stopMode); + if(mTextScroller->IsScrolling()) + { + const Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = mTextScroller->GetStopMode(); + mTextScroller->SetStopMode(Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE); + mTextScroller->StopScrolling(); + mTextScroller->SetStopMode(stopMode); + } } Control::OnSceneDisconnection(); } @@ -1039,6 +1184,12 @@ void TextLabel::OnRelayout(const Vector2& size, RelayoutContainer& container) { DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::OnRelayout\n"); + if(mTextScroller && mTextScroller->IsStop()) + { + // When auto scroll is playing, it triggers a relayout only when an update is absolutely necessary. + return; + } + Actor self = Self(); Extents padding; @@ -1046,7 +1197,12 @@ void TextLabel::OnRelayout(const Vector2& size, RelayoutContainer& container) Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom)); - if(mController->IsTextFitEnabled()) + if(mController->IsTextFitArrayEnabled()) + { + mController->FitArrayPointSizeforLayout(contentSize); + mController->SetTextFitContentSize(contentSize); + } + else if(mController->IsTextFitEnabled()) { mController->FitPointSizeforLayout(contentSize); mController->SetTextFitContentSize(contentSize); @@ -1096,10 +1252,18 @@ void TextLabel::OnRelayout(const Vector2& size, RelayoutContainer& container) layoutSize.width = maxTextureSize; } + // This affects font rendering quality. + // It need to be integerized. + Vector2 visualTransformOffset; + visualTransformOffset.x = roundf(padding.start + alignmentOffset.x); + visualTransformOffset.y = roundf(padding.top + alignmentOffset.y); + + mController->SetVisualTransformOffset(visualTransformOffset); + Property::Map visualTransform; visualTransform.Add(Toolkit::Visual::Transform::Property::SIZE, layoutSize) .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE)) - .Add(Toolkit::Visual::Transform::Property::OFFSET, Vector2(padding.start, padding.top) + alignmentOffset) + .Add(Toolkit::Visual::Transform::Property::OFFSET, visualTransformOffset) .Add(Toolkit::Visual::Transform::Property::OFFSET_POLICY, Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE)) .Add(Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN) .Add(Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN); @@ -1194,17 +1358,27 @@ void TextLabel::ScrollingFinished() { // Pure Virtual from TextScroller Interface DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n"); + mController->SetAutoScrollEnabled(false); + RequestTextRelayout(); +} - if(mController->IsAutoScrollEnabled() || !mController->IsMultiLineEnabled()) +void TextLabel::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type) +{ + mController->ChangedLayoutDirection(); +} + +void TextLabel::OnLocaleChanged(std::string locale) +{ + if(mLocale != locale) { - mController->SetAutoScrollEnabled(false); - RequestTextRelayout(); + mLocale = locale; + mController->ResetFontAndStyleData(); } } -void TextLabel::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type) +std::string TextLabel::GetLocale() { - mController->ChangedLayoutDirection(); + return mLocale; } void TextLabel::EmitTextFitChangedSignal() @@ -1220,6 +1394,7 @@ void TextLabel::OnAccessibilityStatusChanged() TextLabel::TextLabel(ControlBehaviour additionalBehaviour) : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)), + mLocale(std::string()), mRenderingBackend(DEFAULT_RENDERING_BACKEND), mTextUpdateNeeded(false), mLastAutoScrollEnabled(false) @@ -1265,6 +1440,47 @@ void TextLabel::SetSpannedText(const Text::Spanned& spannedText) mController->SetSpannedText(spannedText); } +void TextLabel::SetTextFitArray(const bool enable, std::vector& fitOptions) +{ + if(!enable) + { + // If TextFitArray is disabled, MinLineSize shoud be restored to its original size. + mController->SetDefaultLineSize(mController->GetCurrentLineSize()); + } + mController->SetTextFitArrayEnabled(enable); + mController->SetTextFitArray(fitOptions); +} + +std::vector& TextLabel::GetTextFitArray() +{ + return mController->GetTextFitArray(); +} + +bool TextLabel::IsTextFitArrayEnabled() const +{ + return mController->IsTextFitArrayEnabled(); +} + +void TextLabel::SetRemoveFrontInset(bool remove) +{ + mController->SetRemoveFrontInset(remove); +} + +bool TextLabel::IsRemoveFrontInset() const +{ + return mController->IsRemoveFrontInset(); +} + +void TextLabel::SetRemoveBackInset(bool remove) +{ + mController->SetRemoveBackInset(remove); +} + +bool TextLabel::IsRemoveBackInset() const +{ + return mController->IsRemoveBackInset(); +} + std::string TextLabel::TextLabelAccessible::GetNameRaw() const { return GetWholeText();