X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller.cpp;h=7cc88314bf7692674b73fb889dbb5795f6f835cd;hp=6e4d3616de7dc053b9bca1d93916f0b987d0f747;hb=c427acac5f2616578c05987c99e7b430c9ab0137;hpb=3ea3bc2160dead96a69eae4c12175b6bd760a006 diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 6e4d361..7cc8831 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -28,13 +28,16 @@ // INTERNAL INCLUDES #include +#include #include #include #include +#include #include #include #include #include +#include namespace { @@ -42,8 +45,6 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); #endif -constexpr float MAX_FLOAT = std::numeric_limits::max(); - const std::string EMPTY_STRING(""); template @@ -116,7 +117,6 @@ void UpdateCursorPosition(Dali::Toolkit::Text::EventData* eventData) namespace Dali::Toolkit::Text { - void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext) { if(!decorator) @@ -137,7 +137,7 @@ void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType) mImpl->mMetrics->SetGlyphType(glyphType); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -169,39 +169,17 @@ bool Controller::HasAnchors() const void Controller::SetAutoScrollEnabled(bool enable) { 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); +} - if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX) - { - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | - LAYOUT | - ALIGN | - UPDATE_LAYOUT_SIZE | - REORDER); - - if(enable) - { - DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n"); - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | UPDATE_DIRECTION); - } - else - { - DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n"); - } - - mImpl->mIsAutoScrollEnabled = enable; - mImpl->RequestRelayout(); - } - else - { - DALI_LOG_WARNING("Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n"); - mImpl->mIsAutoScrollEnabled = false; - } +void Controller::SetAutoScrollMaxTextureExceeded(bool exceed) +{ + mImpl->mIsAutoScrollMaxTextureExceeded = exceed; } bool Controller::IsAutoScrollEnabled() const { DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false"); - return mImpl->mIsAutoScrollEnabled; } @@ -271,17 +249,7 @@ int Controller::GetMaximumNumberOfCharacters() void Controller::SetEnableCursorBlink(bool enable) { - DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled"); - - if(mImpl->mEventData) - { - mImpl->mEventData->mCursorBlinkEnabled = enable; - - if(!enable && mImpl->mEventData->mDecorator) - { - mImpl->mEventData->mDecorator->StopCursorBlink(); - } - } + mImpl->SetEnableCursorBlink(enable); } bool Controller::GetEnableCursorBlink() const @@ -291,27 +259,7 @@ bool Controller::GetEnableCursorBlink() const void Controller::SetMultiLineEnabled(bool enable) { - const Layout::Engine::Type layout = enable ? Layout::Engine::MULTI_LINE_BOX : Layout::Engine::SINGLE_LINE_BOX; - - if(layout != mImpl->mLayoutEngine.GetLayout()) - { - // Set the layout type. - mImpl->mLayoutEngine.SetLayout(layout); - - // Set the flags to redo the layout operations - const OperationsMask layoutOperations = static_cast(LAYOUT | - UPDATE_LAYOUT_SIZE | - ALIGN | - REORDER); - - mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true; - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | layoutOperations); - - // Need to recalculate natural size - mImpl->mRecalculateNaturalSize = true; - - mImpl->RequestRelayout(); - } + mImpl->SetMultiLineEnabled(enable); } bool Controller::IsMultiLineEnabled() const @@ -321,28 +269,7 @@ bool Controller::IsMultiLineEnabled() const void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment) { - if(alignment != mImpl->mModel->mHorizontalAlignment) - { - // Set the alignment. - mImpl->mModel->mHorizontalAlignment = alignment; - - // Set the flag to redo the alignment operation. - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | ALIGN); - - if(mImpl->mEventData) - { - mImpl->mEventData->mUpdateAlignment = true; - - // Update the cursor if it's in editing mode - if(EventData::IsEditingState(mImpl->mEventData->mState)) - { - mImpl->ChangeState(EventData::EDITING); - mImpl->mEventData->mUpdateCursorPosition = true; - } - } - - mImpl->RequestRelayout(); - } + mImpl->SetHorizontalAlignment(alignment); } Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const @@ -352,13 +279,7 @@ Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment) { - if(alignment != mImpl->mModel->mVerticalAlignment) - { - // Set the alignment. - mImpl->mModel->mVerticalAlignment = alignment; - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | ALIGN); - mImpl->RequestRelayout(); - } + mImpl->SetVerticalAlignment(alignment); } VerticalAlignment::Type Controller::GetVerticalAlignment() const @@ -398,15 +319,7 @@ void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection) Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const { - if(mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::LOCALE || - (mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::INHERIT && !mImpl->mIsLayoutDirectionChanged)) - { - return static_cast(DevelWindow::Get(actor).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get()); - } - else - { - return static_cast(actor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get()); - } + return mImpl->GetLayoutDirection(actor); } bool Controller::IsShowingRealText() const @@ -416,31 +329,7 @@ bool Controller::IsShowingRealText() const void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode) { - if(lineWrapMode != mImpl->mModel->mLineWrapMode) - { - // Update Text layout for applying wrap mode - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | - ALIGN | - LAYOUT | - UPDATE_LAYOUT_SIZE | - REORDER); - - if((mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || - (mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) // hyphen is treated as line break - { - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | GET_LINE_BREAKS); - } - - // Set the text wrap mode. - mImpl->mModel->mLineWrapMode = lineWrapMode; - - mImpl->mTextUpdateInfo.mCharacterIndex = 0u; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); - - // Request relayout - mImpl->RequestRelayout(); - } + mImpl->SetLineWrapMode(lineWrapMode); } Text::LineWrap::Mode Controller::GetLineWrapMode() const @@ -469,6 +358,16 @@ bool Controller::IsTextFitEnabled() const return mImpl->mTextFitEnabled; } +void Controller::SetTextFitChanged(bool changed) +{ + mImpl->mTextFitChanged = changed; +} + +bool Controller::IsTextFitChanged() const +{ + return mImpl->mTextFitChanged; +} + void Controller::SetTextFitMinSize(float minSize, FontSizeType type) { mImpl->mTextFitMinSize = (type == POINT_SIZE) ? minSize : ConvertPixelToPoint(minSize); @@ -509,6 +408,11 @@ Vector2 Controller::GetTextFitContentSize() const return mImpl->mTextFitContentSize; } +float Controller::GetTextFitPointSize() const +{ + return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFitPointSize : 0.0f; +} + void Controller::SetPlaceholderTextElideEnabled(bool enabled) { PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled); @@ -566,15 +470,7 @@ void Controller::SetText(const std::string& text) void Controller::GetText(std::string& text) const { - if(!mImpl->IsShowingPlaceholderText()) - { - // Retrieves the text string. - mImpl->GetText(0u, text); - } - else - { - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this); - } + mImpl->GetText(text); } void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text) @@ -589,17 +485,7 @@ void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) con void Controller::UpdateAfterFontChange(const std::string& newDefaultFont) { - DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n"); - - if(!mImpl->mFontDefaults->familyDefined) // If user defined font then should not update when system font changes - { - DALI_LOG_INFO(gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str()); - mImpl->mFontDefaults->mFontDescription.family = newDefaultFont; - - ClearFontData(); - - mImpl->RequestRelayout(); - } + mImpl->UpdateAfterFontChange(newDefaultFont); } void Controller::RetrieveSelection(std::string& selectedText) const @@ -639,7 +525,7 @@ void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily) UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -670,7 +556,7 @@ void Controller::SetDefaultFontWeight(FontWeight weight) UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -711,7 +597,7 @@ void Controller::SetDefaultFontWidth(FontWidth width) UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -752,7 +638,7 @@ void Controller::SetDefaultFontSlant(FontSlant slant) UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -786,11 +672,14 @@ void Controller::SetFontSizeScale(float scale) { mImpl->mFontSizeScale = scale; + // No relayout is required + if(!mImpl->mFontSizeScaleEnabled) return; + // Update the cursor position if it's in editing mode UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -800,6 +689,24 @@ float Controller::GetFontSizeScale() const return mImpl->mFontDefaults ? mImpl->mFontSizeScale : 1.0f; } +void Controller::SetFontSizeScaleEnabled(bool enabled) +{ + mImpl->mFontSizeScaleEnabled = enabled; + + // Update the cursor position if it's in editing mode + UpdateCursorPosition(mImpl->mEventData); + + // Clear the font-specific data + mImpl->ClearFontData(); + + mImpl->RequestRelayout(); +} + +bool Controller::IsFontSizeScaleEnabled() const +{ + return mImpl->mFontSizeScaleEnabled; +} + void Controller::SetDefaultFontSize(float fontSize, FontSizeType type) { EnsureCreated(mImpl->mFontDefaults); @@ -811,7 +718,7 @@ void Controller::SetDefaultFontSize(float fontSize, FontSizeType type) UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -837,15 +744,7 @@ float Controller::GetPlaceholderTextFontSize(FontSizeType type) const void Controller::SetDefaultColor(const Vector4& color) { - mImpl->mTextColor = color; - - if(!mImpl->IsShowingPlaceholderText()) - { - mImpl->mModel->mVisualModel->SetTextColor(color); - mImpl->mModel->mLogicalModel->mColorRuns.Clear(); - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | COLOR); - mImpl->RequestRelayout(); - } + mImpl->SetDefaultColor(color); } const Vector4& Controller::GetDefaultColor() const @@ -853,6 +752,26 @@ const Vector4& Controller::GetDefaultColor() const return mImpl->mTextColor; } +void Controller::SetDisabledColorOpacity(float opacity) +{ + mImpl->mDisabledColorOpacity = opacity; +} + +float Controller::GetDisabledColorOpacity() const +{ + return mImpl->mDisabledColorOpacity; +} + +void Controller::SetUserInteractionEnabled(bool enabled) +{ + mImpl->SetUserInteractionEnabled(enabled); +} + +bool Controller::IsUserInteractionEnabled() const +{ + return mImpl->mIsUserInteractionEnabled; +} + void Controller::SetPlaceholderTextColor(const Vector4& textColor) { PlaceholderHandler::SetPlaceholderTextColor(*this, textColor); @@ -932,6 +851,42 @@ float Controller::GetUnderlineHeight() const return mImpl->mModel->mVisualModel->GetUnderlineHeight(); } +void Controller::SetUnderlineType(Text::Underline::Type type) +{ + mImpl->mModel->mVisualModel->SetUnderlineType(type); + + mImpl->RequestRelayout(); +} + +Text::Underline::Type Controller::GetUnderlineType() const +{ + return mImpl->mModel->mVisualModel->GetUnderlineType(); +} + +void Controller::SetDashedUnderlineWidth(float width) +{ + mImpl->mModel->mVisualModel->SetDashedUnderlineWidth(width); + + mImpl->RequestRelayout(); +} + +float Controller::GetDashedUnderlineWidth() const +{ + return mImpl->mModel->mVisualModel->GetDashedUnderlineWidth(); +} + +void Controller::SetDashedUnderlineGap(float gap) +{ + mImpl->mModel->mVisualModel->SetDashedUnderlineGap(gap); + + mImpl->RequestRelayout(); +} + +float Controller::GetDashedUnderlineGap() const +{ + return mImpl->mModel->mVisualModel->GetDashedUnderlineGap(); +} + void Controller::SetOutlineColor(const Vector4& color) { mImpl->mModel->mVisualModel->SetOutlineColor(color); @@ -998,34 +953,9 @@ const std::string& Controller::GetDefaultOutlineProperties() const return mImpl->mOutlineDefaults ? mImpl->mOutlineDefaults->properties : EMPTY_STRING; } -void Controller::RelayoutForNewLineSize() -{ - // relayout all characters - mImpl->mTextUpdateInfo.mCharacterIndex = 0; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | LAYOUT); - - //remove selection - if(mImpl->mEventData && mImpl->mEventData->mState == EventData::SELECTING) - { - mImpl->ChangeState(EventData::EDITING); - } - - mImpl->RequestRelayout(); -} - bool Controller::SetDefaultLineSpacing(float lineSpacing) { - if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000) - { - mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing); - mImpl->mRecalculateNaturalSize = true; - - RelayoutForNewLineSize(); - return true; - } - return false; + return mImpl->SetDefaultLineSpacing(lineSpacing); } float Controller::GetDefaultLineSpacing() const @@ -1035,15 +965,7 @@ float Controller::GetDefaultLineSpacing() const bool Controller::SetDefaultLineSize(float lineSize) { - if(std::fabs(lineSize - mImpl->mLayoutEngine.GetDefaultLineSize()) > Math::MACHINE_EPSILON_1000) - { - mImpl->mLayoutEngine.SetDefaultLineSize(lineSize); - mImpl->mRecalculateNaturalSize = true; - - RelayoutForNewLineSize(); - return true; - } - return false; + return mImpl->SetDefaultLineSize(lineSize); } float Controller::GetDefaultLineSize() const @@ -1051,54 +973,24 @@ float Controller::GetDefaultLineSize() const return mImpl->mLayoutEngine.GetDefaultLineSize(); } -void Controller::SetInputColor(const Vector4& color) +bool Controller::SetRelativeLineSize(float relativeLineSize) { - if(mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.textColor = color; - mImpl->mEventData->mInputStyle.isDefaultColor = false; + return mImpl->SetRelativeLineSize(relativeLineSize); +} - if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState) - { - if(EventData::SELECTING == mImpl->mEventData->mState) - { - const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition; - - // Get start and end position of selection - const CharacterIndex startOfSelectedText = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition; - const Length lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText; - - // Add the color run. - const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count(); - mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u); - - ColorRun& colorRun = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns); - colorRun.color = color; - colorRun.characterRun.characterIndex = startOfSelectedText; - colorRun.characterRun.numberOfCharacters = lengthOfSelectedText; - - mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText; - } - else - { - mImpl->mTextUpdateInfo.mCharacterIndex = 0; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); - } - - // Request to relayout. - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | COLOR); - mImpl->RequestRelayout(); - } - } +float Controller::GetRelativeLineSize() const +{ + return mImpl->GetRelativeLineSize(); +} + +void Controller::SetInputColor(const Vector4& color) +{ + InputProperties::SetInputColor(*this, color); } const Vector4& Controller::GetInputColor() const { - // Return event text input color if we have it, otherwise just return the default text's color - return mImpl->mEventData ? mImpl->mEventData->mInputStyle.textColor : mImpl->mTextColor; + return InputProperties::GetInputColor(*this); } void Controller::SetInputFontFamily(const std::string& fontFamily) @@ -1168,81 +1060,62 @@ float Controller::GetInputFontPointSize() const void Controller::SetInputLineSpacing(float lineSpacing) { - if(mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.lineSpacing = lineSpacing; - mImpl->mEventData->mInputStyle.isLineSpacingDefined = true; - } + InputProperties::SetInputLineSpacing(*this, lineSpacing); } float Controller::GetInputLineSpacing() const { - return mImpl->mEventData ? mImpl->mEventData->mInputStyle.lineSpacing : 0.0f; + return InputProperties::GetInputLineSpacing(*this); } void Controller::SetInputShadowProperties(const std::string& shadowProperties) { - if(mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties; - } + InputProperties::SetInputShadowProperties(*this, shadowProperties); } const std::string& Controller::GetInputShadowProperties() const { - return mImpl->mEventData ? mImpl->mEventData->mInputStyle.shadowProperties : EMPTY_STRING; + return InputProperties::GetInputShadowProperties(*this); } void Controller::SetInputUnderlineProperties(const std::string& underlineProperties) { - if(mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties; - } + InputProperties::SetInputUnderlineProperties(*this, underlineProperties); } const std::string& Controller::GetInputUnderlineProperties() const { - return mImpl->mEventData ? mImpl->mEventData->mInputStyle.underlineProperties : EMPTY_STRING; + return InputProperties::GetInputUnderlineProperties(*this); } void Controller::SetInputEmbossProperties(const std::string& embossProperties) { - if(mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.embossProperties = embossProperties; - } + InputProperties::SetInputEmbossProperties(*this, embossProperties); } const std::string& Controller::GetInputEmbossProperties() const { - return mImpl->mEventData ? mImpl->mEventData->mInputStyle.embossProperties : GetDefaultEmbossProperties(); + return InputProperties::GetInputEmbossProperties(*this); } void Controller::SetInputOutlineProperties(const std::string& outlineProperties) { - if(mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties; - } + InputProperties::SetInputOutlineProperties(*this, outlineProperties); } const std::string& Controller::GetInputOutlineProperties() const { - return mImpl->mEventData ? mImpl->mEventData->mInputStyle.outlineProperties : GetDefaultOutlineProperties(); + return InputProperties::GetInputOutlineProperties(*this); } void Controller::SetInputModePassword(bool passwordInput) { - if(mImpl->mEventData) - { - mImpl->mEventData->mPasswordInput = passwordInput; - } + InputProperties::SetInputModePassword(*this, passwordInput); } bool Controller::IsInputModePassword() { - return mImpl->mEventData && mImpl->mEventData->mPasswordInput; + return InputProperties::IsInputModePassword(*this); } void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action) @@ -1311,6 +1184,65 @@ void Controller::FontStyleSetByString(bool setByString) mImpl->mFontStyleSetByString = setByString; } +void Controller::SetStrikethroughHeight(float height) +{ + mImpl->mModel->mVisualModel->SetStrikethroughHeight(height); + + mImpl->RequestRelayout(); +} + +float Controller::GetStrikethroughHeight() const +{ + return mImpl->mModel->mVisualModel->GetStrikethroughHeight(); +} + +void Controller::SetStrikethroughColor(const Vector4& color) +{ + mImpl->mModel->mVisualModel->SetStrikethroughColor(color); + + mImpl->RequestRelayout(); +} + +const Vector4& Controller::GetStrikethroughColor() const +{ + return mImpl->mModel->mVisualModel->GetStrikethroughColor(); +} + +void Controller::SetStrikethroughEnabled(bool enabled) +{ + mImpl->mModel->mVisualModel->SetStrikethroughEnabled(enabled); + + mImpl->RequestRelayout(); +} + +bool Controller::IsStrikethroughEnabled() const +{ + return mImpl->mModel->mVisualModel->IsStrikethroughEnabled(); +} + +void Controller::SetInputStrikethroughProperties(const std::string& strikethroughProperties) +{ + if(NULL != mImpl->mEventData) + { + mImpl->mEventData->mInputStyle.strikethroughProperties = strikethroughProperties; + } +} + +const std::string& Controller::GetInputStrikethroughProperties() const +{ + return (NULL != mImpl->mEventData) ? mImpl->mEventData->mInputStyle.strikethroughProperties : EMPTY_STRING; +} + +bool Controller::IsStrikethroughSetByString() +{ + return mImpl->mStrikethroughSetByString; +} + +void Controller::StrikethroughSetByString(bool setByString) +{ + mImpl->mStrikethroughSetByString = setByString; +} + Layout::Engine& Controller::GetLayoutEngine() { return mImpl->mLayoutEngine; @@ -1417,45 +1349,9 @@ void Controller::GetPlaceholderProperty(Property::Map& map) Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection() { // Make sure the model is up-to-date before layouting - ProcessModifyEvents(); - - if(mImpl->mUpdateTextDirection) - { - // Operations that can be done only once until the text changes. - const OperationsMask onlyOnceOperations = static_cast(CONVERT_TO_UTF32 | - GET_SCRIPTS | - VALIDATE_FONTS | - GET_LINE_BREAKS | - BIDI_INFO | - SHAPE_TEXT | - GET_GLYPH_METRICS); - - // Set the update info to relayout the whole text. - mImpl->mTextUpdateInfo.mParagraphCharacterIndex = 0u; - mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count(); - - // Make sure the model is up-to-date before layouting - mImpl->UpdateModel(onlyOnceOperations); - - Vector3 naturalSize; - DoRelayout(Size(MAX_FLOAT, MAX_FLOAT), - static_cast(onlyOnceOperations | - LAYOUT | REORDER | UPDATE_DIRECTION), - naturalSize.GetVectorXY()); - - // Do not do again the only once operations. - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending & ~onlyOnceOperations); - - // Clear the update info. This info will be set the next time the text is updated. - mImpl->mTextUpdateInfo.Clear(); - - // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT. - mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true; - - mImpl->mUpdateTextDirection = false; - } + EventHandler::ProcessModifyEvents(*this); - return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT; + return mImpl->GetTextDirection(); } Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const @@ -1479,6 +1375,19 @@ void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition); } +void Controller::SetCharacterSpacing(float characterSpacing) +{ + mImpl->mModel->mVisualModel->SetCharacterSpacing(characterSpacing); + + mImpl->RelayoutAllCharacters(); + mImpl->RequestRelayout(); +} + +const float Controller::GetCharacterSpacing() const +{ + return mImpl->mModel->mVisualModel->GetCharacterSpacing(); +} + Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection) { return Relayouter::Relayout(*this, size, layoutDirection); @@ -1489,25 +1398,60 @@ void Controller::RequestRelayout() mImpl->RequestRelayout(); } -bool Controller::IsInputStyleChangedSignalsQueueEmpty() +Vector Controller::GetTextSize(CharacterIndex startIndex, CharacterIndex endIndex) +{ + Vector sizesList; + Vector positionsList; + + GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizesList, positionsList); + return sizesList; +} + +Vector Controller::GetTextPosition(CharacterIndex startIndex, CharacterIndex endIndex) { - return (NULL == mImpl->mEventData) || (0u == mImpl->mEventData->mInputStyleChangedQueue.Count()); + Vector sizesList; + Vector positionsList; + + GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizesList, positionsList); + return positionsList; } -void Controller::ProcessInputStyleChangedSignals() +Rect<> Controller::GetTextBoundingRectangle(CharacterIndex startIndex, CharacterIndex endIndex) { - if(mImpl->mEventData) + Vector sizeList; + Vector positionList; + + GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizeList, positionList); + + if(sizeList.Empty() || sizeList.Size() != positionList.Size()) { - if(mImpl->mEditableControlInterface) - { - // Emit the input style changed signal for each mask - std::for_each(mImpl->mEventData->mInputStyleChangedQueue.begin(), - mImpl->mEventData->mInputStyleChangedQueue.end(), - [&](const auto mask) { mImpl->mEditableControlInterface->InputStyleChanged(mask); } ); - } + return {0, 0, 0, 0}; + } + + auto minX = positionList[0].x; + auto minY = positionList[0].y; + auto maxRight = positionList[0].x + sizeList[0].x; + auto maxBottom = positionList[0].y + sizeList[0].y; - mImpl->mEventData->mInputStyleChangedQueue.Clear(); + for(unsigned int i = 1; i < sizeList.Size(); i++) + { + minX = std::min(minX, positionList[i].x); + minY = std::min(minY, positionList[i].y); + maxRight = std::max(maxRight, positionList[i].x + sizeList[i].x); + maxBottom = std::max(maxBottom, positionList[i].y + sizeList[i].y); } + + return {minX, minY, maxRight - minX, maxBottom - minY}; +} + +bool Controller::IsInputStyleChangedSignalsQueueEmpty() +{ + return mImpl->IsInputStyleChangedSignalsQueueEmpty(); +} + +void Controller::ProcessInputStyleChangedSignals() +{ + mImpl->ProcessInputStyleChangedSignals(); } void Controller::KeyboardFocusGainEvent() @@ -1550,11 +1494,6 @@ void Controller::SelectEvent(float x, float y, SelectionType selectType) EventHandler::SelectEvent(*this, x, y, selectType); } -void Controller::SelectEvent(const uint32_t start, const uint32_t end, SelectionType selectType) -{ - EventHandler::SelectEvent(*this, start, end, selectType); -} - void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end) { if(mImpl->mEventData) @@ -1564,7 +1503,7 @@ void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* en mImpl->mEventData->mIsRightHandleSelected = true; mImpl->SetTextSelectionRange(start, end); mImpl->RequestRelayout(); - KeyboardFocusGainEvent(); + EventHandler::KeyboardFocusGainEvent(*this); } } @@ -1588,7 +1527,7 @@ bool Controller::SetPrimaryCursorPosition(CharacterIndex index, bool focused) mImpl->mEventData->mCheckScrollAmount = true; if(mImpl->SetPrimaryCursorPosition(index, focused) && focused) { - KeyboardFocusGainEvent(); + EventHandler::KeyboardFocusGainEvent(*this); return true; } } @@ -1597,75 +1536,32 @@ bool Controller::SetPrimaryCursorPosition(CharacterIndex index, bool focused) void Controller::SelectWholeText() { - SelectEvent(0.f, 0.f, SelectionType::ALL); + EventHandler::SelectEvent(*this, 0.f, 0.f, SelectionType::ALL); } void Controller::SelectNone() { - SelectEvent(0.f, 0.f, SelectionType::NONE); + EventHandler::SelectEvent(*this, 0.f, 0.f, SelectionType::NONE); } void Controller::SelectText(const uint32_t start, const uint32_t end) { - SelectEvent(start, end, SelectionType::RANGE); + EventHandler::SelectEvent(*this, start, end, SelectionType::RANGE); } string Controller::GetSelectedText() const { - string text; - if(EventData::SELECTING == mImpl->mEventData->mState) - { - mImpl->RetrieveSelection(text, false); - } - return text; + return mImpl->GetSelectedText(); } string Controller::CopyText() { - string text; - mImpl->RetrieveSelection(text, false); - mImpl->SendSelectionToClipboard(false); // Text not modified - - mImpl->mEventData->mUpdateCursorPosition = true; - - mImpl->RequestRelayout(); // Cursor, Handles, Selection Highlight, Popup - - return text; + return mImpl->CopyText(); } string Controller::CutText() { - string text; - mImpl->RetrieveSelection(text, false); - - if(!IsEditable()) - { - return EMPTY_STRING; - } - - mImpl->SendSelectionToClipboard(true); // Synchronous call to modify text - mImpl->mOperationsPending = ALL_OPERATIONS; - - if((0u != mImpl->mModel->mLogicalModel->mText.Count()) || - !mImpl->IsPlaceholderAvailable()) - { - mImpl->QueueModifyEvent(ModifyEvent::TEXT_DELETED); - } - else - { - ShowPlaceholderText(); - } - - mImpl->mEventData->mUpdateCursorPosition = true; - mImpl->mEventData->mScrollAfterDelete = true; - - mImpl->RequestRelayout(); - - if(nullptr != mImpl->mEditableControlInterface) - { - mImpl->mEditableControlInterface->TextChanged(true); - } - return text; + return mImpl->CutText(); } void Controller::PasteText() @@ -1688,11 +1584,11 @@ void Controller::GetTargetSize(Vector2& targetSize) targetSize = mImpl->mModel->mVisualModel->mControlSize; } -void Controller::AddDecoration(Actor& actor, bool needsClipping) +void Controller::AddDecoration(Actor& actor, DecorationType type, bool needsClipping) { if(mImpl->mEditableControlInterface) { - mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping); + mImpl->mEditableControlInterface->AddDecoration(actor, type, needsClipping); } } @@ -1704,52 +1600,21 @@ bool Controller::IsEditable() const void Controller::SetEditable(bool editable) { mImpl->SetEditable(editable); - if(mImpl->mEventData && mImpl->mEventData->mDecorator) - { - mImpl->mEventData->mDecorator->SetEditable(editable); - } } void Controller::ScrollBy(Vector2 scroll) { - if(mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0)) - { - const Vector2& layoutSize = mImpl->mModel->mVisualModel->GetLayoutSize(); - const Vector2 currentScroll = mImpl->mModel->mScrollPosition; - - scroll.x = -scroll.x; - scroll.y = -scroll.y; - - if(fabs(scroll.x) > Math::MACHINE_EPSILON_0) - { - mImpl->mModel->mScrollPosition.x += scroll.x; - mImpl->ClampHorizontalScroll(layoutSize); - } - - if(fabs(scroll.y) > Math::MACHINE_EPSILON_0) - { - mImpl->mModel->mScrollPosition.y += scroll.y; - mImpl->ClampVerticalScroll(layoutSize); - } - - if(mImpl->mModel->mScrollPosition != currentScroll) - { - mImpl->mEventData->mDecorator->UpdatePositions(mImpl->mModel->mScrollPosition - currentScroll); - mImpl->RequestRelayout(); - } - } + mImpl->ScrollBy(scroll); } float Controller::GetHorizontalScrollPosition() { - // Scroll values are negative internally so we convert them to positive numbers - return mImpl->mEventData ? -mImpl->mModel->mScrollPosition.x : 0.0f; + return mImpl->GetHorizontalScrollPosition(); } float Controller::GetVerticalScrollPosition() { - // Scroll values are negative internally so we convert them to positive numbers - return mImpl->mEventData ? -mImpl->mModel->mScrollPosition.y : 0.0f; + return mImpl->GetVerticalScrollPosition(); } void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y) @@ -1771,116 +1636,6 @@ void Controller::DisplayTimeExpired() mImpl->RequestRelayout(); } -void Controller::InsertText(const std::string& text, Controller::InsertType type) -{ - TextUpdater::InsertText(*this, text, type); -} - -void Controller::PasteText(const std::string& stringToPaste) -{ - TextUpdater::PasteText(*this, stringToPaste); -} - -bool Controller::RemoveText(int cursorOffset, int numberOfCharacters, UpdateInputStyleType type) -{ - return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type); -} - -bool Controller::RemoveSelectedText() -{ - return TextUpdater::RemoveSelectedText(*this); -} - -void Controller::InsertTextAnchor(int numberOfCharacters, CharacterIndex previousCursorIndex) -{ - TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex); -} - -void Controller::RemoveTextAnchor(int cursorOffset, int numberOfCharacters, CharacterIndex previousCursorIndex) -{ - TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex); -} - -bool Controller::DoRelayout(const Size& size, OperationsMask operationsRequired, Size& layoutSize) -{ - return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize); -} - -void Controller::CalculateVerticalOffset(const Size& controlSize) -{ - Relayouter::CalculateVerticalOffset(*this, controlSize); -} - -void Controller::ProcessModifyEvents() -{ - EventHandler::ProcessModifyEvents(*this); -} - -void Controller::TextReplacedEvent() -{ - EventHandler::TextReplacedEvent(*this); -} - -void Controller::TextInsertedEvent() -{ - EventHandler::TextInsertedEvent(*this); -} - -void Controller::TextDeletedEvent() -{ - EventHandler::TextDeletedEvent(*this); -} - -bool Controller::DeleteEvent(int keyCode) -{ - return EventHandler::DeleteEvent(*this, keyCode); -} - -// private : Helpers. - -void Controller::ResetText() -{ - TextUpdater::ResetText(*this); -} - -void Controller::ShowPlaceholderText() -{ - PlaceholderHandler::ShowPlaceholderText(*this); -} - -void Controller::ClearFontData() -{ - if(mImpl->mFontDefaults) - { - mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID - } - - // Set flags to update the model. - mImpl->mTextUpdateInfo.mCharacterIndex = 0u; - mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters; - mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count(); - - mImpl->mTextUpdateInfo.mClearAll = true; - mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true; - mImpl->mRecalculateNaturalSize = true; - - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | - VALIDATE_FONTS | - SHAPE_TEXT | - BIDI_INFO | - GET_GLYPH_METRICS | - LAYOUT | - UPDATE_LAYOUT_SIZE | - REORDER | - ALIGN); -} - -void Controller::ClearStyleData() -{ - mImpl->mModel->mLogicalModel->mColorRuns.Clear(); - mImpl->mModel->mLogicalModel->ClearFontDescriptionRuns(); -} - void Controller::ResetCursorPosition(CharacterIndex cursorIndex) { // Reset the cursor position @@ -1898,20 +1653,7 @@ void Controller::ResetCursorPosition(CharacterIndex cursorIndex) CharacterIndex Controller::GetCursorPosition() { - if(!mImpl->mEventData) - return 0; - - return mImpl->mEventData->mPrimaryCursorPosition; -} - -void Controller::ResetScrollPosition() -{ - if(mImpl->mEventData) - { - // Reset the scroll position. - mImpl->mModel->mScrollPosition = Vector2::ZERO; - mImpl->mEventData->mScrollAfterUpdatePosition = true; - } + return mImpl->mEventData ? mImpl->mEventData->mPrimaryCursorPosition : 0; } void Controller::SetControlInterface(ControlInterface* controlInterface) @@ -1931,7 +1673,17 @@ bool Controller::ShouldClearFocusOnEscape() const Actor Controller::CreateBackgroundActor() { - return mImpl->CreateBackgroundActor(); + return CreateControllerBackgroundActor(mImpl->mView, mImpl->mModel->mVisualModel, mImpl->mModel->mLogicalModel, mImpl->mShaderBackground); +} + +void Controller::GetAnchorActors(std::vector& anchorActors) +{ + mImpl->GetAnchorActors(anchorActors); +} + +int Controller::GetAnchorIndex(size_t characterOffset) +{ + return mImpl->GetAnchorIndex(characterOffset); } Controller::Controller(ControlInterface* controlInterface,