2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/text/text-controller.h>
22 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
23 #include <dali/devel-api/adaptor-framework/window-devel.h>
24 #include <dali/integration-api/debug.h>
30 #include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
31 #include <dali-toolkit/internal/text/text-controller-event-handler.h>
32 #include <dali-toolkit/internal/text/text-controller-impl.h>
33 #include <dali-toolkit/internal/text/text-controller-input-font-handler.h>
34 #include <dali-toolkit/internal/text/text-controller-input-properties.h>
35 #include <dali-toolkit/internal/text/text-controller-placeholder-handler.h>
36 #include <dali-toolkit/internal/text/text-controller-relayouter.h>
37 #include <dali-toolkit/internal/text/text-controller-text-updater.h>
38 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
42 #if defined(DEBUG_ENABLED)
43 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
46 constexpr float MAX_FLOAT = std::numeric_limits<float>::max();
48 const std::string EMPTY_STRING("");
50 template<typename Type>
51 void EnsureCreated(Type*& object)
59 template<typename Type>
60 void EnsureCreated(std::unique_ptr<Type>& object)
64 object = std::unique_ptr<Type>(new Type());
68 template<typename Type, typename Arg1>
69 void EnsureCreated(Type*& object, Arg1 arg1)
73 object = new Type(arg1);
77 template<typename Type, typename Arg1, typename Arg2>
78 void EnsureCreated(Type*& object, Arg1 arg1, Arg2 arg2)
82 object = new Type(arg1, arg2);
88 unsigned int horizontalDpi = 0u;
89 unsigned int verticalDpi = 0u;
90 Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get();
91 fontClient.GetDpi(horizontalDpi, verticalDpi);
92 return static_cast<float>(horizontalDpi);
95 float ConvertPixelToPoint(float pixel)
97 return pixel * 72.0f / GetDpi();
100 float ConvertPointToPixel(float point)
102 // Pixel size = Point size * DPI / 72.f
103 return point * GetDpi() / 72.0f;
106 void UpdateCursorPosition(Dali::Toolkit::Text::EventData* eventData)
108 if(eventData && Dali::Toolkit::Text::EventData::IsEditingState(eventData->mState))
110 // Update the cursor position if it's in editing mode
111 eventData->mDecoratorUpdated = true;
112 eventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
118 namespace Dali::Toolkit::Text
121 void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
125 delete mImpl->mEventData;
126 mImpl->mEventData = NULL;
128 // Nothing else to do.
132 EnsureCreated(mImpl->mEventData, decorator, inputMethodContext);
135 void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
137 // Metrics for bitmap & vector based glyphs are different
138 mImpl->mMetrics->SetGlyphType(glyphType);
140 // Clear the font-specific data
143 mImpl->RequestRelayout();
146 void Controller::SetMarkupProcessorEnabled(bool enable)
148 if(enable != mImpl->mMarkupProcessorEnabled)
150 //If Text was already set, call the SetText again for enabling or disabling markup
151 mImpl->mMarkupProcessorEnabled = enable;
157 mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
160 bool Controller::IsMarkupProcessorEnabled() const
162 return mImpl->mMarkupProcessorEnabled;
165 bool Controller::HasAnchors() const
167 return (mImpl->mMarkupProcessorEnabled && mImpl->mModel->mLogicalModel->mAnchors.Count() && mImpl->IsShowingRealText());
170 void Controller::SetAutoScrollEnabled(bool enable)
172 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);
174 if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
176 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
184 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n");
185 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | UPDATE_DIRECTION);
189 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
192 mImpl->mIsAutoScrollEnabled = enable;
193 mImpl->RequestRelayout();
197 DALI_LOG_WARNING("Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n");
198 mImpl->mIsAutoScrollEnabled = false;
202 bool Controller::IsAutoScrollEnabled() const
204 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
206 return mImpl->mIsAutoScrollEnabled;
209 CharacterDirection Controller::GetAutoScrollDirection() const
211 return mImpl->mIsTextDirectionRTL;
214 float Controller::GetAutoScrollLineAlignment() const
217 if(mImpl->mModel->mVisualModel && (0u != mImpl->mModel->mVisualModel->mLines.Count()))
219 offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
224 void Controller::SetHorizontalScrollEnabled(bool enable)
226 if(mImpl->mEventData && mImpl->mEventData->mDecorator)
228 mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
232 bool Controller::IsHorizontalScrollEnabled() const
234 return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
237 void Controller::SetVerticalScrollEnabled(bool enable)
239 if(mImpl->mEventData && mImpl->mEventData->mDecorator)
241 mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
245 bool Controller::IsVerticalScrollEnabled() const
247 return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
250 void Controller::SetSmoothHandlePanEnabled(bool enable)
252 if(mImpl->mEventData && mImpl->mEventData->mDecorator)
254 mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
258 bool Controller::IsSmoothHandlePanEnabled() const
260 return mImpl->mEventData && mImpl->mEventData->mDecorator && mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
263 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
265 mImpl->mMaximumNumberOfCharacters = maxCharacters;
268 int Controller::GetMaximumNumberOfCharacters()
270 return mImpl->mMaximumNumberOfCharacters;
273 void Controller::SetEnableCursorBlink(bool enable)
275 DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled");
277 if(mImpl->mEventData)
279 mImpl->mEventData->mCursorBlinkEnabled = enable;
281 if(!enable && mImpl->mEventData->mDecorator)
283 mImpl->mEventData->mDecorator->StopCursorBlink();
288 bool Controller::GetEnableCursorBlink() const
290 return mImpl->mEventData && mImpl->mEventData->mCursorBlinkEnabled;
293 void Controller::SetMultiLineEnabled(bool enable)
295 const Layout::Engine::Type layout = enable ? Layout::Engine::MULTI_LINE_BOX : Layout::Engine::SINGLE_LINE_BOX;
297 if(layout != mImpl->mLayoutEngine.GetLayout())
299 // Set the layout type.
300 mImpl->mLayoutEngine.SetLayout(layout);
302 // Set the flags to redo the layout operations
303 const OperationsMask layoutOperations = static_cast<OperationsMask>(LAYOUT |
308 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
309 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | layoutOperations);
311 // Need to recalculate natural size
312 mImpl->mRecalculateNaturalSize = true;
314 mImpl->RequestRelayout();
318 bool Controller::IsMultiLineEnabled() const
320 return Layout::Engine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
323 void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment)
325 if(alignment != mImpl->mModel->mHorizontalAlignment)
327 // Set the alignment.
328 mImpl->mModel->mHorizontalAlignment = alignment;
330 // Set the flag to redo the alignment operation.
331 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
333 if(mImpl->mEventData)
335 mImpl->mEventData->mUpdateAlignment = true;
337 // Update the cursor if it's in editing mode
338 if(EventData::IsEditingState(mImpl->mEventData->mState))
340 mImpl->ChangeState(EventData::EDITING);
341 mImpl->mEventData->mUpdateCursorPosition = true;
345 mImpl->RequestRelayout();
349 Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const
351 return mImpl->mModel->mHorizontalAlignment;
354 void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment)
356 if(alignment != mImpl->mModel->mVerticalAlignment)
358 // Set the alignment.
359 mImpl->mModel->mVerticalAlignment = alignment;
360 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
361 mImpl->RequestRelayout();
365 VerticalAlignment::Type Controller::GetVerticalAlignment() const
367 return mImpl->mModel->mVerticalAlignment;
370 bool Controller::IsIgnoreSpacesAfterText() const
372 return mImpl->mModel->mIgnoreSpacesAfterText;
375 void Controller::SetIgnoreSpacesAfterText(bool ignore)
377 mImpl->mModel->mIgnoreSpacesAfterText = ignore;
380 void Controller::ChangedLayoutDirection()
382 mImpl->mIsLayoutDirectionChanged = true;
385 void Controller::SetMatchLayoutDirection(DevelText::MatchLayoutDirection type)
387 mImpl->mModel->mMatchLayoutDirection = type;
390 DevelText::MatchLayoutDirection Controller::GetMatchLayoutDirection() const
392 return mImpl->mModel->mMatchLayoutDirection;
395 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
397 mImpl->mLayoutDirection = layoutDirection;
400 Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const
402 if(mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::LOCALE ||
403 (mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::INHERIT && !mImpl->mIsLayoutDirectionChanged))
405 return static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(actor).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
409 return static_cast<Dali::LayoutDirection::Type>(actor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
413 bool Controller::IsShowingRealText() const
415 return mImpl->IsShowingRealText();
418 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
420 if(lineWrapMode != mImpl->mModel->mLineWrapMode)
422 // Update Text layout for applying wrap mode
423 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
429 if((mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
430 (mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) // hyphen is treated as line break
432 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | GET_LINE_BREAKS);
435 // Set the text wrap mode.
436 mImpl->mModel->mLineWrapMode = lineWrapMode;
438 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
439 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
440 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
443 mImpl->RequestRelayout();
447 Text::LineWrap::Mode Controller::GetLineWrapMode() const
449 return mImpl->mModel->mLineWrapMode;
452 void Controller::SetTextElideEnabled(bool enabled)
454 mImpl->mModel->mElideEnabled = enabled;
455 mImpl->mModel->mVisualModel->SetTextElideEnabled(enabled);
458 bool Controller::IsTextElideEnabled() const
460 return mImpl->mModel->mElideEnabled;
463 void Controller::SetTextFitEnabled(bool enabled)
465 mImpl->mTextFitEnabled = enabled;
468 bool Controller::IsTextFitEnabled() const
470 return mImpl->mTextFitEnabled;
473 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
475 mImpl->mTextFitMinSize = (type == POINT_SIZE) ? minSize : ConvertPixelToPoint(minSize);
478 float Controller::GetTextFitMinSize() const
480 return mImpl->mTextFitMinSize;
483 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
485 mImpl->mTextFitMaxSize = (type == POINT_SIZE) ? maxSize : ConvertPixelToPoint(maxSize);
488 float Controller::GetTextFitMaxSize() const
490 return mImpl->mTextFitMaxSize;
493 void Controller::SetTextFitStepSize(float step, FontSizeType type)
495 mImpl->mTextFitStepSize = (type == POINT_SIZE) ? step : ConvertPixelToPoint(step);
498 float Controller::GetTextFitStepSize() const
500 return mImpl->mTextFitStepSize;
503 void Controller::SetTextFitContentSize(Vector2 size)
505 mImpl->mTextFitContentSize = size;
508 Vector2 Controller::GetTextFitContentSize() const
510 return mImpl->mTextFitContentSize;
513 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
515 PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
518 bool Controller::IsPlaceholderTextElideEnabled() const
520 return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
523 void Controller::SetSelectionEnabled(bool enabled)
525 mImpl->mEventData->mSelectionEnabled = enabled;
528 bool Controller::IsSelectionEnabled() const
530 return mImpl->mEventData->mSelectionEnabled;
533 void Controller::SetShiftSelectionEnabled(bool enabled)
535 mImpl->mEventData->mShiftSelectionFlag = enabled;
538 bool Controller::IsShiftSelectionEnabled() const
540 return mImpl->mEventData->mShiftSelectionFlag;
543 void Controller::SetGrabHandleEnabled(bool enabled)
545 mImpl->mEventData->mGrabHandleEnabled = enabled;
548 bool Controller::IsGrabHandleEnabled() const
550 return mImpl->mEventData->mGrabHandleEnabled;
553 void Controller::SetGrabHandlePopupEnabled(bool enabled)
555 mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
558 bool Controller::IsGrabHandlePopupEnabled() const
560 return mImpl->mEventData->mGrabHandlePopupEnabled;
563 void Controller::SetText(const std::string& text)
565 TextUpdater::SetText(*this, text);
568 void Controller::GetText(std::string& text) const
570 if(!mImpl->IsShowingPlaceholderText())
572 // Retrieves the text string.
573 mImpl->GetText(0u, text);
577 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this);
581 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
583 PlaceholderHandler::SetPlaceholderText(*this, type, text);
586 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
588 PlaceholderHandler::GetPlaceholderText(*this, type, text);
591 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
593 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n");
595 if(!mImpl->mFontDefaults->familyDefined) // If user defined font then should not update when system font changes
597 DALI_LOG_INFO(gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str());
598 mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
602 mImpl->RequestRelayout();
606 void Controller::RetrieveSelection(std::string& selectedText) const
608 mImpl->RetrieveSelection(selectedText, false);
611 void Controller::SetSelection(int start, int end)
613 mImpl->SetSelection(start, end);
616 std::pair<int, int> Controller::GetSelectionIndexes() const
618 return mImpl->GetSelectionIndexes();
621 void Controller::CopyStringToClipboard(const std::string& source)
623 mImpl->CopyStringToClipboard(source);
626 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
628 mImpl->SendSelectionToClipboard(deleteAfterSending);
631 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
633 EnsureCreated(mImpl->mFontDefaults);
635 mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
636 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
637 mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
639 // Update the cursor position if it's in editing mode
640 UpdateCursorPosition(mImpl->mEventData);
642 // Clear the font-specific data
645 mImpl->RequestRelayout();
648 const std::string& Controller::GetDefaultFontFamily() const
650 return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.family : EMPTY_STRING;
653 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
655 PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
658 const std::string& Controller::GetPlaceholderFontFamily() const
660 return PlaceholderHandler::GetPlaceholderFontFamily(*this);
663 void Controller::SetDefaultFontWeight(FontWeight weight)
665 EnsureCreated(mImpl->mFontDefaults);
667 mImpl->mFontDefaults->mFontDescription.weight = weight;
668 mImpl->mFontDefaults->weightDefined = true;
670 // Update the cursor position if it's in editing mode
671 UpdateCursorPosition(mImpl->mEventData);
673 // Clear the font-specific data
676 mImpl->RequestRelayout();
679 bool Controller::IsDefaultFontWeightDefined() const
681 return mImpl->mFontDefaults && mImpl->mFontDefaults->weightDefined;
684 FontWeight Controller::GetDefaultFontWeight() const
686 return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.weight : TextAbstraction::FontWeight::NORMAL;
689 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
691 PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
694 bool Controller::IsPlaceholderTextFontWeightDefined() const
696 return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
699 FontWeight Controller::GetPlaceholderTextFontWeight() const
701 return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
704 void Controller::SetDefaultFontWidth(FontWidth width)
706 EnsureCreated(mImpl->mFontDefaults);
708 mImpl->mFontDefaults->mFontDescription.width = width;
709 mImpl->mFontDefaults->widthDefined = true;
711 // Update the cursor position if it's in editing mode
712 UpdateCursorPosition(mImpl->mEventData);
714 // Clear the font-specific data
717 mImpl->RequestRelayout();
720 bool Controller::IsDefaultFontWidthDefined() const
722 return mImpl->mFontDefaults && mImpl->mFontDefaults->widthDefined;
725 FontWidth Controller::GetDefaultFontWidth() const
727 return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.width : TextAbstraction::FontWidth::NORMAL;
730 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
732 PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
735 bool Controller::IsPlaceholderTextFontWidthDefined() const
737 return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
740 FontWidth Controller::GetPlaceholderTextFontWidth() const
742 return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
745 void Controller::SetDefaultFontSlant(FontSlant slant)
747 EnsureCreated(mImpl->mFontDefaults);
749 mImpl->mFontDefaults->mFontDescription.slant = slant;
750 mImpl->mFontDefaults->slantDefined = true;
752 // Update the cursor position if it's in editing mode
753 UpdateCursorPosition(mImpl->mEventData);
755 // Clear the font-specific data
758 mImpl->RequestRelayout();
761 bool Controller::IsDefaultFontSlantDefined() const
763 return mImpl->mFontDefaults && mImpl->mFontDefaults->slantDefined;
766 FontSlant Controller::GetDefaultFontSlant() const
768 return mImpl->mFontDefaults ? mImpl->mFontDefaults->mFontDescription.slant : TextAbstraction::FontSlant::NORMAL;
771 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
773 PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
776 bool Controller::IsPlaceholderTextFontSlantDefined() const
778 return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
781 FontSlant Controller::GetPlaceholderTextFontSlant() const
783 return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
786 void Controller::SetFontSizeScale(float scale)
788 mImpl->mFontSizeScale = scale;
790 // Update the cursor position if it's in editing mode
791 UpdateCursorPosition(mImpl->mEventData);
793 // Clear the font-specific data
796 mImpl->RequestRelayout();
799 float Controller::GetFontSizeScale() const
801 return mImpl->mFontDefaults ? mImpl->mFontSizeScale : 1.0f;
804 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
806 EnsureCreated(mImpl->mFontDefaults);
808 mImpl->mFontDefaults->mDefaultPointSize = (type == POINT_SIZE) ? fontSize : ConvertPixelToPoint(fontSize);
809 mImpl->mFontDefaults->sizeDefined = true;
811 // Update the cursor position if it's in editing mode
812 UpdateCursorPosition(mImpl->mEventData);
814 // Clear the font-specific data
817 mImpl->RequestRelayout();
820 float Controller::GetDefaultFontSize(FontSizeType type) const
822 if(mImpl->mFontDefaults)
824 return (type == POINT_SIZE) ? mImpl->mFontDefaults->mDefaultPointSize : ConvertPointToPixel(mImpl->mFontDefaults->mDefaultPointSize);
829 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
831 PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
834 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
836 return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
839 void Controller::SetDefaultColor(const Vector4& color)
841 mImpl->mTextColor = color;
843 if(!mImpl->IsShowingPlaceholderText())
845 mImpl->mModel->mVisualModel->SetTextColor(color);
846 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
847 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
848 mImpl->RequestRelayout();
852 const Vector4& Controller::GetDefaultColor() const
854 return mImpl->mTextColor;
857 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
859 PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
862 const Vector4& Controller::GetPlaceholderTextColor() const
864 return PlaceholderHandler::GetPlaceholderTextColor(*this);
867 void Controller::SetShadowOffset(const Vector2& shadowOffset)
869 mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
870 mImpl->RequestRelayout();
873 const Vector2& Controller::GetShadowOffset() const
875 return mImpl->mModel->mVisualModel->GetShadowOffset();
878 void Controller::SetShadowColor(const Vector4& shadowColor)
880 mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
881 mImpl->RequestRelayout();
884 const Vector4& Controller::GetShadowColor() const
886 return mImpl->mModel->mVisualModel->GetShadowColor();
889 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
891 if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
893 mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
894 mImpl->RequestRelayout();
898 const float& Controller::GetShadowBlurRadius() const
900 return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
903 void Controller::SetUnderlineColor(const Vector4& color)
905 mImpl->mModel->mVisualModel->SetUnderlineColor(color);
906 mImpl->RequestRelayout();
909 const Vector4& Controller::GetUnderlineColor() const
911 return mImpl->mModel->mVisualModel->GetUnderlineColor();
914 void Controller::SetUnderlineEnabled(bool enabled)
916 mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
917 mImpl->RequestRelayout();
920 bool Controller::IsUnderlineEnabled() const
922 return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
925 void Controller::SetUnderlineHeight(float height)
927 mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
928 mImpl->RequestRelayout();
931 float Controller::GetUnderlineHeight() const
933 return mImpl->mModel->mVisualModel->GetUnderlineHeight();
936 void Controller::SetOutlineColor(const Vector4& color)
938 mImpl->mModel->mVisualModel->SetOutlineColor(color);
939 mImpl->RequestRelayout();
942 const Vector4& Controller::GetOutlineColor() const
944 return mImpl->mModel->mVisualModel->GetOutlineColor();
947 void Controller::SetOutlineWidth(uint16_t width)
949 mImpl->mModel->mVisualModel->SetOutlineWidth(width);
950 mImpl->RequestRelayout();
953 uint16_t Controller::GetOutlineWidth() const
955 return mImpl->mModel->mVisualModel->GetOutlineWidth();
958 void Controller::SetBackgroundColor(const Vector4& color)
960 mImpl->mModel->mVisualModel->SetBackgroundColor(color);
961 mImpl->RequestRelayout();
964 const Vector4& Controller::GetBackgroundColor() const
966 return mImpl->mModel->mVisualModel->GetBackgroundColor();
969 void Controller::SetBackgroundEnabled(bool enabled)
971 mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
972 mImpl->RequestRelayout();
975 bool Controller::IsBackgroundEnabled() const
977 return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
980 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
982 EnsureCreated(mImpl->mEmbossDefaults);
983 mImpl->mEmbossDefaults->properties = embossProperties;
986 const std::string& Controller::GetDefaultEmbossProperties() const
988 return mImpl->mEmbossDefaults ? mImpl->mEmbossDefaults->properties : EMPTY_STRING;
991 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
993 EnsureCreated(mImpl->mOutlineDefaults);
994 mImpl->mOutlineDefaults->properties = outlineProperties;
997 const std::string& Controller::GetDefaultOutlineProperties() const
999 return mImpl->mOutlineDefaults ? mImpl->mOutlineDefaults->properties : EMPTY_STRING;
1002 bool Controller::SetDefaultLineSpacing(float lineSpacing)
1004 if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
1006 mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
1007 mImpl->mRecalculateNaturalSize = true;
1009 mImpl->RelayoutForNewLineSize();
1015 float Controller::GetDefaultLineSpacing() const
1017 return mImpl->mLayoutEngine.GetDefaultLineSpacing();
1020 bool Controller::SetDefaultLineSize(float lineSize)
1022 if(std::fabs(lineSize - mImpl->mLayoutEngine.GetDefaultLineSize()) > Math::MACHINE_EPSILON_1000)
1024 mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
1025 mImpl->mRecalculateNaturalSize = true;
1027 mImpl->RelayoutForNewLineSize();
1033 float Controller::GetDefaultLineSize() const
1035 return mImpl->mLayoutEngine.GetDefaultLineSize();
1038 void Controller::SetInputColor(const Vector4& color)
1040 InputProperties::SetInputColor(*this, color);
1043 const Vector4& Controller::GetInputColor() const
1045 return InputProperties::GetInputColor(*this);
1048 void Controller::SetInputFontFamily(const std::string& fontFamily)
1050 InputFontHandler::SetInputFontFamily(*this, fontFamily);
1053 const std::string& Controller::GetInputFontFamily() const
1055 return InputFontHandler::GetInputFontFamily(*this);
1058 void Controller::SetInputFontWeight(FontWeight weight)
1060 InputFontHandler::SetInputFontWeight(*this, weight);
1063 bool Controller::IsInputFontWeightDefined() const
1065 return InputFontHandler::IsInputFontWeightDefined(*this);
1068 FontWeight Controller::GetInputFontWeight() const
1070 return InputFontHandler::GetInputFontWeight(*this);
1073 void Controller::SetInputFontWidth(FontWidth width)
1075 InputFontHandler::SetInputFontWidth(*this, width);
1078 bool Controller::IsInputFontWidthDefined() const
1080 return InputFontHandler::IsInputFontWidthDefined(*this);
1083 FontWidth Controller::GetInputFontWidth() const
1085 return InputFontHandler::GetInputFontWidth(*this);
1088 void Controller::SetInputFontSlant(FontSlant slant)
1090 InputFontHandler::SetInputFontSlant(*this, slant);
1093 bool Controller::IsInputFontSlantDefined() const
1095 return InputFontHandler::IsInputFontSlantDefined(*this);
1098 FontSlant Controller::GetInputFontSlant() const
1100 return InputFontHandler::GetInputFontSlant(*this);
1103 void Controller::SetInputFontPointSize(float size)
1105 InputFontHandler::SetInputFontPointSize(*this, size);
1108 float Controller::GetInputFontPointSize() const
1110 return InputFontHandler::GetInputFontPointSize(*this);
1113 void Controller::SetInputLineSpacing(float lineSpacing)
1115 InputProperties::SetInputLineSpacing(*this, lineSpacing);
1118 float Controller::GetInputLineSpacing() const
1120 return InputProperties::GetInputLineSpacing(*this);
1123 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
1125 InputProperties::SetInputShadowProperties(*this, shadowProperties);
1128 const std::string& Controller::GetInputShadowProperties() const
1130 return InputProperties::GetInputShadowProperties(*this);
1133 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
1135 InputProperties::SetInputUnderlineProperties(*this, underlineProperties);
1138 const std::string& Controller::GetInputUnderlineProperties() const
1140 return InputProperties::GetInputUnderlineProperties(*this);
1143 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1145 InputProperties::SetInputEmbossProperties(*this, embossProperties);
1148 const std::string& Controller::GetInputEmbossProperties() const
1150 return InputProperties::GetInputEmbossProperties(*this);
1153 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1155 InputProperties::SetInputOutlineProperties(*this, outlineProperties);
1158 const std::string& Controller::GetInputOutlineProperties() const
1160 return InputProperties::GetInputOutlineProperties(*this);
1163 void Controller::SetInputModePassword(bool passwordInput)
1165 InputProperties::SetInputModePassword(*this, passwordInput);
1168 bool Controller::IsInputModePassword()
1170 return InputProperties::IsInputModePassword(*this);
1173 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1175 if(mImpl->mEventData)
1177 mImpl->mEventData->mDoubleTapAction = action;
1181 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1183 return mImpl->mEventData ? mImpl->mEventData->mDoubleTapAction : NoTextTap::NO_ACTION;
1186 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1188 if(mImpl->mEventData)
1190 mImpl->mEventData->mLongPressAction = action;
1194 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1196 return mImpl->mEventData ? mImpl->mEventData->mLongPressAction : NoTextTap::NO_ACTION;
1199 bool Controller::IsUnderlineSetByString()
1201 return mImpl->mUnderlineSetByString;
1204 void Controller::UnderlineSetByString(bool setByString)
1206 mImpl->mUnderlineSetByString = setByString;
1209 bool Controller::IsShadowSetByString()
1211 return mImpl->mShadowSetByString;
1214 void Controller::ShadowSetByString(bool setByString)
1216 mImpl->mShadowSetByString = setByString;
1219 bool Controller::IsOutlineSetByString()
1221 return mImpl->mOutlineSetByString;
1224 void Controller::OutlineSetByString(bool setByString)
1226 mImpl->mOutlineSetByString = setByString;
1229 bool Controller::IsFontStyleSetByString()
1231 return mImpl->mFontStyleSetByString;
1234 void Controller::FontStyleSetByString(bool setByString)
1236 mImpl->mFontStyleSetByString = setByString;
1239 Layout::Engine& Controller::GetLayoutEngine()
1241 return mImpl->mLayoutEngine;
1244 View& Controller::GetView()
1246 return mImpl->mView;
1249 Vector3 Controller::GetNaturalSize()
1251 return Relayouter::GetNaturalSize(*this);
1254 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1256 return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1259 void Controller::FitPointSizeforLayout(Size layoutSize)
1261 Relayouter::FitPointSizeforLayout(*this, layoutSize);
1264 float Controller::GetHeightForWidth(float width)
1266 return Relayouter::GetHeightForWidth(*this, width);
1269 int Controller::GetLineCount(float width)
1271 GetHeightForWidth(width);
1272 return mImpl->mModel->GetNumberOfLines();
1275 const ModelInterface* const Controller::GetTextModel() const
1277 return mImpl->mModel.Get();
1280 float Controller::GetScrollAmountByUserInput()
1282 float scrollAmount = 0.0f;
1284 if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1286 scrollAmount = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1287 mImpl->mEventData->mCheckScrollAmount = false;
1289 return scrollAmount;
1292 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1294 const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1297 controlHeight = mImpl->mModel->mVisualModel->mControlSize.height;
1298 layoutHeight = layout.height;
1299 scrollPosition = mImpl->mModel->mScrollPosition.y;
1300 isScrolled = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1304 void Controller::SetHiddenInputOption(const Property::Map& options)
1306 EnsureCreated<HiddenText, Controller*>(mImpl->mHiddenInput, this);
1307 mImpl->mHiddenInput->SetProperties(options);
1310 void Controller::GetHiddenInputOption(Property::Map& options)
1312 if(mImpl->mHiddenInput)
1314 mImpl->mHiddenInput->GetProperties(options);
1318 void Controller::SetInputFilterOption(const Property::Map& options)
1320 EnsureCreated(mImpl->mInputFilter);
1321 mImpl->mInputFilter->SetProperties(options);
1324 void Controller::GetInputFilterOption(Property::Map& options)
1326 if(mImpl->mInputFilter)
1328 mImpl->mInputFilter->GetProperties(options);
1332 void Controller::SetPlaceholderProperty(const Property::Map& map)
1334 PlaceholderHandler::SetPlaceholderProperty(*this, map);
1337 void Controller::GetPlaceholderProperty(Property::Map& map)
1339 PlaceholderHandler::GetPlaceholderProperty(*this, map);
1342 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1344 // Make sure the model is up-to-date before layouting
1345 ProcessModifyEvents();
1347 if(mImpl->mUpdateTextDirection)
1349 // Operations that can be done only once until the text changes.
1350 const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
1358 // Set the update info to relayout the whole text.
1359 mImpl->mTextUpdateInfo.mParagraphCharacterIndex = 0u;
1360 mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count();
1362 // Make sure the model is up-to-date before layouting
1363 mImpl->UpdateModel(onlyOnceOperations);
1365 Vector3 naturalSize;
1366 DoRelayout(Size(MAX_FLOAT, MAX_FLOAT),
1367 static_cast<OperationsMask>(onlyOnceOperations |
1368 LAYOUT | REORDER | UPDATE_DIRECTION),
1369 naturalSize.GetVectorXY());
1371 // Do not do again the only once operations.
1372 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending & ~onlyOnceOperations);
1374 // Clear the update info. This info will be set the next time the text is updated.
1375 mImpl->mTextUpdateInfo.Clear();
1377 // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
1378 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1380 mImpl->mUpdateTextDirection = false;
1383 return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
1386 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1388 return mImpl->mModel->GetVerticalLineAlignment();
1391 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1393 mImpl->mModel->mVerticalLineAlignment = alignment;
1396 Toolkit::DevelText::EllipsisPosition::Type Controller::GetEllipsisPosition() const
1398 return mImpl->mModel->GetEllipsisPosition();
1401 void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition)
1403 mImpl->mModel->mEllipsisPosition = ellipsisPosition;
1404 mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
1407 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1409 return Relayouter::Relayout(*this, size, layoutDirection);
1412 void Controller::RequestRelayout()
1414 mImpl->RequestRelayout();
1417 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1419 return mImpl->IsInputStyleChangedSignalsQueueEmpty();
1422 void Controller::ProcessInputStyleChangedSignals()
1424 mImpl->ProcessInputStyleChangedSignals();
1427 void Controller::KeyboardFocusGainEvent()
1429 EventHandler::KeyboardFocusGainEvent(*this);
1432 void Controller::KeyboardFocusLostEvent()
1434 EventHandler::KeyboardFocusLostEvent(*this);
1437 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1439 return EventHandler::KeyEvent(*this, keyEvent);
1442 void Controller::AnchorEvent(float x, float y)
1444 EventHandler::AnchorEvent(*this, x, y);
1447 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1449 EventHandler::TapEvent(*this, tapCount, x, y);
1452 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1454 EventHandler::PanEvent(*this, state, displacement);
1457 void Controller::LongPressEvent(GestureState state, float x, float y)
1459 EventHandler::LongPressEvent(*this, state, x, y);
1462 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1464 EventHandler::SelectEvent(*this, x, y, selectType);
1467 void Controller::SelectEvent(const uint32_t start, const uint32_t end, SelectionType selectType)
1469 EventHandler::SelectEvent(*this, start, end, selectType);
1472 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1474 if(mImpl->mEventData)
1476 mImpl->mEventData->mCheckScrollAmount = true;
1477 mImpl->mEventData->mIsLeftHandleSelected = true;
1478 mImpl->mEventData->mIsRightHandleSelected = true;
1479 mImpl->SetTextSelectionRange(start, end);
1480 mImpl->RequestRelayout();
1481 KeyboardFocusGainEvent();
1485 Uint32Pair Controller::GetTextSelectionRange() const
1487 return mImpl->GetTextSelectionRange();
1490 CharacterIndex Controller::GetPrimaryCursorPosition() const
1492 return mImpl->GetPrimaryCursorPosition();
1495 bool Controller::SetPrimaryCursorPosition(CharacterIndex index, bool focused)
1497 if(mImpl->mEventData)
1499 mImpl->mEventData->mCheckScrollAmount = true;
1500 mImpl->mEventData->mIsLeftHandleSelected = true;
1501 mImpl->mEventData->mIsRightHandleSelected = true;
1502 mImpl->mEventData->mCheckScrollAmount = true;
1503 if(mImpl->SetPrimaryCursorPosition(index, focused) && focused)
1505 KeyboardFocusGainEvent();
1512 void Controller::SelectWholeText()
1514 SelectEvent(0.f, 0.f, SelectionType::ALL);
1517 void Controller::SelectNone()
1519 SelectEvent(0.f, 0.f, SelectionType::NONE);
1522 void Controller::SelectText(const uint32_t start, const uint32_t end)
1524 SelectEvent(start, end, SelectionType::RANGE);
1527 string Controller::GetSelectedText() const
1530 if(EventData::SELECTING == mImpl->mEventData->mState)
1532 mImpl->RetrieveSelection(text, false);
1537 string Controller::CopyText()
1540 mImpl->RetrieveSelection(text, false);
1541 mImpl->SendSelectionToClipboard(false); // Text not modified
1543 mImpl->mEventData->mUpdateCursorPosition = true;
1545 mImpl->RequestRelayout(); // Cursor, Handles, Selection Highlight, Popup
1550 string Controller::CutText()
1553 mImpl->RetrieveSelection(text, false);
1557 return EMPTY_STRING;
1560 mImpl->SendSelectionToClipboard(true); // Synchronous call to modify text
1561 mImpl->mOperationsPending = ALL_OPERATIONS;
1563 if((0u != mImpl->mModel->mLogicalModel->mText.Count()) ||
1564 !mImpl->IsPlaceholderAvailable())
1566 mImpl->QueueModifyEvent(ModifyEvent::TEXT_DELETED);
1570 ShowPlaceholderText();
1573 mImpl->mEventData->mUpdateCursorPosition = true;
1574 mImpl->mEventData->mScrollAfterDelete = true;
1576 mImpl->RequestRelayout();
1578 if(nullptr != mImpl->mEditableControlInterface)
1580 mImpl->mEditableControlInterface->TextChanged(true);
1585 void Controller::PasteText()
1587 mImpl->RequestGetTextFromClipboard(); // Request clipboard service to retrieve an item
1590 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1592 return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1595 void Controller::PasteClipboardItemEvent()
1597 EventHandler::PasteClipboardItemEvent(*this);
1600 void Controller::GetTargetSize(Vector2& targetSize)
1602 targetSize = mImpl->mModel->mVisualModel->mControlSize;
1605 void Controller::AddDecoration(Actor& actor, bool needsClipping)
1607 if(mImpl->mEditableControlInterface)
1609 mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
1613 bool Controller::IsEditable() const
1615 return mImpl->IsEditable();
1618 void Controller::SetEditable(bool editable)
1620 mImpl->SetEditable(editable);
1623 void Controller::ScrollBy(Vector2 scroll)
1625 mImpl->ScrollBy(scroll);
1628 float Controller::GetHorizontalScrollPosition()
1630 return mImpl->GetHorizontalScrollPosition();
1633 float Controller::GetVerticalScrollPosition()
1635 return mImpl->GetVerticalScrollPosition();
1638 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1640 EventHandler::DecorationEvent(*this, handleType, state, x, y);
1643 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1645 EventHandler::TextPopupButtonTouched(*this, button);
1648 void Controller::DisplayTimeExpired()
1650 mImpl->mEventData->mUpdateCursorPosition = true;
1651 // Apply modifications to the model
1652 mImpl->mOperationsPending = ALL_OPERATIONS;
1654 mImpl->RequestRelayout();
1657 void Controller::InsertText(const std::string& text, Controller::InsertType type)
1659 TextUpdater::InsertText(*this, text, type);
1662 void Controller::PasteText(const std::string& stringToPaste)
1664 TextUpdater::PasteText(*this, stringToPaste);
1667 bool Controller::RemoveText(int cursorOffset, int numberOfCharacters, UpdateInputStyleType type)
1669 return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
1672 bool Controller::RemoveSelectedText()
1674 return TextUpdater::RemoveSelectedText(*this);
1677 void Controller::InsertTextAnchor(int numberOfCharacters, CharacterIndex previousCursorIndex)
1679 TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
1682 void Controller::RemoveTextAnchor(int cursorOffset, int numberOfCharacters, CharacterIndex previousCursorIndex)
1684 TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
1687 bool Controller::DoRelayout(const Size& size, OperationsMask operationsRequired, Size& layoutSize)
1689 return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
1692 void Controller::CalculateVerticalOffset(const Size& controlSize)
1694 Relayouter::CalculateVerticalOffset(*this, controlSize);
1697 void Controller::ProcessModifyEvents()
1699 EventHandler::ProcessModifyEvents(*this);
1702 void Controller::TextReplacedEvent()
1704 EventHandler::TextReplacedEvent(*this);
1707 void Controller::TextInsertedEvent()
1709 EventHandler::TextInsertedEvent(*this);
1712 void Controller::TextDeletedEvent()
1714 EventHandler::TextDeletedEvent(*this);
1717 bool Controller::DeleteEvent(int keyCode)
1719 return EventHandler::DeleteEvent(*this, keyCode);
1722 // private : Helpers.
1724 void Controller::ResetText()
1726 TextUpdater::ResetText(*this);
1729 void Controller::ShowPlaceholderText()
1731 PlaceholderHandler::ShowPlaceholderText(*this);
1734 void Controller::ClearFontData()
1736 if(mImpl->mFontDefaults)
1738 mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
1741 // Set flags to update the model.
1742 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
1743 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
1744 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
1746 mImpl->mTextUpdateInfo.mClearAll = true;
1747 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1748 mImpl->mRecalculateNaturalSize = true;
1750 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
1756 UPDATE_LAYOUT_SIZE |
1761 void Controller::ClearStyleData()
1763 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
1764 mImpl->mModel->mLogicalModel->ClearFontDescriptionRuns();
1767 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
1769 // Reset the cursor position
1770 if(NULL != mImpl->mEventData)
1772 mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
1774 // Update the cursor if it's in editing mode.
1775 if(EventData::IsEditingState(mImpl->mEventData->mState))
1777 mImpl->mEventData->mUpdateCursorPosition = true;
1782 CharacterIndex Controller::GetCursorPosition()
1784 if(!mImpl->mEventData)
1787 return mImpl->mEventData->mPrimaryCursorPosition;
1790 void Controller::ResetScrollPosition()
1792 if(mImpl->mEventData)
1794 // Reset the scroll position.
1795 mImpl->mModel->mScrollPosition = Vector2::ZERO;
1796 mImpl->mEventData->mScrollAfterUpdatePosition = true;
1800 void Controller::SetControlInterface(ControlInterface* controlInterface)
1802 mImpl->mControlInterface = controlInterface;
1805 void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
1807 mImpl->mAnchorControlInterface = anchorControlInterface;
1810 bool Controller::ShouldClearFocusOnEscape() const
1812 return mImpl->mShouldClearFocusOnEscape;
1815 Actor Controller::CreateBackgroundActor()
1817 return mImpl->CreateBackgroundActor();
1820 Controller::Controller(ControlInterface* controlInterface,
1821 EditableControlInterface* editableControlInterface,
1822 SelectableControlInterface* selectableControlInterface,
1823 AnchorControlInterface* anchorControlInterface)
1824 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
1828 Controller::~Controller()
1833 } // namespace Dali::Toolkit::Text