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=21e13c82052709c7ea6addfa63f5cfd396c172b5;hp=a2d866e521698b71306f82ac2027b0d1d6956857;hb=91a31a5bdf35ebea5818c3809467b6fb74a547a2;hpb=6a945b790dae35b878e88f25ca19d69d6e2e6d46 diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp old mode 100755 new mode 100644 index a2d866e..21e13c8 --- 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) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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. @@ -19,76 +19,78 @@ #include // EXTERNAL INCLUDES -#include -#include -#include +#include #include +#include +#include #include +#include +#include // INTERNAL INCLUDES -#include -#include #include +#include +#include #include #include +#include #include #include #include -#include -#include +#include -#include -#include #include #include +#include +#include +#include #include #include -#include +// DEVEL INCLUDES #include using namespace Dali::Toolkit::Text; namespace Dali { - namespace Toolkit { - namespace Internal { - namespace { - const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND; +const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND; - /** - * @brief How the text visual should be aligned vertically inside the control. - * - * 0.0f aligns the text to the top, 0.5f aligns the text to the center, 1.0f aligns the text to the bottom. - * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations). - */ - const float VERTICAL_ALIGNMENT_TABLE[ Text::VerticalAlignment::BOTTOM + 1 ] = +/** + * @brief How the text visual should be aligned vertically inside the control. + * + * 0.0f aligns the text to the top, 0.5f aligns the text to the center, 1.0f aligns the text to the bottom. + * 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 - }; -} + 0.0f, // VerticalAlignment::TOP + 0.5f, // VerticalAlignment::CENTER + 1.0f // VerticalAlignment::BOTTOM +}; -namespace -{ +const std::string TEXT_FIT_ENABLE_KEY("enable"); +const std::string TEXT_FIT_MIN_SIZE_KEY("minSize"); +const std::string TEXT_FIT_MAX_SIZE_KEY("maxSize"); +const std::string TEXT_FIT_STEP_SIZE_KEY("stepSize"); +const std::string TEXT_FIT_FONT_SIZE_TYPE_KEY("fontSizeType"); -#if defined ( DEBUG_ENABLED ) - Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); +#if defined(DEBUG_ENABLED) +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); #endif const Scripting::StringEnum AUTO_SCROLL_STOP_MODE_TABLE[] = -{ - { "IMMEDIATE", Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE }, - { "FINISH_LOOP", Toolkit::TextLabel::AutoScrollStopMode::FINISH_LOOP }, + { + {"IMMEDIATE", Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE}, + {"FINISH_LOOP", Toolkit::TextLabel::AutoScrollStopMode::FINISH_LOOP}, }; -const unsigned int AUTO_SCROLL_STOP_MODE_TABLE_COUNT = sizeof( AUTO_SCROLL_STOP_MODE_TABLE ) / sizeof( AUTO_SCROLL_STOP_MODE_TABLE[0] ); +const unsigned int AUTO_SCROLL_STOP_MODE_TABLE_COUNT = sizeof(AUTO_SCROLL_STOP_MODE_TABLE) / sizeof(AUTO_SCROLL_STOP_MODE_TABLE[0]); // Type registration BaseHandle Create() @@ -96,60 +98,131 @@ BaseHandle Create() return Toolkit::TextLabel::New(); } +// clang-format off // Setup properties, signals and actions using the type-registry. -DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create ); - -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend", INTEGER, RENDERING_BACKEND ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text", STRING, TEXT ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily", STRING, FONT_FAMILY ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle", MAP, FONT_STYLE ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "pointSize", FLOAT, POINT_SIZE ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "multiLine", BOOLEAN, MULTI_LINE ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "horizontalAlignment", STRING, HORIZONTAL_ALIGNMENT ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "verticalAlignment", STRING, VERTICAL_ALIGNMENT ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "unusedPropertyTextColor", VECTOR4, UNUSED_PROPERTY_TEXT_COLOR ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "reservedProperty01", STRING, RESERVED_PROPERTY_01 ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "reservedProperty02", STRING, RESERVED_PROPERTY_02 ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "reservedProperty03", STRING, RESERVED_PROPERTY_03 ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "reservedProperty04", STRING, RESERVED_PROPERTY_04 ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "reservedProperty05", STRING, RESERVED_PROPERTY_05 ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableMarkup", BOOLEAN, ENABLE_MARKUP ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableAutoScroll", BOOLEAN, ENABLE_AUTO_SCROLL ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollSpeed", INTEGER, AUTO_SCROLL_SPEED ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopCount", INTEGER, AUTO_SCROLL_LOOP_COUNT ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollGap", FLOAT, AUTO_SCROLL_GAP ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineSpacing", FLOAT, LINE_SPACING ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underline", MAP, UNDERLINE ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadow", MAP, SHADOW ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "emboss", MAP, EMBOSS ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "outline", MAP, OUTLINE ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "pixelSize", FLOAT, PIXEL_SIZE ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "ellipsis", BOOLEAN, ELLIPSIS ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopDelay", FLOAT, AUTO_SCROLL_LOOP_DELAY ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollStopMode", STRING, AUTO_SCROLL_STOP_MODE ) -DALI_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "lineCount", INTEGER, LINE_COUNT ) -DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineWrapMode", INTEGER, LINE_WRAP_MODE ) -DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "textDirection", INTEGER, TEXT_DIRECTION ) -DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "verticalLineAlignment", INTEGER, VERTICAL_LINE_ALIGNMENT ) -DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "textBackground", MAP, BACKGROUND ) -DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "ignoreSpacesAfterText", BOOLEAN, IGNORE_SPACES_AFTER_TEXT ) -DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "matchSystemLanguageDirection", BOOLEAN, MATCH_SYSTEM_LANGUAGE_DIRECTION ) -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 ) -DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR, 1 ) -DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorBlue", TEXT_COLOR_BLUE, TEXT_COLOR, 2 ) -DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorAlpha", TEXT_COLOR_ALPHA, TEXT_COLOR, 3 ) +DALI_TYPE_REGISTRATION_BEGIN(Toolkit::TextLabel, Toolkit::Control, Create); + +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "text", STRING, TEXT ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "fontFamily", STRING, FONT_FAMILY ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "fontStyle", MAP, FONT_STYLE ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "pointSize", FLOAT, POINT_SIZE ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "multiLine", BOOLEAN, MULTI_LINE ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "horizontalAlignment", STRING, HORIZONTAL_ALIGNMENT ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "verticalAlignment", STRING, VERTICAL_ALIGNMENT ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "enableMarkup", BOOLEAN, ENABLE_MARKUP ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "enableAutoScroll", BOOLEAN, ENABLE_AUTO_SCROLL ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "autoScrollSpeed", INTEGER, AUTO_SCROLL_SPEED ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "autoScrollLoopCount", INTEGER, AUTO_SCROLL_LOOP_COUNT ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "autoScrollGap", FLOAT, AUTO_SCROLL_GAP ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "lineSpacing", FLOAT, LINE_SPACING ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "underline", MAP, UNDERLINE ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "shadow", MAP, SHADOW ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "emboss", MAP, EMBOSS ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "outline", MAP, OUTLINE ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "pixelSize", FLOAT, PIXEL_SIZE ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "ellipsis", BOOLEAN, ELLIPSIS ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "autoScrollLoopDelay", FLOAT, AUTO_SCROLL_LOOP_DELAY ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "autoScrollStopMode", STRING, AUTO_SCROLL_STOP_MODE ) +DALI_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "lineCount", INTEGER, LINE_COUNT ) +DALI_PROPERTY_REGISTRATION(Toolkit, TextLabel, "lineWrapMode", INTEGER, LINE_WRAP_MODE ) +DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextLabel, "textDirection", INTEGER, TEXT_DIRECTION ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "verticalLineAlignment", INTEGER, VERTICAL_LINE_ALIGNMENT ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "textBackground", MAP, BACKGROUND ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "ignoreSpacesAfterText", BOOLEAN, IGNORE_SPACES_AFTER_TEXT ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "matchSystemLanguageDirection", BOOLEAN, MATCH_SYSTEM_LANGUAGE_DIRECTION) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "textFit", MAP, TEXT_FIT ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "minLineSize", FLOAT, MIN_LINE_SIZE ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "renderingBackend", INTEGER, RENDERING_BACKEND ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "fontSizeScale", FLOAT, FONT_SIZE_SCALE ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextLabel, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION ) + +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) +DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit, TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR, 1) +DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit, TextLabel, "textColorBlue", TEXT_COLOR_BLUE, TEXT_COLOR, 2) +DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION(Toolkit, TextLabel, "textColorAlpha", TEXT_COLOR_ALPHA, TEXT_COLOR, 3) + +DALI_SIGNAL_REGISTRATION(Toolkit, TextLabel, "anchorClicked", SIGNAL_ANCHOR_CLICKED) + DALI_TYPE_REGISTRATION_END() +// clang-format on + +/// Parses the property map for the TEXT_FIT property +void ParseTextFitProperty(Text::ControllerPtr& controller, const Property::Map* propertiesMap) +{ + if(propertiesMap && !propertiesMap->Empty()) + { + bool enabled = false; + float minSize = 0.f; + float maxSize = 0.f; + float stepSize = 0.f; + bool isMinSizeSet = false, isMaxSizeSet = false, isStepSizeSet = false; + Controller::FontSizeType type = Controller::FontSizeType::POINT_SIZE; + + const unsigned int numberOfItems = propertiesMap->Count(); + + // Parses and applies + for(unsigned int index = 0u; index < numberOfItems; ++index) + { + const KeyValuePair& valueGet = propertiesMap->GetKeyValue(index); + + if((Controller::TextFitInfo::Property::TEXT_FIT_ENABLE == valueGet.first.indexKey) || (TEXT_FIT_ENABLE_KEY == valueGet.first.stringKey)) + { + /// Enable key. + enabled = valueGet.second.Get(); + } + else if((Controller::TextFitInfo::Property::TEXT_FIT_MIN_SIZE == valueGet.first.indexKey) || (TEXT_FIT_MIN_SIZE_KEY == valueGet.first.stringKey)) + { + /// min size. + minSize = valueGet.second.Get(); + isMinSizeSet = true; + } + else if((Controller::TextFitInfo::Property::TEXT_FIT_MAX_SIZE == valueGet.first.indexKey) || (TEXT_FIT_MAX_SIZE_KEY == valueGet.first.stringKey)) + { + /// max size. + maxSize = valueGet.second.Get(); + isMaxSizeSet = true; + } + else if((Controller::TextFitInfo::Property::TEXT_FIT_STEP_SIZE == valueGet.first.indexKey) || (TEXT_FIT_STEP_SIZE_KEY == valueGet.first.stringKey)) + { + /// step size. + stepSize = valueGet.second.Get(); + isStepSizeSet = true; + } + else if((Controller::TextFitInfo::Property::TEXT_FIT_FONT_SIZE_TYPE == valueGet.first.indexKey) || (TEXT_FIT_FONT_SIZE_TYPE_KEY == valueGet.first.stringKey)) + { + if("pixelSize" == valueGet.second.Get()) + { + type = Controller::FontSizeType::PIXEL_SIZE; + } + } + } + + controller->SetTextFitEnabled(enabled); + if(isMinSizeSet) + { + controller->SetTextFitMinSize(minSize, type); + } + if(isMaxSizeSet) + { + controller->SetTextFitMaxSize(maxSize, type); + } + if(isStepSizeSet) + { + controller->SetTextFitStepSize(stepSize, type); + } + } +} } // namespace Toolkit::TextLabel TextLabel::New() { // Create the implementation, temporarily owned by this handle on stack - IntrusivePtr< TextLabel > impl = new TextLabel(); + IntrusivePtr impl = new TextLabel(); // Pass ownership to CustomActor handle - Toolkit::TextLabel handle( *impl ); + Toolkit::TextLabel handle(*impl); // Second-phase init of the implementation // This can only be done after the CustomActor connection has been made... @@ -158,324 +231,287 @@ Toolkit::TextLabel TextLabel::New() return handle; } -void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +void TextLabel::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value) { - Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) ); + Toolkit::TextLabel label = Toolkit::TextLabel::DownCast(Dali::BaseHandle(object)); - if( label ) + if(label) { - TextLabel& impl( GetImpl( label ) ); - switch( index ) + TextLabel& impl(GetImpl(label)); + DALI_ASSERT_ALWAYS(impl.mController && "No text contoller"); + + switch(index) { - case Toolkit::TextLabel::Property::RENDERING_BACKEND: + case Toolkit::DevelTextLabel::Property::RENDERING_BACKEND: { - DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__); - - int backend = value.Get< int >(); + int backend = value.Get(); #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING - if( Text::RENDERING_VECTOR_BASED == backend ) + if(DevelText::RENDERING_VECTOR_BASED == backend) { backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering } #endif - if( impl.mRenderingBackend != backend ) + if(impl.mRenderingBackend != backend) { impl.mRenderingBackend = backend; impl.mTextUpdateNeeded = true; - if( impl.mController ) - { - // When using the vector-based rendering, the size of the GLyphs are different - TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH; - impl.mController->SetGlyphType( glyphType ); - } + // When using the vector-based rendering, the size of the GLyphs are different + TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH; + impl.mController->SetGlyphType(glyphType); } break; } case Toolkit::TextLabel::Property::TEXT: { - if( impl.mController ) + impl.mController->SetText(value.Get()); + + if(impl.mController->HasAnchors()) { - impl.mController->SetText( value.Get< std::string >() ); + // Forward input events to controller + impl.EnableGestureDetection(static_cast(GestureType::TAP)); } + else + { + impl.DisableGestureDetection(static_cast(GestureType::TAP)); + } + break; } case Toolkit::TextLabel::Property::FONT_FAMILY: { - if( impl.mController ) - { - const std::string& fontFamily = value.Get< std::string >(); + const std::string& fontFamily = value.Get(); - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() ); - impl.mController->SetDefaultFontFamily( fontFamily ); - } + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str()); + impl.mController->SetDefaultFontFamily(fontFamily); break; } case Toolkit::TextLabel::Property::FONT_STYLE: { - SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); + SetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT); break; } case Toolkit::TextLabel::Property::POINT_SIZE: { - if( impl.mController ) - { - const float pointSize = value.Get< float >(); + const float pointSize = value.Get(); - if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) ) - { - impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE ); - } + if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE), pointSize)) + { + impl.mController->SetDefaultFontSize(pointSize, Text::Controller::POINT_SIZE); } break; } case Toolkit::TextLabel::Property::MULTI_LINE: { - if( impl.mController ) - { - impl.mController->SetMultiLineEnabled( value.Get< bool >() ); - } + impl.mController->SetMultiLineEnabled(value.Get()); break; } case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT: { - if( impl.mController ) + Text::HorizontalAlignment::Type alignment(static_cast(-1)); // Set to invalid value to ensure a valid mode does get set + if(Text::GetHorizontalAlignmentEnumeration(value, alignment)) { - Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set - if( Text::GetHorizontalAlignmentEnumeration( value, alignment ) ) - { - impl.mController->SetHorizontalAlignment( alignment ); - } + impl.mController->SetHorizontalAlignment(alignment); } break; } case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT: { - if( impl.mController ) + Toolkit::Text::VerticalAlignment::Type alignment(static_cast(-1)); // Set to invalid value to ensure a valid mode does get set + if(Text::GetVerticalAlignmentEnumeration(value, alignment)) { - Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set - if( Text::GetVerticalAlignmentEnumeration( value, alignment ) ) - { - impl.mController->SetVerticalAlignment( alignment ); - } + impl.mController->SetVerticalAlignment(alignment); } break; } - - case Toolkit::TextLabel::Property::UNUSED_PROPERTY_TEXT_COLOR: - { - label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, value ); - impl.mTextUpdateNeeded = true; - break; - } case Toolkit::TextLabel::Property::ENABLE_MARKUP: { - if( impl.mController ) + const bool enableMarkup = value.Get(); + impl.mController->SetMarkupProcessorEnabled(enableMarkup); + + if(impl.mController->HasAnchors()) { - const bool enableMarkup = value.Get(); - impl.mController->SetMarkupProcessorEnabled( enableMarkup ); + // Forward input events to controller + impl.EnableGestureDetection(static_cast(GestureType::TAP)); + } + else + { + impl.DisableGestureDetection(static_cast(GestureType::TAP)); } break; } case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL: { - if( impl.mController ) + const bool enableAutoScroll = value.Get(); + // If request to auto scroll is the same as current state then do nothing. + if(enableAutoScroll != impl.mController->IsAutoScrollEnabled()) { - const bool enableAutoScroll = value.Get(); - // If request to auto scroll is the same as current state then do nothing. - if ( enableAutoScroll != impl.mController->IsAutoScrollEnabled() ) + // If request is disable (false) and auto scrolling is enabled then need to stop it + if(enableAutoScroll == false) + { + if(impl.mTextScroller) + { + impl.mTextScroller->StopScrolling(); + } + } + // If request is enable (true) then start autoscroll as not already running + else { - // If request is disable (false) and auto scrolling is enabled then need to stop it - if ( enableAutoScroll == false ) - { - if( impl.mTextScroller ) - { - impl.mTextScroller->StopScrolling(); - } - } - // If request is enable (true) then start autoscroll as not already running - else - { - impl.mController->SetAutoScrollEnabled( enableAutoScroll ); - } + impl.mController->SetAutoScrollEnabled(enableAutoScroll); } } break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_STOP_MODE: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = impl.mTextScroller->GetStopMode(); - if( Scripting::GetEnumerationProperty< Toolkit::TextLabel::AutoScrollStopMode::Type >( value, - AUTO_SCROLL_STOP_MODE_TABLE, - AUTO_SCROLL_STOP_MODE_TABLE_COUNT, - stopMode ) ) + Text::TextScrollerPtr textScroller = impl.GetTextScroller(); + Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = textScroller->GetStopMode(); + if(Scripting::GetEnumerationProperty(value, + AUTO_SCROLL_STOP_MODE_TABLE, + AUTO_SCROLL_STOP_MODE_TABLE_COUNT, + stopMode)) { - impl.mTextScroller->SetStopMode( stopMode ); + textScroller->SetStopMode(stopMode); } break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetSpeed( value.Get() ); + impl.GetTextScroller()->SetSpeed(value.Get()); break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetLoopCount( value.Get() ); + impl.GetTextScroller()->SetLoopCount(value.Get()); break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_DELAY: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetLoopDelay( value.Get() ); + impl.GetTextScroller()->SetLoopDelay(value.Get()); break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP: { - if( !impl.mTextScroller ) - { - impl.mTextScroller = Text::TextScroller::New( impl ); - } - impl.mTextScroller->SetGap( value.Get() ); + impl.GetTextScroller()->SetGap(value.Get()); break; } case Toolkit::TextLabel::Property::LINE_SPACING: { - if( impl.mController ) - { - const float lineSpacing = value.Get(); - - // Don't trigger anything if the line spacing didn't change - if( impl.mController->SetDefaultLineSpacing( lineSpacing ) ) - { - impl.mTextUpdateNeeded = true; - } - } + const float lineSpacing = value.Get(); + impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSpacing(lineSpacing) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::UNDERLINE: { - const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::SHADOW: { - const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::EMBOSS: { - const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::OUTLINE: { - const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT) || impl.mTextUpdateNeeded; break; } case Toolkit::TextLabel::Property::PIXEL_SIZE: { - if( impl.mController ) - { - const float pixelSize = value.Get< float >(); - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize ); + const float pixelSize = value.Get(); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize); - if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) ) - { - impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE ); - } + if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE), pixelSize)) + { + impl.mController->SetDefaultFontSize(pixelSize, Text::Controller::PIXEL_SIZE); } break; } case Toolkit::TextLabel::Property::ELLIPSIS: { - if( impl.mController ) - { - const bool ellipsis = value.Get(); - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis ); + const bool ellipsis = value.Get(); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis); - impl.mController->SetTextElideEnabled( ellipsis ); - } + impl.mController->SetTextElideEnabled(ellipsis); break; } case Toolkit::TextLabel::Property::LINE_WRAP_MODE: { - if( impl.mController ) + Text::LineWrap::Mode lineWrapMode(static_cast(-1)); // Set to invalid value to ensure a valid mode does get set + if(GetLineWrapModeEnumeration(value, lineWrapMode)) { - Text::LineWrap::Mode lineWrapMode( static_cast< Text::LineWrap::Mode >( -1 ) ); // Set to invalid value to ensure a valid mode does get set - if( GetLineWrapModeEnumeration( value, lineWrapMode ) ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode ); - impl.mController->SetLineWrapMode( lineWrapMode ); - } + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode); + impl.mController->SetLineWrapMode(lineWrapMode); } break; } case Toolkit::DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT: { - if( impl.mController && impl.mController->GetTextModel() ) + if(impl.mController->GetTextModel()) { - DevelText::VerticalLineAlignment::Type alignment = static_cast( value.Get() ); + DevelText::VerticalLineAlignment::Type alignment = static_cast(value.Get()); - impl.mController->SetVerticalLineAlignment( alignment ); + impl.mController->SetVerticalLineAlignment(alignment); // Property doesn't affect the layout, only Visual must be updated - TextVisual::EnableRendererUpdate( impl.mVisual ); + TextVisual::EnableRendererUpdate(impl.mVisual); // No need to trigger full re-layout. Instead call UpdateRenderer() directly - TextVisual::UpdateRenderer( impl.mVisual ); + TextVisual::UpdateRenderer(impl.mVisual); } break; } case Toolkit::DevelTextLabel::Property::BACKGROUND: { - const bool update = SetBackgroundProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); - if( update ) - { - impl.mTextUpdateNeeded = true; - } + impl.mTextUpdateNeeded = SetBackgroundProperties(impl.mController, value, Text::EffectStyle::DEFAULT) || impl.mTextUpdateNeeded; break; } case Toolkit::DevelTextLabel::Property::IGNORE_SPACES_AFTER_TEXT: { - impl.mController->SetIgnoreSpacesAfterText(value.Get< bool >()); + impl.mController->SetIgnoreSpacesAfterText(value.Get()); break; } case Toolkit::DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION: { - impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >()); + impl.mController->SetMatchLayoutDirection(value.Get() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS); + break; + } + case Toolkit::DevelTextLabel::Property::TEXT_FIT: + { + ParseTextFitProperty(impl.mController, value.GetMap()); + break; + } + case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE: + { + const float lineSize = value.Get(); + impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSize(lineSize) || impl.mTextUpdateNeeded; + break; + } + case Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE: + { + const float scale = value.Get(); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale); + + if(!Equals(impl.mController->GetFontSizeScale(), scale)) + { + impl.mController->SetFontSizeScale(scale); + } + break; + } + case Toolkit::DevelTextLabel::Property::ELLIPSIS_POSITION: + { + DevelText::EllipsisPosition::Type ellipsisPositionType(static_cast(-1)); // Set to invalid value to ensure a valid mode does get set + if(GetEllipsisPositionTypeEnumeration(value, ellipsisPositionType)) + { + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel %p EllipsisPosition::Type %d\n", impl.mController.Get(), ellipsisPositionType); + impl.mController->SetEllipsisPosition(ellipsisPositionType); + } break; } } @@ -483,139 +519,110 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr // Request relayout when text update is needed. It's necessary to call it // as changing the property not via UI interaction brings no effect if only // the mTextUpdateNeeded is changed. - if( impl.mTextUpdateNeeded ) + if(impl.mTextUpdateNeeded) { // need to request relayout as size of text may have changed impl.RequestTextRelayout(); } } +} - - - +Text::ControllerPtr TextLabel::GetTextController() +{ + return mController; } -Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index ) +Property::Value TextLabel::GetProperty(BaseObject* object, Property::Index index) { Property::Value value; - Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) ); + Toolkit::TextLabel label = Toolkit::TextLabel::DownCast(Dali::BaseHandle(object)); - if( label ) + if(label) { - TextLabel& impl( GetImpl( label ) ); - switch( index ) + TextLabel& impl(GetImpl(label)); + DALI_ASSERT_DEBUG(impl.mController && "No text contoller"); + + switch(index) { - case Toolkit::TextLabel::Property::RENDERING_BACKEND: + case Toolkit::DevelTextLabel::Property::RENDERING_BACKEND: { - DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__); - value = impl.mRenderingBackend; break; } case Toolkit::TextLabel::Property::TEXT: { - if( impl.mController ) - { - std::string text; - impl.mController->GetText( text ); - value = text; - } + std::string text; + impl.mController->GetText(text); + value = text; break; } case Toolkit::TextLabel::Property::FONT_FAMILY: { - if( impl.mController ) - { - value = impl.mController->GetDefaultFontFamily(); - } + value = impl.mController->GetDefaultFontFamily(); break; } case Toolkit::TextLabel::Property::FONT_STYLE: { - GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); + GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT); break; } case Toolkit::TextLabel::Property::POINT_SIZE: { - if( impl.mController ) - { - value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ); - } + value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE); break; } case Toolkit::TextLabel::Property::MULTI_LINE: { - if( impl.mController ) - { - value = impl.mController->IsMultiLineEnabled(); - } + value = impl.mController->IsMultiLineEnabled(); break; } case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT: { - if( impl.mController ) - { - const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() ); + const char* name = Text::GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment()); - if ( name ) - { - value = std::string( name ); - } + if(name) + { + value = std::string(name); } break; } case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT: { - if( impl.mController ) + const char* name = Text::GetVerticalAlignmentString(impl.mController->GetVerticalAlignment()); + if(name) { - const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() ); - if( name ) - { - value = std::string( name ); - } + value = std::string(name); } break; } - case Toolkit::TextLabel::Property::UNUSED_PROPERTY_TEXT_COLOR: - { - value = label.GetProperty( Toolkit::TextLabel::Property::TEXT_COLOR ); - break; - } case Toolkit::TextLabel::Property::ENABLE_MARKUP: { - if( impl.mController ) - { - value = impl.mController->IsMarkupProcessorEnabled(); - } + value = impl.mController->IsMarkupProcessorEnabled(); break; } case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL: { - if( impl.mController ) - { - value = impl.mController->IsAutoScrollEnabled(); - } + value = impl.mController->IsAutoScrollEnabled(); break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_STOP_MODE: { - if( impl.mTextScroller ) + if(impl.mTextScroller) { - const char* mode = Scripting::GetEnumerationName< Toolkit::TextLabel::AutoScrollStopMode::Type >( impl.mTextScroller->GetStopMode(), - AUTO_SCROLL_STOP_MODE_TABLE, - AUTO_SCROLL_STOP_MODE_TABLE_COUNT ); - if( mode ) + const char* mode = Scripting::GetEnumerationName(impl.mTextScroller->GetStopMode(), + AUTO_SCROLL_STOP_MODE_TABLE, + AUTO_SCROLL_STOP_MODE_TABLE_COUNT); + if(mode) { - value = std::string( mode ); + value = std::string(mode); } } break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED: { - TextLabel& impl( GetImpl( label ) ); - if ( impl.mTextScroller ) + if(impl.mTextScroller) { value = impl.mTextScroller->GetSpeed(); } @@ -623,32 +630,23 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde } case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT: { - if( impl.mController ) + if(impl.mTextScroller) { - TextLabel& impl( GetImpl( label ) ); - if ( impl.mTextScroller ) - { - value = impl.mTextScroller->GetLoopCount(); - } + value = impl.mTextScroller->GetLoopCount(); } break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_DELAY: { - if( impl.mController ) + if(impl.mTextScroller) { - TextLabel& impl( GetImpl( label ) ); - if ( impl.mTextScroller ) - { - value = impl.mTextScroller->GetLoopDelay(); - } + value = impl.mTextScroller->GetLoopDelay(); } break; } case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP: { - TextLabel& impl( GetImpl( label ) ); - if ( impl.mTextScroller ) + if(impl.mTextScroller) { value = impl.mTextScroller->GetGap(); } @@ -656,84 +654,63 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde } case Toolkit::TextLabel::Property::LINE_SPACING: { - if( impl.mController ) - { - value = impl.mController->GetDefaultLineSpacing(); - } + value = impl.mController->GetDefaultLineSpacing(); break; } case Toolkit::TextLabel::Property::UNDERLINE: { - GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT); break; } case Toolkit::TextLabel::Property::SHADOW: { - GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT); break; } case Toolkit::TextLabel::Property::EMBOSS: { - GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT); break; } case Toolkit::TextLabel::Property::OUTLINE: { - GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT); break; } case Toolkit::TextLabel::Property::PIXEL_SIZE: { - if( impl.mController ) - { - value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ); - } + value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE); break; } case Toolkit::TextLabel::Property::ELLIPSIS: { - if( impl.mController ) - { - value = impl.mController->IsTextElideEnabled(); - } + value = impl.mController->IsTextElideEnabled(); break; } case Toolkit::TextLabel::Property::LINE_WRAP_MODE: { - if( impl.mController ) - { - value = impl.mController->GetLineWrapMode(); - } + value = impl.mController->GetLineWrapMode(); break; } case Toolkit::TextLabel::Property::LINE_COUNT: { - if( impl.mController ) - { - float width = label.GetProperty( Actor::Property::SIZE_WIDTH ).Get(); - value = impl.mController->GetLineCount( width ); - } + float width = label.GetProperty(Actor::Property::SIZE_WIDTH).Get(); + value = impl.mController->GetLineCount(width); break; } case Toolkit::DevelTextLabel::Property::TEXT_DIRECTION: { - if( impl.mController ) - { - value = impl.mController->GetTextDirection(); - } + value = impl.mController->GetTextDirection(); break; } case Toolkit::DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT: { - if( impl.mController ) - { - value = impl.mController->GetVerticalLineAlignment(); - } + value = impl.mController->GetVerticalLineAlignment(); break; } case Toolkit::DevelTextLabel::Property::BACKGROUND: { - GetBackgroundProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + GetBackgroundProperties(impl.mController, value, Text::EffectStyle::DEFAULT); break; } case Toolkit::DevelTextLabel::Property::IGNORE_SPACES_AFTER_TEXT: @@ -743,7 +720,39 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde } case Toolkit::DevelTextLabel::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION: { - value = impl.mController->IsMatchSystemLanguageDirection(); + value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS; + break; + } + case Toolkit::DevelTextLabel::Property::TEXT_FIT: + { + const bool enabled = impl.mController->IsTextFitEnabled(); + const float minSize = impl.mController->GetTextFitMinSize(); + const float maxSize = impl.mController->GetTextFitMaxSize(); + const float stepSize = impl.mController->GetTextFitStepSize(); + + Property::Map map; + map.Insert(TEXT_FIT_ENABLE_KEY, enabled); + map.Insert(TEXT_FIT_MIN_SIZE_KEY, minSize); + map.Insert(TEXT_FIT_MAX_SIZE_KEY, maxSize); + map.Insert(TEXT_FIT_STEP_SIZE_KEY, stepSize); + map.Insert(TEXT_FIT_FONT_SIZE_TYPE_KEY, "pointSize"); + + value = map; + break; + } + case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE: + { + value = impl.mController->GetDefaultLineSize(); + break; + } + case Toolkit::DevelTextLabel::Property::FONT_SIZE_SCALE: + { + value = impl.mController->GetFontSizeScale(); + break; + } + case Toolkit::DevelTextLabel::Property::ELLIPSIS_POSITION: + { + value = impl.mController->GetEllipsisPosition(); break; } } @@ -752,58 +761,97 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde return value; } +bool TextLabel::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor) +{ + Dali::BaseHandle handle(object); + + bool connected(true); + Toolkit::TextLabel label = Toolkit::TextLabel::DownCast(handle); + + if(0 == strcmp(signalName.c_str(), SIGNAL_ANCHOR_CLICKED)) + { + if(label) + { + Internal::TextLabel& labelImpl(GetImpl(label)); + labelImpl.AnchorClickedSignal().Connect(tracker, functor); + } + } + else + { + // signalName does not match any signal + connected = false; + } + + return connected; +} + +DevelTextLabel::AnchorClickedSignalType& TextLabel::AnchorClickedSignal() +{ + return mAnchorClickedSignal; +} + void TextLabel::OnInitialize() { Actor self = Self(); Property::Map propertyMap; - propertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT ); + propertyMap.Add(Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT); - mVisual = Toolkit::VisualFactory::Get().CreateVisual( propertyMap ); - DevelControl::RegisterVisual( *this, Toolkit::TextLabel::Property::TEXT, mVisual ); + mVisual = Toolkit::VisualFactory::Get().CreateVisual(propertyMap); + DevelControl::RegisterVisual(*this, Toolkit::TextLabel::Property::TEXT, mVisual); - TextVisual::SetAnimatableTextColorProperty( mVisual, Toolkit::TextLabel::Property::TEXT_COLOR ); + TextVisual::SetAnimatableTextColorProperty(mVisual, Toolkit::TextLabel::Property::TEXT_COLOR); mController = TextVisual::GetController(mVisual); - if( mController ) - { - mController->SetControlInterface(this); - } + DALI_ASSERT_DEBUG(mController && "Invalid Text Controller") + + mController->SetControlInterface(this); + mController->SetAnchorControlInterface(this); // Use height-for-width negotiation by default - self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); - self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT ); + self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH); + self.SetResizePolicy(ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT); + + // Enable highlightability + self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true); // Enable the text ellipsis. - mController->SetTextElideEnabled( true ); // If false then text larger than control will overflow + mController->SetTextElideEnabled(true); // If false then text larger than control will overflow // Sets layoutDirection value - Dali::Stage stage = Dali::Stage::GetCurrent(); - Dali::LayoutDirection::Type layoutDirection = static_cast( stage.GetRootLayer().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get() ); - mController->SetLayoutDirection( layoutDirection ); + Dali::Stage stage = Dali::Stage::GetCurrent(); + Dali::LayoutDirection::Type layoutDirection = static_cast(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get()); + mController->SetLayoutDirection(layoutDirection); + + self.LayoutDirectionChangedSignal().Connect(this, &TextLabel::OnLayoutDirectionChanged); Layout::Engine& engine = mController->GetLayoutEngine(); - engine.SetCursorWidth( 0u ); // Do not layout space for the cursor. + engine.SetCursorWidth(0u); // Do not layout space for the cursor. + + DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) { + return std::unique_ptr( + new AccessibleImpl(actor, Dali::Accessibility::Role::LABEL)); + }); } -void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change ) +void TextLabel::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n"); + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n"); - switch ( change ) + switch(change) { case StyleChange::DEFAULT_FONT_CHANGE: { // Property system did not set the font so should update it. - const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily(); - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str() ); - mController->UpdateAfterFontChange( newFont ); + const std::string& newFont = GetImpl(styleManager).GetDefaultFontFamily(); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str()); + mController->UpdateAfterFontChange(newFont); RelayoutRequest(); break; } case StyleChange::DEFAULT_FONT_SIZE_CHANGE: { - GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) ); + GetImpl(styleManager).ApplyThemeStyle(Toolkit::Control(GetOwner())); RelayoutRequest(); break; } @@ -815,110 +863,134 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange:: } // Up call to Control - Control::OnStyleChange( styleManager, change ); + Control::OnStyleChange(styleManager, change); +} + +void TextLabel::OnTap(const TapGesture& gesture) +{ + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::OnTap %p\n", mController.Get()); + + // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures + Extents padding; + padding = Self().GetProperty(Toolkit::Control::Property::PADDING); + const Vector2& localPoint = gesture.GetLocalPoint(); + mController->AnchorEvent(localPoint.x - padding.start, localPoint.y - padding.top); +} + +void TextLabel::AnchorClicked(const std::string& href) +{ + Dali::Toolkit::TextLabel handle(GetOwner()); + mAnchorClickedSignal.Emit(handle, href.c_str(), href.length()); } Vector3 TextLabel::GetNaturalSize() { Extents padding; - padding = Self().GetProperty( Toolkit::Control::Property::PADDING ); + padding = Self().GetProperty(Toolkit::Control::Property::PADDING); Vector3 naturalSize = mController->GetNaturalSize(); - naturalSize.width += ( padding.start + padding.end ); - naturalSize.height += ( padding.top + padding.bottom ); + naturalSize.width += (padding.start + padding.end); + naturalSize.height += (padding.top + padding.bottom); return naturalSize; } -float TextLabel::GetHeightForWidth( float width ) +float TextLabel::GetHeightForWidth(float width) { Extents padding; - padding = Self().GetProperty( Toolkit::Control::Property::PADDING ); + padding = Self().GetProperty(Toolkit::Control::Property::PADDING); - return mController->GetHeightForWidth( width ) + padding.top + padding.bottom; + return mController->GetHeightForWidth(width) + padding.top + padding.bottom; } -void TextLabel::OnPropertySet( Property::Index index, Property::Value propertyValue ) +void TextLabel::OnPropertySet(Property::Index index, const Property::Value& propertyValue) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::OnPropertySet index[%d]\n", index ); + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextLabel::OnPropertySet index[%d]\n", index); - switch ( index ) + switch(index) { case Toolkit::TextLabel::Property::TEXT_COLOR: { - const Vector4& textColor = propertyValue.Get< Vector4 >(); - if( mController->GetDefaultColor() != textColor ) + const Vector4& textColor = propertyValue.Get(); + if(mController->GetDefaultColor() != textColor) { - mController->SetDefaultColor( textColor ); - mTextUpdateNeeded = true; + mController->SetDefaultColor(textColor); + mTextUpdateNeeded = true; } break; } default: { - Control::OnPropertySet( index, propertyValue ); // up call to control for non-handled properties + Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties break; } } } -void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container ) +void TextLabel::OnRelayout(const Vector2& size, RelayoutContainer& container) { - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" ); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::OnRelayout\n"); + + Actor self = Self(); Extents padding; - padding = Self().GetProperty( Toolkit::Control::Property::PADDING ); + padding = self.GetProperty(Toolkit::Control::Property::PADDING); + + Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom)); - Vector2 contentSize( size.x - ( padding.start + padding.end ), size.y - ( padding.top + padding.bottom ) ); + if(mController->IsTextFitEnabled()) + { + mController->FitPointSizeforLayout(contentSize); + mController->SetTextFitContentSize(contentSize); + } // Support Right-To-Left - Dali::LayoutDirection::Type layoutDirection = static_cast( Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get() ); + Dali::LayoutDirection::Type layoutDirection = mController->GetLayoutDirection(self); - const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection ); + const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection); - if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) - || mTextUpdateNeeded ) + if((Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType)) || mTextUpdateNeeded) { - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this ); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::OnRelayout IsAutoScrollEnabled[%s] [%p]\n", (mController->IsAutoScrollEnabled()) ? "true" : "false", this); // Update the visual - TextVisual::EnableRendererUpdate( mVisual ); + TextVisual::EnableRendererUpdate(mVisual); // Support Right-To-Left of padding - if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection ) + if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection) { - std::swap( padding.start, padding.end ); + std::swap(padding.start, padding.end); } // Calculate the size of the visual that can fit the text Size layoutSize = mController->GetTextModel()->GetLayoutSize(); - layoutSize.x = contentSize.x; + layoutSize.x = contentSize.x; const Vector2& shadowOffset = mController->GetTextModel()->GetShadowOffset(); - if ( shadowOffset.y > Math::MACHINE_EPSILON_1 ) + if(shadowOffset.y > Math::MACHINE_EPSILON_1) { layoutSize.y += shadowOffset.y; } float outlineWidth = mController->GetTextModel()->GetOutlineWidth(); layoutSize.y += outlineWidth * 2.0f; - layoutSize.y = std::min( layoutSize.y, contentSize.y ); + layoutSize.y = std::min(layoutSize.y, contentSize.y); // Calculate the offset for vertical alignment only, as the layout engine will do the horizontal alignment. Vector2 alignmentOffset; alignmentOffset.x = 0.0f; - alignmentOffset.y = ( contentSize.y - layoutSize.y ) * VERTICAL_ALIGNMENT_TABLE[mController->GetVerticalAlignment()]; + alignmentOffset.y = (contentSize.y - layoutSize.y) * VERTICAL_ALIGNMENT_TABLE[mController->GetVerticalAlignment()]; 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_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 ); - mVisual.SetTransformAndSize( visualTransform, size ); - - if ( mController->IsAutoScrollEnabled() ) + 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_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); + mVisual.SetTransformAndSize(visualTransform, size); + + if(mController->IsAutoScrollEnabled()) { SetUpAutoScrolling(); } @@ -930,83 +1002,88 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container ) void TextLabel::RequestTextRelayout() { RelayoutRequest(); - Toolkit::DevelControl::RequestLayout( *this ); + // Signal that a Relayout may be needed } void TextLabel::SetUpAutoScrolling() { - const Size& controlSize = mController->GetView().GetControlSize(); - const Size textNaturalSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only. - const Text::CharacterDirection direction = mController->GetAutoScrollDirection(); + const Size& controlSize = mController->GetView().GetControlSize(); + const Size textNaturalSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only. + const Text::CharacterDirection direction = mController->GetAutoScrollDirection(); - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling textNaturalSize[%f,%f] controlSize[%f,%f]\n", - textNaturalSize.x,textNaturalSize.y , controlSize.x,controlSize.y ); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling textNaturalSize[%f,%f] controlSize[%f,%f]\n", textNaturalSize.x, textNaturalSize.y, controlSize.x, controlSize.y); - if ( !mTextScroller ) + if(!mTextScroller) { - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n" ); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n"); // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults - mTextScroller = Text::TextScroller::New( *this ); + mTextScroller = Text::TextScroller::New(*this); } // Calculate the actual gap before scrolling wraps. - int textPadding = std::max( controlSize.x - textNaturalSize.x, 0.0f ); - float wrapGap = std::max( mTextScroller->GetGap(), textPadding ); + int textPadding = std::max(controlSize.x - textNaturalSize.x, 0.0f); + float wrapGap = std::max(mTextScroller->GetGap(), textPadding); Vector2 textureSize = textNaturalSize + Vector2(wrapGap, 0.0f); // Add the gap as a part of the texture // Create a texture of the text for scrolling - Size verifiedSize = textureSize; + Size verifiedSize = textureSize; const int maxTextureSize = Dali::GetMaxTextureSize(); //if the texture size width exceed maxTextureSize, modify the visual model size and enabled the ellipsis - if( verifiedSize.width > maxTextureSize ) + bool actualellipsis = mController->IsTextElideEnabled(); + if(verifiedSize.width > maxTextureSize) { verifiedSize.width = maxTextureSize; - if( textNaturalSize.width > maxTextureSize ) + if(textNaturalSize.width > maxTextureSize) { - mController->SetTextElideEnabled( true ); + mController->SetTextElideEnabled(true); } - GetHeightForWidth( maxTextureSize ); - wrapGap = std::max( maxTextureSize - textNaturalSize.width, 0.0f ); + GetHeightForWidth(maxTextureSize); + wrapGap = std::max(maxTextureSize - textNaturalSize.width, 0.0f); } - Text::TypesetterPtr typesetter = Text::Typesetter::New( mController->GetTextModel() ); + Text::TypesetterPtr typesetter = Text::Typesetter::New(mController->GetTextModel()); - PixelData data = typesetter->Render( verifiedSize, mController->GetTextDirection(), Text::Typesetter::RENDER_TEXT_AND_STYLES, true, Pixel::RGBA8888 ); // ignore the horizontal alignment - Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, - data.GetPixelFormat(), - data.GetWidth(), - data.GetHeight() ); - texture.Upload( data ); + PixelData data = typesetter->Render(verifiedSize, mController->GetTextDirection(), Text::Typesetter::RENDER_TEXT_AND_STYLES, true, Pixel::RGBA8888); // ignore the horizontal alignment + Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, + data.GetPixelFormat(), + data.GetWidth(), + data.GetHeight()); + texture.Upload(data); TextureSet textureSet = TextureSet::New(); - textureSet.SetTexture( 0u, texture ); + textureSet.SetTexture(0u, texture); // Filter mode needs to be set to linear to produce better quality while scaling. Sampler sampler = Sampler::New(); - sampler.SetFilterMode( FilterMode::LINEAR, FilterMode::LINEAR ); - sampler.SetWrapMode( Dali::WrapMode::DEFAULT, Dali::WrapMode::REPEAT, Dali::WrapMode::DEFAULT ); // Wrap the texture in the x direction - textureSet.SetSampler( 0u, sampler ); + sampler.SetFilterMode(FilterMode::LINEAR, FilterMode::LINEAR); + sampler.SetWrapMode(Dali::WrapMode::DEFAULT, Dali::WrapMode::REPEAT, Dali::WrapMode::DEFAULT); // Wrap the texture in the x direction + textureSet.SetSampler(0u, sampler); // Set parameters for scrolling - Renderer renderer = static_cast( GetImplementation( mVisual ) ).GetRenderer(); - mTextScroller->SetParameters( Self(), renderer, textureSet, controlSize, verifiedSize, wrapGap, direction, mController->GetHorizontalAlignment(), mController->GetVerticalAlignment() ); + Renderer renderer = static_cast(GetImplementation(mVisual)).GetRenderer(); + mTextScroller->SetParameters(Self(), renderer, textureSet, controlSize, verifiedSize, wrapGap, direction, mController->GetHorizontalAlignment(), mController->GetVerticalAlignment()); + mController->SetTextElideEnabled(actualellipsis); } void TextLabel::ScrollingFinished() { // Pure Virtual from TextScroller Interface - DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n"); - mController->SetAutoScrollEnabled( false ); - mController->SetTextElideEnabled( true ); + DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n"); + mController->SetAutoScrollEnabled(false); RequestTextRelayout(); } +void TextLabel::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type) +{ + mController->ChangedLayoutDirection(); +} + TextLabel::TextLabel() -: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), - mRenderingBackend( DEFAULT_RENDERING_BACKEND ), - mTextUpdateNeeded( false ) +: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)), + mRenderingBackend(DEFAULT_RENDERING_BACKEND), + mTextUpdateNeeded(false) { } @@ -1014,6 +1091,187 @@ TextLabel::~TextLabel() { } +std::string TextLabel::AccessibleImpl::GetNameRaw() +{ + auto self = Toolkit::TextLabel::DownCast(Self()); + return self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get(); +} + +Property::Index TextLabel::AccessibleImpl::GetNamePropertyIndex() +{ + return Toolkit::TextLabel::Property::TEXT; +} + +std::string TextLabel::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) +{ + if(endOffset <= startOffset) + { + return {}; + } + + auto self = Toolkit::TextLabel::DownCast(Self()); + auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get(); + + if(startOffset > text.size() || endOffset > text.size()) + { + return {}; + } + + return text.substr(startOffset, endOffset - startOffset); +} + +size_t TextLabel::AccessibleImpl::GetCharacterCount() +{ + auto self = Toolkit::TextLabel::DownCast(Self()); + auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get(); + + return text.size(); +} + +size_t TextLabel::AccessibleImpl::GetCursorOffset() +{ + return {}; +} + +bool TextLabel::AccessibleImpl::SetCursorOffset(size_t offset) +{ + return {}; +} + +Dali::Accessibility::Range TextLabel::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) +{ + auto self = Toolkit::TextLabel::DownCast(Self()); + auto text = self.GetProperty(Toolkit::TextLabel::Property::TEXT).Get(); + auto textSize = text.size(); + + auto range = Dali::Accessibility::Range{}; + + switch(boundary) + { + case Dali::Accessibility::TextBoundary::CHARACTER: + { + if(offset < textSize) + { + range.content = text[offset]; + range.startOffset = offset; + range.endOffset = offset + 1; + } + break; + } + case Dali::Accessibility::TextBoundary::WORD: + case Dali::Accessibility::TextBoundary::LINE: + { + auto textString = text.c_str(); + auto breaks = std::vector(textSize, 0); + + if(boundary == Dali::Accessibility::TextBoundary::WORD) + { + Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast(textString), textSize, "", breaks.data()); + } + else + { + Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast(textString), textSize, "", breaks.data()); + } + + auto index = 0u; + auto counter = 0u; + while(index < textSize && counter <= offset) + { + auto start = index; + if(breaks[index]) + { + while(breaks[index]) + { + index++; + } + counter++; + } + else + { + if(boundary == Dali::Accessibility::TextBoundary::WORD) + { + index++; + } + if(boundary == Dali::Accessibility::TextBoundary::LINE) + { + counter++; + } + } + + if((counter > 0) && ((counter - 1) == offset)) + { + range.content = text.substr(start, index - start + 1); + range.startOffset = start; + range.endOffset = index + 1; + } + + if(boundary == Dali::Accessibility::TextBoundary::LINE) + { + index++; + } + } + break; + } + case Dali::Accessibility::TextBoundary::SENTENCE: + { + /* not supported by default */ + break; + } + case Dali::Accessibility::TextBoundary::PARAGRAPH: + { + /* Paragraph is not supported by libunibreak library */ + break; + } + default: + break; + } + + return range; +} + +Dali::Accessibility::Range TextLabel::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if(selectionIndex > 0) + { + return {}; + } + + auto self = Toolkit::TextLabel::DownCast(Self()); + auto controller = Dali::Toolkit::GetImpl(self).GetTextController(); + std::string value{}; + controller->RetrieveSelection(value); + auto indices = controller->GetSelectionIndexes(); + + return {static_cast(indices.first), static_cast(indices.second), value}; +} + +bool TextLabel::AccessibleImpl::RemoveSelection(size_t selectionIndex) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if(selectionIndex > 0) + { + return false; + } + + auto self = Toolkit::TextLabel::DownCast(Self()); + Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0); + return true; +} + +bool TextLabel::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) +{ + // Since DALi supports only one selection indexes higher than 0 are ignored + if(selectionIndex > 0) + { + return false; + } + + auto self = Toolkit::TextLabel::DownCast(Self()); + Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset); + return true; +} + } // namespace Internal } // namespace Toolkit