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=a863317932719ae4edada96d398432dc6dc5082f;hb=c427acac5f2616578c05987c99e7b430c9ab0137;hpb=1cd43040ed72d023a51d8b4b6e366b1550e05301 diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index a863317..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. @@ -19,6 +19,8 @@ #include // EXTERNAL INCLUDES +#include +#include #include #include #include @@ -26,13 +28,16 @@ // INTERNAL INCLUDES #include +#include #include #include #include +#include #include #include #include #include +#include namespace { @@ -40,53 +45,78 @@ 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(""); -int ConvertPixelToPint(float pixel) +template +void EnsureCreated(Type*& object) { - unsigned int horizontalDpi = 0u; - unsigned int verticalDpi = 0u; - Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get(); - fontClient.GetDpi(horizontalDpi, verticalDpi); - - return (pixel * 72.f) / static_cast(horizontalDpi); + if(!object) + { + object = new Type(); + } } -} // namespace +template +void EnsureCreated(std::unique_ptr& object) +{ + if(!object) + { + object = std::unique_ptr(new Type()); + } +} -namespace Dali +template +void EnsureCreated(Type*& object, Arg1 arg1) { -namespace Toolkit + if(!object) + { + object = new Type(arg1); + } +} + +template +void EnsureCreated(Type*& object, Arg1 arg1, Arg2 arg2) { -namespace Text + if(!object) + { + object = new Type(arg1, arg2); + } +} + +float GetDpi() { -// public : Constructor. + unsigned int horizontalDpi = 0u; + unsigned int verticalDpi = 0u; + Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get(); + fontClient.GetDpi(horizontalDpi, verticalDpi); + return static_cast(horizontalDpi); +} -ControllerPtr Controller::New() +float ConvertPixelToPoint(float pixel) { - return ControllerPtr(new Controller()); + return pixel * 72.0f / GetDpi(); } -ControllerPtr Controller::New(ControlInterface* controlInterface) +float ConvertPointToPixel(float point) { - return ControllerPtr(new Controller(controlInterface)); + // Pixel size = Point size * DPI / 72.f + return point * GetDpi() / 72.0f; } -ControllerPtr Controller::New(ControlInterface* controlInterface, - EditableControlInterface* editableControlInterface, - SelectableControlInterface* selectableControlInterface, - AnchorControlInterface* anchorControlInterface) +void UpdateCursorPosition(Dali::Toolkit::Text::EventData* eventData) { - return ControllerPtr(new Controller(controlInterface, - editableControlInterface, - selectableControlInterface, - anchorControlInterface)); + if(eventData && Dali::Toolkit::Text::EventData::IsEditingState(eventData->mState)) + { + // Update the cursor position if it's in editing mode + eventData->mDecoratorUpdated = true; + eventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated. + } } -// public : Configure the text controller. +} // namespace +namespace Dali::Toolkit::Text +{ void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext) { if(!decorator) @@ -98,10 +128,7 @@ void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inp return; } - if(NULL == mImpl->mEventData) - { - mImpl->mEventData = new EventData(decorator, inputMethodContext); - } + EnsureCreated(mImpl->mEventData, decorator, inputMethodContext); } void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType) @@ -110,7 +137,7 @@ void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType) mImpl->mMetrics->SetGlyphType(glyphType); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } @@ -134,46 +161,25 @@ bool Controller::IsMarkupProcessorEnabled() const return mImpl->mMarkupProcessorEnabled; } +bool Controller::HasAnchors() const +{ + return (mImpl->mMarkupProcessorEnabled && mImpl->mModel->mLogicalModel->mAnchors.Count() && mImpl->IsShowingRealText()); +} + 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) - { - if(enable) - { - DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n"); - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | - LAYOUT | - ALIGN | - UPDATE_LAYOUT_SIZE | - UPDATE_DIRECTION | - REORDER); - } - else - { - DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n"); - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | - LAYOUT | - ALIGN | - UPDATE_LAYOUT_SIZE | - REORDER); - } - - 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; } @@ -185,62 +191,42 @@ CharacterDirection Controller::GetAutoScrollDirection() const float Controller::GetAutoScrollLineAlignment() const { float offset = 0.f; - - if(mImpl->mModel->mVisualModel && - (0u != mImpl->mModel->mVisualModel->mLines.Count())) + if(mImpl->mModel->mVisualModel && (0u != mImpl->mModel->mVisualModel->mLines.Count())) { offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset; } - return offset; } void Controller::SetHorizontalScrollEnabled(bool enable) { - if((NULL != mImpl->mEventData) && - mImpl->mEventData->mDecorator) + if(mImpl->mEventData && mImpl->mEventData->mDecorator) { mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable); } } + bool Controller::IsHorizontalScrollEnabled() const { - if((NULL != mImpl->mEventData) && - mImpl->mEventData->mDecorator) - { - return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled(); - } - - return false; + return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled(); } void Controller::SetVerticalScrollEnabled(bool enable) { - if((NULL != mImpl->mEventData) && - mImpl->mEventData->mDecorator) + if(mImpl->mEventData && mImpl->mEventData->mDecorator) { - if(mImpl->mEventData->mDecorator) - { - mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable); - } + mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable); } } bool Controller::IsVerticalScrollEnabled() const { - if((NULL != mImpl->mEventData) && - mImpl->mEventData->mDecorator) - { - return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled(); - } - - return false; + return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsVerticalScrollEnabled(); } void Controller::SetSmoothHandlePanEnabled(bool enable) { - if((NULL != mImpl->mEventData) && - mImpl->mEventData->mDecorator) + if(mImpl->mEventData && mImpl->mEventData->mDecorator) { mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable); } @@ -248,13 +234,7 @@ void Controller::SetSmoothHandlePanEnabled(bool enable) bool Controller::IsSmoothHandlePanEnabled() const { - if((NULL != mImpl->mEventData) && - mImpl->mEventData->mDecorator) - { - return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled(); - } - - return false; + return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled(); } void Controller::SetMaximumNumberOfCharacters(Length maxCharacters) @@ -269,53 +249,17 @@ int Controller::GetMaximumNumberOfCharacters() void Controller::SetEnableCursorBlink(bool enable) { - DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled"); - - if(NULL != mImpl->mEventData) - { - mImpl->mEventData->mCursorBlinkEnabled = enable; - - if(!enable && - mImpl->mEventData->mDecorator) - { - mImpl->mEventData->mDecorator->StopCursorBlink(); - } - } + mImpl->SetEnableCursorBlink(enable); } bool Controller::GetEnableCursorBlink() const { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mCursorBlinkEnabled; - } - - return false; + return mImpl->mEventData && mImpl->mEventData->mCursorBlinkEnabled; } 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 @@ -325,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 @@ -356,15 +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 @@ -382,14 +297,19 @@ void Controller::SetIgnoreSpacesAfterText(bool ignore) mImpl->mModel->mIgnoreSpacesAfterText = ignore; } -bool Controller::IsMatchSystemLanguageDirection() const +void Controller::ChangedLayoutDirection() +{ + mImpl->mIsLayoutDirectionChanged = true; +} + +void Controller::SetMatchLayoutDirection(DevelText::MatchLayoutDirection type) { - return mImpl->mModel->mMatchSystemLanguageDirection; + mImpl->mModel->mMatchLayoutDirection = type; } -void Controller::SetMatchSystemLanguageDirection(bool match) +DevelText::MatchLayoutDirection Controller::GetMatchLayoutDirection() const { - mImpl->mModel->mMatchSystemLanguageDirection = match; + return mImpl->mModel->mMatchLayoutDirection; } void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection) @@ -397,6 +317,11 @@ void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection) mImpl->mLayoutDirection = layoutDirection; } +Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const +{ + return mImpl->GetLayoutDirection(actor); +} + bool Controller::IsShowingRealText() const { return mImpl->IsShowingRealText(); @@ -404,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 @@ -439,6 +340,7 @@ Text::LineWrap::Mode Controller::GetLineWrapMode() const void Controller::SetTextElideEnabled(bool enabled) { mImpl->mModel->mElideEnabled = enabled; + mImpl->mModel->mVisualModel->SetTextElideEnabled(enabled); } bool Controller::IsTextElideEnabled() const @@ -456,21 +358,19 @@ 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) { - switch(type) - { - case POINT_SIZE: - { - mImpl->mTextFitMinSize = minSize; - break; - } - case PIXEL_SIZE: - { - mImpl->mTextFitMinSize = ConvertPixelToPint(minSize); - break; - } - } + mImpl->mTextFitMinSize = (type == POINT_SIZE) ? minSize : ConvertPixelToPoint(minSize); } float Controller::GetTextFitMinSize() const @@ -480,19 +380,7 @@ float Controller::GetTextFitMinSize() const void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type) { - switch(type) - { - case POINT_SIZE: - { - mImpl->mTextFitMaxSize = maxSize; - break; - } - case PIXEL_SIZE: - { - mImpl->mTextFitMaxSize = ConvertPixelToPint(maxSize); - break; - } - } + mImpl->mTextFitMaxSize = (type == POINT_SIZE) ? maxSize : ConvertPixelToPoint(maxSize); } float Controller::GetTextFitMaxSize() const @@ -502,19 +390,7 @@ float Controller::GetTextFitMaxSize() const void Controller::SetTextFitStepSize(float step, FontSizeType type) { - switch(type) - { - case POINT_SIZE: - { - mImpl->mTextFitStepSize = step; - break; - } - case PIXEL_SIZE: - { - mImpl->mTextFitStepSize = ConvertPixelToPint(step); - break; - } - } + mImpl->mTextFitStepSize = (type == POINT_SIZE) ? step : ConvertPixelToPoint(step); } float Controller::GetTextFitStepSize() const @@ -532,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); @@ -582,8 +463,6 @@ bool Controller::IsGrabHandlePopupEnabled() const return mImpl->mEventData->mGrabHandlePopupEnabled; } -// public : Update - void Controller::SetText(const std::string& text) { TextUpdater::SetText(*this, text); @@ -591,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) @@ -614,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 @@ -652,43 +513,26 @@ void Controller::SendSelectionToClipboard(bool deleteAfterSending) mImpl->SendSelectionToClipboard(deleteAfterSending); } -// public : Default style & Input style - void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily) { - if(NULL == mImpl->mFontDefaults) - { - mImpl->mFontDefaults = new FontDefaults(); - } + EnsureCreated(mImpl->mFontDefaults); mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily; DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str()); mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty(); - if(mImpl->mEventData) - { - // Update the cursor position if it's in editing mode - if(EventData::IsEditingState(mImpl->mEventData->mState)) - { - mImpl->mEventData->mDecoratorUpdated = true; - mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated. - } - } + // Update the cursor position if it's in editing mode + UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } const std::string& Controller::GetDefaultFontFamily() const { - if(NULL != mImpl->mFontDefaults) - { - return mImpl->mFontDefaults->mFontDescription.family; - } - - return EMPTY_STRING; + return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.family : EMPTY_STRING; } void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily) @@ -703,48 +547,28 @@ const std::string& Controller::GetPlaceholderFontFamily() const void Controller::SetDefaultFontWeight(FontWeight weight) { - if(NULL == mImpl->mFontDefaults) - { - mImpl->mFontDefaults = new FontDefaults(); - } + EnsureCreated(mImpl->mFontDefaults); mImpl->mFontDefaults->mFontDescription.weight = weight; mImpl->mFontDefaults->weightDefined = true; - if(mImpl->mEventData) - { - // Update the cursor position if it's in editing mode - if(EventData::IsEditingState(mImpl->mEventData->mState)) - { - mImpl->mEventData->mDecoratorUpdated = true; - mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated. - } - } + // Update the cursor position if it's in editing mode + UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } bool Controller::IsDefaultFontWeightDefined() const { - if(NULL != mImpl->mFontDefaults) - { - return mImpl->mFontDefaults->weightDefined; - } - - return false; + return mImpl->mFontDefaults && mImpl->mFontDefaults->weightDefined; } FontWeight Controller::GetDefaultFontWeight() const { - if(NULL != mImpl->mFontDefaults) - { - return mImpl->mFontDefaults->mFontDescription.weight; - } - - return TextAbstraction::FontWeight::NORMAL; + return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.weight : TextAbstraction::FontWeight::NORMAL; } void Controller::SetPlaceholderTextFontWeight(FontWeight weight) @@ -755,7 +579,6 @@ void Controller::SetPlaceholderTextFontWeight(FontWeight weight) bool Controller::IsPlaceholderTextFontWeightDefined() const { return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this); - ; } FontWeight Controller::GetPlaceholderTextFontWeight() const @@ -765,48 +588,28 @@ FontWeight Controller::GetPlaceholderTextFontWeight() const void Controller::SetDefaultFontWidth(FontWidth width) { - if(NULL == mImpl->mFontDefaults) - { - mImpl->mFontDefaults = new FontDefaults(); - } + EnsureCreated(mImpl->mFontDefaults); mImpl->mFontDefaults->mFontDescription.width = width; mImpl->mFontDefaults->widthDefined = true; - if(mImpl->mEventData) - { - // Update the cursor position if it's in editing mode - if(EventData::IsEditingState(mImpl->mEventData->mState)) - { - mImpl->mEventData->mDecoratorUpdated = true; - mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated. - } - } + // Update the cursor position if it's in editing mode + UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } bool Controller::IsDefaultFontWidthDefined() const { - if(NULL != mImpl->mFontDefaults) - { - return mImpl->mFontDefaults->widthDefined; - } - - return false; + return mImpl->mFontDefaults && mImpl->mFontDefaults->widthDefined; } FontWidth Controller::GetDefaultFontWidth() const { - if(NULL != mImpl->mFontDefaults) - { - return mImpl->mFontDefaults->mFontDescription.width; - } - - return TextAbstraction::FontWidth::NORMAL; + return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.width : TextAbstraction::FontWidth::NORMAL; } void Controller::SetPlaceholderTextFontWidth(FontWidth width) @@ -826,47 +629,28 @@ FontWidth Controller::GetPlaceholderTextFontWidth() const void Controller::SetDefaultFontSlant(FontSlant slant) { - if(NULL == mImpl->mFontDefaults) - { - mImpl->mFontDefaults = new FontDefaults(); - } + EnsureCreated(mImpl->mFontDefaults); mImpl->mFontDefaults->mFontDescription.slant = slant; mImpl->mFontDefaults->slantDefined = true; - if(mImpl->mEventData) - { - // Update the cursor position if it's in editing mode - if(EventData::IsEditingState(mImpl->mEventData->mState)) - { - mImpl->mEventData->mDecoratorUpdated = true; - mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated. - } - } + // Update the cursor position if it's in editing mode + UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } bool Controller::IsDefaultFontSlantDefined() const { - if(NULL != mImpl->mFontDefaults) - { - return mImpl->mFontDefaults->slantDefined; - } - return false; + return mImpl->mFontDefaults && mImpl->mFontDefaults->slantDefined; } FontSlant Controller::GetDefaultFontSlant() const { - if(NULL != mImpl->mFontDefaults) - { - return mImpl->mFontDefaults->mFontDescription.slant; - } - - return TextAbstraction::FontSlant::NORMAL; + return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.slant : TextAbstraction::FontSlant::NORMAL; } void Controller::SetPlaceholderTextFontSlant(FontSlant slant) @@ -888,105 +672,64 @@ void Controller::SetFontSizeScale(float scale) { mImpl->mFontSizeScale = scale; - if(mImpl->mEventData) - { - // Update the cursor position if it's in editing mode - if(EventData::IsEditingState(mImpl->mEventData->mState)) - { - mImpl->mEventData->mDecoratorUpdated = true; - mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated. - } - } + // 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(); } float Controller::GetFontSizeScale() const { - if(nullptr != mImpl->mFontDefaults) - { - return mImpl->mFontSizeScale; - } + 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(); +} - return 1.f; +bool Controller::IsFontSizeScaleEnabled() const +{ + return mImpl->mFontSizeScaleEnabled; } void Controller::SetDefaultFontSize(float fontSize, FontSizeType type) { - if(NULL == mImpl->mFontDefaults) - { - mImpl->mFontDefaults = new FontDefaults(); - } + EnsureCreated(mImpl->mFontDefaults); - switch(type) - { - case POINT_SIZE: - { - mImpl->mFontDefaults->mDefaultPointSize = fontSize; - mImpl->mFontDefaults->sizeDefined = true; - break; - } - case PIXEL_SIZE: - { - // Point size = Pixel size * 72.f / DPI - unsigned int horizontalDpi = 0u; - unsigned int verticalDpi = 0u; - TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - fontClient.GetDpi(horizontalDpi, verticalDpi); - - mImpl->mFontDefaults->mDefaultPointSize = (fontSize * 72.f) / static_cast(horizontalDpi); - mImpl->mFontDefaults->sizeDefined = true; - break; - } - } + mImpl->mFontDefaults->mDefaultPointSize = (type == POINT_SIZE) ? fontSize : ConvertPixelToPoint(fontSize); + mImpl->mFontDefaults->sizeDefined = true; - if(mImpl->mEventData) - { - // Update the cursor position if it's in editing mode - if(EventData::IsEditingState(mImpl->mEventData->mState)) - { - mImpl->mEventData->mDecoratorUpdated = true; - mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated. - } - } + // Update the cursor position if it's in editing mode + UpdateCursorPosition(mImpl->mEventData); // Clear the font-specific data - ClearFontData(); + mImpl->ClearFontData(); mImpl->RequestRelayout(); } float Controller::GetDefaultFontSize(FontSizeType type) const { - float value = 0.0f; - if(NULL != mImpl->mFontDefaults) + if(mImpl->mFontDefaults) { - switch(type) - { - case POINT_SIZE: - { - value = mImpl->mFontDefaults->mDefaultPointSize; - break; - } - case PIXEL_SIZE: - { - // Pixel size = Point size * DPI / 72.f - unsigned int horizontalDpi = 0u; - unsigned int verticalDpi = 0u; - TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - fontClient.GetDpi(horizontalDpi, verticalDpi); - - value = mImpl->mFontDefaults->mDefaultPointSize * static_cast(horizontalDpi) / 72.f; - break; - } - } - return value; + return (type == POINT_SIZE) ? mImpl->mFontDefaults->mDefaultPointSize : ConvertPointToPixel(mImpl->mFontDefaults->mDefaultPointSize); } - - return value; + return 0.0f; } void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type) @@ -1001,23 +744,32 @@ float Controller::GetPlaceholderTextFontSize(FontSizeType type) const void Controller::SetDefaultColor(const Vector4& color) { - mImpl->mTextColor = color; - - if(!mImpl->IsShowingPlaceholderText()) - { - mImpl->mModel->mVisualModel->SetTextColor(color); + mImpl->SetDefaultColor(color); +} - mImpl->mModel->mLogicalModel->mColorRuns.Clear(); +const Vector4& Controller::GetDefaultColor() const +{ + return mImpl->mTextColor; +} - mImpl->mOperationsPending = static_cast(mImpl->mOperationsPending | COLOR); +void Controller::SetDisabledColorOpacity(float opacity) +{ + mImpl->mDisabledColorOpacity = opacity; +} - mImpl->RequestRelayout(); - } +float Controller::GetDisabledColorOpacity() const +{ + return mImpl->mDisabledColorOpacity; } -const Vector4& Controller::GetDefaultColor() const +void Controller::SetUserInteractionEnabled(bool enabled) { - return mImpl->mTextColor; + mImpl->SetUserInteractionEnabled(enabled); +} + +bool Controller::IsUserInteractionEnabled() const +{ + return mImpl->mIsUserInteractionEnabled; } void Controller::SetPlaceholderTextColor(const Vector4& textColor) @@ -1033,7 +785,6 @@ const Vector4& Controller::GetPlaceholderTextColor() const void Controller::SetShadowOffset(const Vector2& shadowOffset) { mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset); - mImpl->RequestRelayout(); } @@ -1045,7 +796,6 @@ const Vector2& Controller::GetShadowOffset() const void Controller::SetShadowColor(const Vector4& shadowColor) { mImpl->mModel->mVisualModel->SetShadowColor(shadowColor); - mImpl->RequestRelayout(); } @@ -1059,7 +809,6 @@ void Controller::SetShadowBlurRadius(const float& shadowBlurRadius) if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1) { mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius); - mImpl->RequestRelayout(); } } @@ -1072,7 +821,6 @@ const float& Controller::GetShadowBlurRadius() const void Controller::SetUnderlineColor(const Vector4& color) { mImpl->mModel->mVisualModel->SetUnderlineColor(color); - mImpl->RequestRelayout(); } @@ -1084,7 +832,6 @@ const Vector4& Controller::GetUnderlineColor() const void Controller::SetUnderlineEnabled(bool enabled) { mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled); - mImpl->RequestRelayout(); } @@ -1096,7 +843,6 @@ bool Controller::IsUnderlineEnabled() const void Controller::SetUnderlineHeight(float height) { mImpl->mModel->mVisualModel->SetUnderlineHeight(height); - mImpl->RequestRelayout(); } @@ -1105,10 +851,45 @@ 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); - mImpl->RequestRelayout(); } @@ -1120,7 +901,6 @@ const Vector4& Controller::GetOutlineColor() const void Controller::SetOutlineWidth(uint16_t width) { mImpl->mModel->mVisualModel->SetOutlineWidth(width); - mImpl->RequestRelayout(); } @@ -1132,7 +912,6 @@ uint16_t Controller::GetOutlineWidth() const void Controller::SetBackgroundColor(const Vector4& color) { mImpl->mModel->mVisualModel->SetBackgroundColor(color); - mImpl->RequestRelayout(); } @@ -1144,7 +923,6 @@ const Vector4& Controller::GetBackgroundColor() const void Controller::SetBackgroundEnabled(bool enabled) { mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled); - mImpl->RequestRelayout(); } @@ -1155,53 +933,29 @@ bool Controller::IsBackgroundEnabled() const void Controller::SetDefaultEmbossProperties(const std::string& embossProperties) { - if(NULL == mImpl->mEmbossDefaults) - { - mImpl->mEmbossDefaults = new EmbossDefaults(); - } - + EnsureCreated(mImpl->mEmbossDefaults); mImpl->mEmbossDefaults->properties = embossProperties; } const std::string& Controller::GetDefaultEmbossProperties() const { - if(NULL != mImpl->mEmbossDefaults) - { - return mImpl->mEmbossDefaults->properties; - } - - return EMPTY_STRING; + return mImpl->mEmbossDefaults ? mImpl->mEmbossDefaults->properties : EMPTY_STRING; } void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties) { - if(NULL == mImpl->mOutlineDefaults) - { - mImpl->mOutlineDefaults = new OutlineDefaults(); - } - + EnsureCreated(mImpl->mOutlineDefaults); mImpl->mOutlineDefaults->properties = outlineProperties; } const std::string& Controller::GetDefaultOutlineProperties() const { - if(NULL != mImpl->mOutlineDefaults) - { - return mImpl->mOutlineDefaults->properties; - } - - return EMPTY_STRING; + return mImpl->mOutlineDefaults ? mImpl->mOutlineDefaults->properties : EMPTY_STRING; } bool Controller::SetDefaultLineSpacing(float lineSpacing) { - if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000) - { - mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing); - mImpl->mRecalculateNaturalSize = true; - return true; - } - return false; + return mImpl->SetDefaultLineSpacing(lineSpacing); } float Controller::GetDefaultLineSpacing() const @@ -1211,13 +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; - return true; - } - return false; + return mImpl->SetDefaultLineSize(lineSize); } float Controller::GetDefaultLineSize() const @@ -1225,59 +973,24 @@ float Controller::GetDefaultLineSize() const return mImpl->mLayoutEngine.GetDefaultLineSize(); } -void Controller::SetInputColor(const Vector4& color) +bool Controller::SetRelativeLineSize(float relativeLineSize) { - if(NULL != 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(); } -const Vector4& Controller::GetInputColor() const +void Controller::SetInputColor(const Vector4& color) { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mInputStyle.textColor; - } + InputProperties::SetInputColor(*this, color); +} - // Return the default text's color if there is no EventData. - return mImpl->mTextColor; +const Vector4& Controller::GetInputColor() const +{ + return InputProperties::GetInputColor(*this); } void Controller::SetInputFontFamily(const std::string& fontFamily) @@ -1347,115 +1060,67 @@ float Controller::GetInputFontPointSize() const void Controller::SetInputLineSpacing(float lineSpacing) { - if(NULL != mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.lineSpacing = lineSpacing; - mImpl->mEventData->mInputStyle.isLineSpacingDefined = true; - } + InputProperties::SetInputLineSpacing(*this, lineSpacing); } float Controller::GetInputLineSpacing() const { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mInputStyle.lineSpacing; - } - - return 0.f; + return InputProperties::GetInputLineSpacing(*this); } void Controller::SetInputShadowProperties(const std::string& shadowProperties) { - if(NULL != mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties; - } + InputProperties::SetInputShadowProperties(*this, shadowProperties); } const std::string& Controller::GetInputShadowProperties() const { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mInputStyle.shadowProperties; - } - - return EMPTY_STRING; + return InputProperties::GetInputShadowProperties(*this); } void Controller::SetInputUnderlineProperties(const std::string& underlineProperties) { - if(NULL != mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties; - } + InputProperties::SetInputUnderlineProperties(*this, underlineProperties); } const std::string& Controller::GetInputUnderlineProperties() const { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mInputStyle.underlineProperties; - } - - return EMPTY_STRING; + return InputProperties::GetInputUnderlineProperties(*this); } void Controller::SetInputEmbossProperties(const std::string& embossProperties) { - if(NULL != mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.embossProperties = embossProperties; - } + InputProperties::SetInputEmbossProperties(*this, embossProperties); } const std::string& Controller::GetInputEmbossProperties() const { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mInputStyle.embossProperties; - } - - return GetDefaultEmbossProperties(); + return InputProperties::GetInputEmbossProperties(*this); } void Controller::SetInputOutlineProperties(const std::string& outlineProperties) { - if(NULL != mImpl->mEventData) - { - mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties; - } + InputProperties::SetInputOutlineProperties(*this, outlineProperties); } const std::string& Controller::GetInputOutlineProperties() const { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mInputStyle.outlineProperties; - } - - return GetDefaultOutlineProperties(); + return InputProperties::GetInputOutlineProperties(*this); } void Controller::SetInputModePassword(bool passwordInput) { - if(NULL != mImpl->mEventData) - { - mImpl->mEventData->mPasswordInput = passwordInput; - } + InputProperties::SetInputModePassword(*this, passwordInput); } bool Controller::IsInputModePassword() { - if(NULL != mImpl->mEventData) - { - return mImpl->mEventData->mPasswordInput; - } - return false; + return InputProperties::IsInputModePassword(*this); } void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action) { - if(NULL != mImpl->mEventData) + if(mImpl->mEventData) { mImpl->mEventData->mDoubleTapAction = action; } @@ -1463,19 +1128,12 @@ void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action) Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const { - NoTextTap::Action action = NoTextTap::NO_ACTION; - - if(NULL != mImpl->mEventData) - { - action = mImpl->mEventData->mDoubleTapAction; - } - - return action; + return mImpl->mEventData ? mImpl->mEventData->mDoubleTapAction : NoTextTap::NO_ACTION; } void Controller::SetNoTextLongPressAction(NoTextTap::Action action) { - if(NULL != mImpl->mEventData) + if(mImpl->mEventData) { mImpl->mEventData->mLongPressAction = action; } @@ -1483,14 +1141,7 @@ void Controller::SetNoTextLongPressAction(NoTextTap::Action action) Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const { - NoTextTap::Action action = NoTextTap::NO_ACTION; - - if(NULL != mImpl->mEventData) - { - action = mImpl->mEventData->mLongPressAction; - } - - return action; + return mImpl->mEventData ? mImpl->mEventData->mLongPressAction : NoTextTap::NO_ACTION; } bool Controller::IsUnderlineSetByString() @@ -1533,7 +1184,64 @@ void Controller::FontStyleSetByString(bool setByString) mImpl->mFontStyleSetByString = setByString; } -// public : Queries & retrieves. +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() { @@ -1568,8 +1276,7 @@ float Controller::GetHeightForWidth(float width) int Controller::GetLineCount(float width) { GetHeightForWidth(width); - int numberofLines = mImpl->mModel->GetNumberOfLines(); - return numberofLines; + return mImpl->mModel->GetNumberOfLines(); } const ModelInterface* const Controller::GetTextModel() const @@ -1603,21 +1310,32 @@ bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, void Controller::SetHiddenInputOption(const Property::Map& options) { - if(NULL == mImpl->mHiddenInput) - { - mImpl->mHiddenInput = new HiddenText(this); - } + EnsureCreated(mImpl->mHiddenInput, this); mImpl->mHiddenInput->SetProperties(options); } void Controller::GetHiddenInputOption(Property::Map& options) { - if(NULL != mImpl->mHiddenInput) + if(mImpl->mHiddenInput) { mImpl->mHiddenInput->GetProperties(options); } } +void Controller::SetInputFilterOption(const Property::Map& options) +{ + EnsureCreated(mImpl->mInputFilter); + mImpl->mInputFilter->SetProperties(options); +} + +void Controller::GetInputFilterOption(Property::Map& options) +{ + if(mImpl->mInputFilter) + { + mImpl->mInputFilter->GetProperties(options); + } +} + void Controller::SetPlaceholderProperty(const Property::Map& map) { PlaceholderHandler::SetPlaceholderProperty(*this, map); @@ -1631,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 @@ -1682,7 +1364,29 @@ void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignm mImpl->mModel->mVerticalLineAlignment = alignment; } -// public : Relayout. +Toolkit::DevelText::EllipsisPosition::Type Controller::GetEllipsisPosition() const +{ + return mImpl->mModel->GetEllipsisPosition(); +} + +void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition) +{ + mImpl->mModel->mEllipsisPosition = ellipsisPosition; + 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) { @@ -1694,39 +1398,61 @@ void Controller::RequestRelayout() mImpl->RequestRelayout(); } -// public : Input style change signals. +Vector Controller::GetTextSize(CharacterIndex startIndex, CharacterIndex endIndex) +{ + Vector sizesList; + Vector positionsList; + + GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizesList, positionsList); + return sizesList; +} -bool Controller::IsInputStyleChangedSignalsQueueEmpty() +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(NULL == mImpl->mEventData) + Vector sizeList; + Vector positionList; + + GetTextGeometry(mImpl->mModel, startIndex, endIndex, sizeList, positionList); + + if(sizeList.Empty() || sizeList.Size() != positionList.Size()) { - // Nothing to do. - return; + return {0, 0, 0, 0}; } - for(Vector::ConstIterator it = mImpl->mEventData->mInputStyleChangedQueue.Begin(), - endIt = mImpl->mEventData->mInputStyleChangedQueue.End(); - it != endIt; - ++it) - { - const InputStyle::Mask mask = *it; + 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; - if(NULL != mImpl->mEditableControlInterface) - { - // Emit the input style changed signal. - mImpl->mEditableControlInterface->InputStyleChanged(mask); - } + 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); } - mImpl->mEventData->mInputStyleChangedQueue.Clear(); + return {minX, minY, maxRight - minX, maxBottom - minY}; } -// public : Text-input Event Queuing. +bool Controller::IsInputStyleChangedSignalsQueueEmpty() +{ + return mImpl->IsInputStyleChangedSignalsQueueEmpty(); +} + +void Controller::ProcessInputStyleChangedSignals() +{ + mImpl->ProcessInputStyleChangedSignals(); +} void Controller::KeyboardFocusGainEvent() { @@ -1777,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); } } @@ -1791,7 +1517,7 @@ CharacterIndex Controller::GetPrimaryCursorPosition() const return mImpl->GetPrimaryCursorPosition(); } -bool Controller::SetPrimaryCursorPosition(CharacterIndex index) +bool Controller::SetPrimaryCursorPosition(CharacterIndex index, bool focused) { if(mImpl->mEventData) { @@ -1799,9 +1525,9 @@ bool Controller::SetPrimaryCursorPosition(CharacterIndex index) mImpl->mEventData->mIsLeftHandleSelected = true; mImpl->mEventData->mIsRightHandleSelected = true; mImpl->mEventData->mCheckScrollAmount = true; - if(mImpl->SetPrimaryCursorPosition(index)) + if(mImpl->SetPrimaryCursorPosition(index, focused) && focused) { - KeyboardFocusGainEvent(); + EventHandler::KeyboardFocusGainEvent(*this); return true; } } @@ -1810,22 +1536,37 @@ bool Controller::SetPrimaryCursorPosition(CharacterIndex index) 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) +{ + 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() +{ + return mImpl->CopyText(); +} + +string Controller::CutText() +{ + return mImpl->CutText(); +} + +void Controller::PasteText() +{ + mImpl->RequestGetTextFromClipboard(); // Request clipboard service to retrieve an item } InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent) @@ -1838,18 +1579,16 @@ void Controller::PasteClipboardItemEvent() EventHandler::PasteClipboardItemEvent(*this); } -// protected : Inherit from Text::Decorator::ControllerInterface. - 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(NULL != mImpl->mEditableControlInterface) + if(mImpl->mEditableControlInterface) { - mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping); + mImpl->mEditableControlInterface->AddDecoration(actor, type, needsClipping); } } @@ -1861,60 +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() { - if(mImpl->mEventData) - { - //scroll values are negative internally so we convert them to positive numbers - return -mImpl->mModel->mScrollPosition.x; - } - return 0; + return mImpl->GetHorizontalScrollPosition(); } float Controller::GetVerticalScrollPosition() { - if(mImpl->mEventData) - { - //scroll values are negative internally so we convert them to positive numbers - return -mImpl->mModel->mScrollPosition.y; - } - return 0; + return mImpl->GetVerticalScrollPosition(); } void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y) @@ -1922,8 +1622,6 @@ void Controller::DecorationEvent(HandleType handleType, HandleState state, float EventHandler::DecorationEvent(*this, handleType, state, x, y); } -// protected : Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface. - void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button) { EventHandler::TextPopupButtonTouched(*this, button); @@ -1938,129 +1636,6 @@ void Controller::DisplayTimeExpired() mImpl->RequestRelayout(); } -// private : Update. - -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); -} - -// private : Relayout. - -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); -} - -// private : Events. - -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 @@ -2078,20 +1653,7 @@ void Controller::ResetCursorPosition(CharacterIndex cursorIndex) CharacterIndex Controller::GetCursorPosition() { - if(!mImpl->mEventData) - return 0; - - return mImpl->mEventData->mPrimaryCursorPosition; -} - -void Controller::ResetScrollPosition() -{ - if(NULL != 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) @@ -2111,19 +1673,17 @@ bool Controller::ShouldClearFocusOnEscape() const Actor Controller::CreateBackgroundActor() { - return mImpl->CreateBackgroundActor(); + return CreateControllerBackgroundActor(mImpl->mView, mImpl->mModel->mVisualModel, mImpl->mModel->mLogicalModel, mImpl->mShaderBackground); } -// private : Private contructors & copy operator. - -Controller::Controller() -: Controller(nullptr, nullptr, nullptr, nullptr) +void Controller::GetAnchorActors(std::vector& anchorActors) { + mImpl->GetAnchorActors(anchorActors); } -Controller::Controller(ControlInterface* controlInterface) -: Controller(controlInterface, nullptr, nullptr, nullptr) +int Controller::GetAnchorIndex(size_t characterOffset) { + return mImpl->GetAnchorIndex(characterOffset); } Controller::Controller(ControlInterface* controlInterface, @@ -2134,17 +1694,9 @@ Controller::Controller(ControlInterface* controlInterface, { } -// The copy constructor and operator are left unimplemented. - -// protected : Destructor. - Controller::~Controller() { delete mImpl; } -} // namespace Text - -} // namespace Toolkit - -} // namespace Dali +} // namespace Dali::Toolkit::Text