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/integration-api/debug.h>
28 #include <dali-toolkit/internal/text/text-controller-event-handler.h>
29 #include <dali-toolkit/internal/text/text-controller-impl.h>
30 #include <dali-toolkit/internal/text/text-controller-input-font-handler.h>
31 #include <dali-toolkit/internal/text/text-controller-placeholder-handler.h>
32 #include <dali-toolkit/internal/text/text-controller-relayouter.h>
33 #include <dali-toolkit/internal/text/text-controller-text-updater.h>
34 #include <dali-toolkit/internal/text/text-editable-control-interface.h>
38 #if defined(DEBUG_ENABLED)
39 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
42 constexpr float MAX_FLOAT = std::numeric_limits<float>::max();
44 const std::string EMPTY_STRING("");
46 int ConvertPixelToPint(float pixel)
48 unsigned int horizontalDpi = 0u;
49 unsigned int verticalDpi = 0u;
50 Dali::TextAbstraction::FontClient fontClient = Dali::TextAbstraction::FontClient::Get();
51 fontClient.GetDpi(horizontalDpi, verticalDpi);
53 return (pixel * 72.f) / static_cast<float>(horizontalDpi);
64 // public : Constructor.
66 ControllerPtr Controller::New()
68 return ControllerPtr(new Controller());
71 ControllerPtr Controller::New(ControlInterface* controlInterface)
73 return ControllerPtr(new Controller(controlInterface));
76 ControllerPtr Controller::New(ControlInterface* controlInterface,
77 EditableControlInterface* editableControlInterface,
78 SelectableControlInterface* selectableControlInterface,
79 AnchorControlInterface* anchorControlInterface)
81 return ControllerPtr(new Controller(controlInterface,
82 editableControlInterface,
83 selectableControlInterface,
84 anchorControlInterface));
87 // public : Configure the text controller.
89 void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
93 delete mImpl->mEventData;
94 mImpl->mEventData = NULL;
96 // Nothing else to do.
100 if(NULL == mImpl->mEventData)
102 mImpl->mEventData = new EventData(decorator, inputMethodContext);
106 void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
108 // Metrics for bitmap & vector based glyphs are different
109 mImpl->mMetrics->SetGlyphType(glyphType);
111 // Clear the font-specific data
114 mImpl->RequestRelayout();
117 void Controller::SetMarkupProcessorEnabled(bool enable)
119 if(enable != mImpl->mMarkupProcessorEnabled)
121 //If Text was already set, call the SetText again for enabling or disabling markup
122 mImpl->mMarkupProcessorEnabled = enable;
129 bool Controller::IsMarkupProcessorEnabled() const
131 return mImpl->mMarkupProcessorEnabled;
134 void Controller::SetAutoScrollEnabled(bool enable)
136 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);
138 if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
142 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n");
143 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
152 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
153 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
160 mImpl->mIsAutoScrollEnabled = enable;
161 mImpl->RequestRelayout();
165 DALI_LOG_WARNING("Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n");
166 mImpl->mIsAutoScrollEnabled = false;
170 bool Controller::IsAutoScrollEnabled() const
172 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
174 return mImpl->mIsAutoScrollEnabled;
177 CharacterDirection Controller::GetAutoScrollDirection() const
179 return mImpl->mIsTextDirectionRTL;
182 float Controller::GetAutoScrollLineAlignment() const
186 if(mImpl->mModel->mVisualModel &&
187 (0u != mImpl->mModel->mVisualModel->mLines.Count()))
189 offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
195 void Controller::SetHorizontalScrollEnabled(bool enable)
197 if((NULL != mImpl->mEventData) &&
198 mImpl->mEventData->mDecorator)
200 mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
203 bool Controller::IsHorizontalScrollEnabled() const
205 if((NULL != mImpl->mEventData) &&
206 mImpl->mEventData->mDecorator)
208 return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
214 void Controller::SetVerticalScrollEnabled(bool enable)
216 if((NULL != mImpl->mEventData) &&
217 mImpl->mEventData->mDecorator)
219 if(mImpl->mEventData->mDecorator)
221 mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
226 bool Controller::IsVerticalScrollEnabled() const
228 if((NULL != mImpl->mEventData) &&
229 mImpl->mEventData->mDecorator)
231 return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
237 void Controller::SetSmoothHandlePanEnabled(bool enable)
239 if((NULL != mImpl->mEventData) &&
240 mImpl->mEventData->mDecorator)
242 mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
246 bool Controller::IsSmoothHandlePanEnabled() const
248 if((NULL != mImpl->mEventData) &&
249 mImpl->mEventData->mDecorator)
251 return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
257 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
259 mImpl->mMaximumNumberOfCharacters = maxCharacters;
262 int Controller::GetMaximumNumberOfCharacters()
264 return mImpl->mMaximumNumberOfCharacters;
267 void Controller::SetEnableCursorBlink(bool enable)
269 DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled");
271 if(NULL != mImpl->mEventData)
273 mImpl->mEventData->mCursorBlinkEnabled = enable;
276 mImpl->mEventData->mDecorator)
278 mImpl->mEventData->mDecorator->StopCursorBlink();
283 bool Controller::GetEnableCursorBlink() const
285 if(NULL != mImpl->mEventData)
287 return 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;
361 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
363 mImpl->RequestRelayout();
367 VerticalAlignment::Type Controller::GetVerticalAlignment() const
369 return mImpl->mModel->mVerticalAlignment;
372 bool Controller::IsIgnoreSpacesAfterText() const
374 return mImpl->mModel->mIgnoreSpacesAfterText;
377 void Controller::SetIgnoreSpacesAfterText(bool ignore)
379 mImpl->mModel->mIgnoreSpacesAfterText = ignore;
382 bool Controller::IsMatchSystemLanguageDirection() const
384 return mImpl->mModel->mMatchSystemLanguageDirection;
387 void Controller::SetMatchSystemLanguageDirection(bool match)
389 mImpl->mModel->mMatchSystemLanguageDirection = match;
392 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
394 mImpl->mLayoutDirection = layoutDirection;
397 bool Controller::IsShowingRealText() const
399 return mImpl->IsShowingRealText();
402 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
404 if(lineWrapMode != mImpl->mModel->mLineWrapMode)
406 // Set the text wrap mode.
407 mImpl->mModel->mLineWrapMode = lineWrapMode;
409 // Update Text layout for applying wrap mode
410 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
415 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
416 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
417 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
420 mImpl->RequestRelayout();
424 Text::LineWrap::Mode Controller::GetLineWrapMode() const
426 return mImpl->mModel->mLineWrapMode;
429 void Controller::SetTextElideEnabled(bool enabled)
431 mImpl->mModel->mElideEnabled = enabled;
434 bool Controller::IsTextElideEnabled() const
436 return mImpl->mModel->mElideEnabled;
439 void Controller::SetTextFitEnabled(bool enabled)
441 mImpl->mTextFitEnabled = enabled;
444 bool Controller::IsTextFitEnabled() const
446 return mImpl->mTextFitEnabled;
449 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
455 mImpl->mTextFitMinSize = minSize;
460 mImpl->mTextFitMinSize = ConvertPixelToPint(minSize);
466 float Controller::GetTextFitMinSize() const
468 return mImpl->mTextFitMinSize;
471 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
477 mImpl->mTextFitMaxSize = maxSize;
482 mImpl->mTextFitMaxSize = ConvertPixelToPint(maxSize);
488 float Controller::GetTextFitMaxSize() const
490 return mImpl->mTextFitMaxSize;
493 void Controller::SetTextFitStepSize(float step, FontSizeType type)
499 mImpl->mTextFitStepSize = step;
504 mImpl->mTextFitStepSize = ConvertPixelToPint(step);
510 float Controller::GetTextFitStepSize() const
512 return mImpl->mTextFitStepSize;
515 void Controller::SetTextFitContentSize(Vector2 size)
517 mImpl->mTextFitContentSize = size;
520 Vector2 Controller::GetTextFitContentSize() const
522 return mImpl->mTextFitContentSize;
525 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
527 PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
530 bool Controller::IsPlaceholderTextElideEnabled() const
532 return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
535 void Controller::SetSelectionEnabled(bool enabled)
537 mImpl->mEventData->mSelectionEnabled = enabled;
540 bool Controller::IsSelectionEnabled() const
542 return mImpl->mEventData->mSelectionEnabled;
545 void Controller::SetShiftSelectionEnabled(bool enabled)
547 mImpl->mEventData->mShiftSelectionFlag = enabled;
550 bool Controller::IsShiftSelectionEnabled() const
552 return mImpl->mEventData->mShiftSelectionFlag;
555 void Controller::SetGrabHandleEnabled(bool enabled)
557 mImpl->mEventData->mGrabHandleEnabled = enabled;
560 bool Controller::IsGrabHandleEnabled() const
562 return mImpl->mEventData->mGrabHandleEnabled;
565 void Controller::SetGrabHandlePopupEnabled(bool enabled)
567 mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
570 bool Controller::IsGrabHandlePopupEnabled() const
572 return mImpl->mEventData->mGrabHandlePopupEnabled;
577 void Controller::SetText(const std::string& text)
579 TextUpdater::SetText(*this, text);
582 void Controller::GetText(std::string& text) const
584 if(!mImpl->IsShowingPlaceholderText())
586 // Retrieves the text string.
587 mImpl->GetText(0u, text);
591 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this);
595 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
597 PlaceholderHandler::SetPlaceholderText(*this, type, text);
600 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
602 PlaceholderHandler::GetPlaceholderText(*this, type, text);
605 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
607 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n");
609 if(!mImpl->mFontDefaults->familyDefined) // If user defined font then should not update when system font changes
611 DALI_LOG_INFO(gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str());
612 mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
616 mImpl->RequestRelayout();
620 void Controller::RetrieveSelection(std::string& selectedText) const
622 mImpl->RetrieveSelection(selectedText, false);
625 void Controller::SetSelection(int start, int end)
627 mImpl->SetSelection(start, end);
630 std::pair<int, int> Controller::GetSelectionIndexes() const
632 return mImpl->GetSelectionIndexes();
635 void Controller::CopyStringToClipboard(const std::string& source)
637 mImpl->CopyStringToClipboard(source);
640 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
642 mImpl->SendSelectionToClipboard(deleteAfterSending);
645 // public : Default style & Input style
647 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
649 if(NULL == mImpl->mFontDefaults)
651 mImpl->mFontDefaults = new FontDefaults();
654 mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
655 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
656 mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
658 if(mImpl->mEventData)
660 // Update the cursor position if it's in editing mode
661 if(EventData::IsEditingState(mImpl->mEventData->mState))
663 mImpl->mEventData->mDecoratorUpdated = true;
664 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated.
668 // Clear the font-specific data
671 mImpl->RequestRelayout();
674 const std::string& Controller::GetDefaultFontFamily() const
676 if(NULL != mImpl->mFontDefaults)
678 return mImpl->mFontDefaults->mFontDescription.family;
684 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
686 PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
689 const std::string& Controller::GetPlaceholderFontFamily() const
691 return PlaceholderHandler::GetPlaceholderFontFamily(*this);
694 void Controller::SetDefaultFontWeight(FontWeight weight)
696 if(NULL == mImpl->mFontDefaults)
698 mImpl->mFontDefaults = new FontDefaults();
701 mImpl->mFontDefaults->mFontDescription.weight = weight;
702 mImpl->mFontDefaults->weightDefined = true;
704 if(mImpl->mEventData)
706 // Update the cursor position if it's in editing mode
707 if(EventData::IsEditingState(mImpl->mEventData->mState))
709 mImpl->mEventData->mDecoratorUpdated = true;
710 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated.
714 // Clear the font-specific data
717 mImpl->RequestRelayout();
720 bool Controller::IsDefaultFontWeightDefined() const
722 if(NULL != mImpl->mFontDefaults)
724 return mImpl->mFontDefaults->weightDefined;
730 FontWeight Controller::GetDefaultFontWeight() const
732 if(NULL != mImpl->mFontDefaults)
734 return mImpl->mFontDefaults->mFontDescription.weight;
737 return TextAbstraction::FontWeight::NORMAL;
740 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
742 PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
745 bool Controller::IsPlaceholderTextFontWeightDefined() const
747 return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
751 FontWeight Controller::GetPlaceholderTextFontWeight() const
753 return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
756 void Controller::SetDefaultFontWidth(FontWidth width)
758 if(NULL == mImpl->mFontDefaults)
760 mImpl->mFontDefaults = new FontDefaults();
763 mImpl->mFontDefaults->mFontDescription.width = width;
764 mImpl->mFontDefaults->widthDefined = true;
766 if(mImpl->mEventData)
768 // Update the cursor position if it's in editing mode
769 if(EventData::IsEditingState(mImpl->mEventData->mState))
771 mImpl->mEventData->mDecoratorUpdated = true;
772 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated.
776 // Clear the font-specific data
779 mImpl->RequestRelayout();
782 bool Controller::IsDefaultFontWidthDefined() const
784 if(NULL != mImpl->mFontDefaults)
786 return mImpl->mFontDefaults->widthDefined;
792 FontWidth Controller::GetDefaultFontWidth() const
794 if(NULL != mImpl->mFontDefaults)
796 return mImpl->mFontDefaults->mFontDescription.width;
799 return TextAbstraction::FontWidth::NORMAL;
802 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
804 PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
807 bool Controller::IsPlaceholderTextFontWidthDefined() const
809 return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
812 FontWidth Controller::GetPlaceholderTextFontWidth() const
814 return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
817 void Controller::SetDefaultFontSlant(FontSlant slant)
819 if(NULL == mImpl->mFontDefaults)
821 mImpl->mFontDefaults = new FontDefaults();
824 mImpl->mFontDefaults->mFontDescription.slant = slant;
825 mImpl->mFontDefaults->slantDefined = true;
827 if(mImpl->mEventData)
829 // Update the cursor position if it's in editing mode
830 if(EventData::IsEditingState(mImpl->mEventData->mState))
832 mImpl->mEventData->mDecoratorUpdated = true;
833 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated.
837 // Clear the font-specific data
840 mImpl->RequestRelayout();
843 bool Controller::IsDefaultFontSlantDefined() const
845 if(NULL != mImpl->mFontDefaults)
847 return mImpl->mFontDefaults->slantDefined;
852 FontSlant Controller::GetDefaultFontSlant() const
854 if(NULL != mImpl->mFontDefaults)
856 return mImpl->mFontDefaults->mFontDescription.slant;
859 return TextAbstraction::FontSlant::NORMAL;
862 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
864 PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
867 bool Controller::IsPlaceholderTextFontSlantDefined() const
869 return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
872 FontSlant Controller::GetPlaceholderTextFontSlant() const
874 return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
877 void Controller::SetFontSizeScale(float scale)
879 mImpl->mFontSizeScale = scale;
881 if(mImpl->mEventData)
883 // Update the cursor position if it's in editing mode
884 if(EventData::IsEditingState(mImpl->mEventData->mState))
886 mImpl->mEventData->mDecoratorUpdated = true;
887 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
891 // Clear the font-specific data
894 mImpl->RequestRelayout();
897 float Controller::GetFontSizeScale() const
899 if(nullptr != mImpl->mFontDefaults)
901 return mImpl->mFontSizeScale;
907 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
909 if(NULL == mImpl->mFontDefaults)
911 mImpl->mFontDefaults = new FontDefaults();
918 mImpl->mFontDefaults->mDefaultPointSize = fontSize;
919 mImpl->mFontDefaults->sizeDefined = true;
924 // Point size = Pixel size * 72.f / DPI
925 unsigned int horizontalDpi = 0u;
926 unsigned int verticalDpi = 0u;
927 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
928 fontClient.GetDpi(horizontalDpi, verticalDpi);
930 mImpl->mFontDefaults->mDefaultPointSize = (fontSize * 72.f) / static_cast<float>(horizontalDpi);
931 mImpl->mFontDefaults->sizeDefined = true;
936 if(mImpl->mEventData)
938 // Update the cursor position if it's in editing mode
939 if(EventData::IsEditingState(mImpl->mEventData->mState))
941 mImpl->mEventData->mDecoratorUpdated = true;
942 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
946 // Clear the font-specific data
949 mImpl->RequestRelayout();
952 float Controller::GetDefaultFontSize(FontSizeType type) const
955 if(NULL != mImpl->mFontDefaults)
961 value = mImpl->mFontDefaults->mDefaultPointSize;
966 // Pixel size = Point size * DPI / 72.f
967 unsigned int horizontalDpi = 0u;
968 unsigned int verticalDpi = 0u;
969 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
970 fontClient.GetDpi(horizontalDpi, verticalDpi);
972 value = mImpl->mFontDefaults->mDefaultPointSize * static_cast<float>(horizontalDpi) / 72.f;
982 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
984 PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
987 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
989 return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
992 void Controller::SetDefaultColor(const Vector4& color)
994 mImpl->mTextColor = color;
996 if(!mImpl->IsShowingPlaceholderText())
998 mImpl->mModel->mVisualModel->SetTextColor(color);
1000 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
1002 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1004 mImpl->RequestRelayout();
1008 const Vector4& Controller::GetDefaultColor() const
1010 return mImpl->mTextColor;
1013 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
1015 PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
1018 const Vector4& Controller::GetPlaceholderTextColor() const
1020 return PlaceholderHandler::GetPlaceholderTextColor(*this);
1023 void Controller::SetShadowOffset(const Vector2& shadowOffset)
1025 mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
1027 mImpl->RequestRelayout();
1030 const Vector2& Controller::GetShadowOffset() const
1032 return mImpl->mModel->mVisualModel->GetShadowOffset();
1035 void Controller::SetShadowColor(const Vector4& shadowColor)
1037 mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
1039 mImpl->RequestRelayout();
1042 const Vector4& Controller::GetShadowColor() const
1044 return mImpl->mModel->mVisualModel->GetShadowColor();
1047 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
1049 if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
1051 mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
1053 mImpl->RequestRelayout();
1057 const float& Controller::GetShadowBlurRadius() const
1059 return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
1062 void Controller::SetUnderlineColor(const Vector4& color)
1064 mImpl->mModel->mVisualModel->SetUnderlineColor(color);
1066 mImpl->RequestRelayout();
1069 const Vector4& Controller::GetUnderlineColor() const
1071 return mImpl->mModel->mVisualModel->GetUnderlineColor();
1074 void Controller::SetUnderlineEnabled(bool enabled)
1076 mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
1078 mImpl->RequestRelayout();
1081 bool Controller::IsUnderlineEnabled() const
1083 return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
1086 void Controller::SetUnderlineHeight(float height)
1088 mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
1090 mImpl->RequestRelayout();
1093 float Controller::GetUnderlineHeight() const
1095 return mImpl->mModel->mVisualModel->GetUnderlineHeight();
1098 void Controller::SetOutlineColor(const Vector4& color)
1100 mImpl->mModel->mVisualModel->SetOutlineColor(color);
1102 mImpl->RequestRelayout();
1105 const Vector4& Controller::GetOutlineColor() const
1107 return mImpl->mModel->mVisualModel->GetOutlineColor();
1110 void Controller::SetOutlineWidth(uint16_t width)
1112 mImpl->mModel->mVisualModel->SetOutlineWidth(width);
1114 mImpl->RequestRelayout();
1117 uint16_t Controller::GetOutlineWidth() const
1119 return mImpl->mModel->mVisualModel->GetOutlineWidth();
1122 void Controller::SetBackgroundColor(const Vector4& color)
1124 mImpl->mModel->mVisualModel->SetBackgroundColor(color);
1126 mImpl->RequestRelayout();
1129 const Vector4& Controller::GetBackgroundColor() const
1131 return mImpl->mModel->mVisualModel->GetBackgroundColor();
1134 void Controller::SetBackgroundEnabled(bool enabled)
1136 mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
1138 mImpl->RequestRelayout();
1141 bool Controller::IsBackgroundEnabled() const
1143 return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
1146 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
1148 if(NULL == mImpl->mEmbossDefaults)
1150 mImpl->mEmbossDefaults = new EmbossDefaults();
1153 mImpl->mEmbossDefaults->properties = embossProperties;
1156 const std::string& Controller::GetDefaultEmbossProperties() const
1158 if(NULL != mImpl->mEmbossDefaults)
1160 return mImpl->mEmbossDefaults->properties;
1163 return EMPTY_STRING;
1166 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
1168 if(NULL == mImpl->mOutlineDefaults)
1170 mImpl->mOutlineDefaults = new OutlineDefaults();
1173 mImpl->mOutlineDefaults->properties = outlineProperties;
1176 const std::string& Controller::GetDefaultOutlineProperties() const
1178 if(NULL != mImpl->mOutlineDefaults)
1180 return mImpl->mOutlineDefaults->properties;
1183 return EMPTY_STRING;
1186 bool Controller::SetDefaultLineSpacing(float lineSpacing)
1188 if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
1190 mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
1191 mImpl->mRecalculateNaturalSize = true;
1197 float Controller::GetDefaultLineSpacing() const
1199 return mImpl->mLayoutEngine.GetDefaultLineSpacing();
1202 bool Controller::SetDefaultLineSize(float lineSize)
1204 if(std::fabs(lineSize - mImpl->mLayoutEngine.GetDefaultLineSize()) > Math::MACHINE_EPSILON_1000)
1206 mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
1207 mImpl->mRecalculateNaturalSize = true;
1213 float Controller::GetDefaultLineSize() const
1215 return mImpl->mLayoutEngine.GetDefaultLineSize();
1218 void Controller::SetInputColor(const Vector4& color)
1220 if(NULL != mImpl->mEventData)
1222 mImpl->mEventData->mInputStyle.textColor = color;
1223 mImpl->mEventData->mInputStyle.isDefaultColor = false;
1225 if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState)
1227 const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
1229 // Get start and end position of selection
1230 const CharacterIndex startOfSelectedText = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
1231 const Length lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
1233 // Add the color run.
1234 const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
1235 mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
1237 ColorRun& colorRun = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
1238 colorRun.color = color;
1239 colorRun.characterRun.characterIndex = startOfSelectedText;
1240 colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
1242 // Request to relayout.
1243 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1244 mImpl->RequestRelayout();
1246 mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
1247 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
1248 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText;
1253 const Vector4& Controller::GetInputColor() const
1255 if(NULL != mImpl->mEventData)
1257 return mImpl->mEventData->mInputStyle.textColor;
1260 // Return the default text's color if there is no EventData.
1261 return mImpl->mTextColor;
1264 void Controller::SetInputFontFamily(const std::string& fontFamily)
1266 InputFontHandler::SetInputFontFamily(*this, fontFamily);
1269 const std::string& Controller::GetInputFontFamily() const
1271 return InputFontHandler::GetInputFontFamily(*this);
1274 void Controller::SetInputFontWeight(FontWeight weight)
1276 InputFontHandler::SetInputFontWeight(*this, weight);
1279 bool Controller::IsInputFontWeightDefined() const
1281 return InputFontHandler::IsInputFontWeightDefined(*this);
1284 FontWeight Controller::GetInputFontWeight() const
1286 return InputFontHandler::GetInputFontWeight(*this);
1289 void Controller::SetInputFontWidth(FontWidth width)
1291 InputFontHandler::SetInputFontWidth(*this, width);
1294 bool Controller::IsInputFontWidthDefined() const
1296 return InputFontHandler::IsInputFontWidthDefined(*this);
1299 FontWidth Controller::GetInputFontWidth() const
1301 return InputFontHandler::GetInputFontWidth(*this);
1304 void Controller::SetInputFontSlant(FontSlant slant)
1306 InputFontHandler::SetInputFontSlant(*this, slant);
1309 bool Controller::IsInputFontSlantDefined() const
1311 return InputFontHandler::IsInputFontSlantDefined(*this);
1314 FontSlant Controller::GetInputFontSlant() const
1316 return InputFontHandler::GetInputFontSlant(*this);
1319 void Controller::SetInputFontPointSize(float size)
1321 InputFontHandler::SetInputFontPointSize(*this, size);
1324 float Controller::GetInputFontPointSize() const
1326 return InputFontHandler::GetInputFontPointSize(*this);
1329 void Controller::SetInputLineSpacing(float lineSpacing)
1331 if(NULL != mImpl->mEventData)
1333 mImpl->mEventData->mInputStyle.lineSpacing = lineSpacing;
1334 mImpl->mEventData->mInputStyle.isLineSpacingDefined = true;
1338 float Controller::GetInputLineSpacing() const
1340 if(NULL != mImpl->mEventData)
1342 return mImpl->mEventData->mInputStyle.lineSpacing;
1348 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
1350 if(NULL != mImpl->mEventData)
1352 mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties;
1356 const std::string& Controller::GetInputShadowProperties() const
1358 if(NULL != mImpl->mEventData)
1360 return mImpl->mEventData->mInputStyle.shadowProperties;
1363 return EMPTY_STRING;
1366 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
1368 if(NULL != mImpl->mEventData)
1370 mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties;
1374 const std::string& Controller::GetInputUnderlineProperties() const
1376 if(NULL != mImpl->mEventData)
1378 return mImpl->mEventData->mInputStyle.underlineProperties;
1381 return EMPTY_STRING;
1384 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1386 if(NULL != mImpl->mEventData)
1388 mImpl->mEventData->mInputStyle.embossProperties = embossProperties;
1392 const std::string& Controller::GetInputEmbossProperties() const
1394 if(NULL != mImpl->mEventData)
1396 return mImpl->mEventData->mInputStyle.embossProperties;
1399 return GetDefaultEmbossProperties();
1402 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1404 if(NULL != mImpl->mEventData)
1406 mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties;
1410 const std::string& Controller::GetInputOutlineProperties() const
1412 if(NULL != mImpl->mEventData)
1414 return mImpl->mEventData->mInputStyle.outlineProperties;
1417 return GetDefaultOutlineProperties();
1420 void Controller::SetInputModePassword(bool passwordInput)
1422 if(NULL != mImpl->mEventData)
1424 mImpl->mEventData->mPasswordInput = passwordInput;
1428 bool Controller::IsInputModePassword()
1430 if(NULL != mImpl->mEventData)
1432 return mImpl->mEventData->mPasswordInput;
1437 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1439 if(NULL != mImpl->mEventData)
1441 mImpl->mEventData->mDoubleTapAction = action;
1445 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1447 NoTextTap::Action action = NoTextTap::NO_ACTION;
1449 if(NULL != mImpl->mEventData)
1451 action = mImpl->mEventData->mDoubleTapAction;
1457 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1459 if(NULL != mImpl->mEventData)
1461 mImpl->mEventData->mLongPressAction = action;
1465 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1467 NoTextTap::Action action = NoTextTap::NO_ACTION;
1469 if(NULL != mImpl->mEventData)
1471 action = mImpl->mEventData->mLongPressAction;
1477 bool Controller::IsUnderlineSetByString()
1479 return mImpl->mUnderlineSetByString;
1482 void Controller::UnderlineSetByString(bool setByString)
1484 mImpl->mUnderlineSetByString = setByString;
1487 bool Controller::IsShadowSetByString()
1489 return mImpl->mShadowSetByString;
1492 void Controller::ShadowSetByString(bool setByString)
1494 mImpl->mShadowSetByString = setByString;
1497 bool Controller::IsOutlineSetByString()
1499 return mImpl->mOutlineSetByString;
1502 void Controller::OutlineSetByString(bool setByString)
1504 mImpl->mOutlineSetByString = setByString;
1507 bool Controller::IsFontStyleSetByString()
1509 return mImpl->mFontStyleSetByString;
1512 void Controller::FontStyleSetByString(bool setByString)
1514 mImpl->mFontStyleSetByString = setByString;
1517 // public : Queries & retrieves.
1519 Layout::Engine& Controller::GetLayoutEngine()
1521 return mImpl->mLayoutEngine;
1524 View& Controller::GetView()
1526 return mImpl->mView;
1529 Vector3 Controller::GetNaturalSize()
1531 return Relayouter::GetNaturalSize(*this);
1534 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1536 return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1539 void Controller::FitPointSizeforLayout(Size layoutSize)
1541 Relayouter::FitPointSizeforLayout(*this, layoutSize);
1544 float Controller::GetHeightForWidth(float width)
1546 return Relayouter::GetHeightForWidth(*this, width);
1549 int Controller::GetLineCount(float width)
1551 GetHeightForWidth(width);
1552 int numberofLines = mImpl->mModel->GetNumberOfLines();
1553 return numberofLines;
1556 const ModelInterface* const Controller::GetTextModel() const
1558 return mImpl->mModel.Get();
1561 float Controller::GetScrollAmountByUserInput()
1563 float scrollAmount = 0.0f;
1565 if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1567 scrollAmount = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1568 mImpl->mEventData->mCheckScrollAmount = false;
1570 return scrollAmount;
1573 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1575 const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1578 controlHeight = mImpl->mModel->mVisualModel->mControlSize.height;
1579 layoutHeight = layout.height;
1580 scrollPosition = mImpl->mModel->mScrollPosition.y;
1581 isScrolled = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1585 void Controller::SetHiddenInputOption(const Property::Map& options)
1587 if(NULL == mImpl->mHiddenInput)
1589 mImpl->mHiddenInput = new HiddenText(this);
1591 mImpl->mHiddenInput->SetProperties(options);
1594 void Controller::GetHiddenInputOption(Property::Map& options)
1596 if(NULL != mImpl->mHiddenInput)
1598 mImpl->mHiddenInput->GetProperties(options);
1602 void Controller::SetPlaceholderProperty(const Property::Map& map)
1604 PlaceholderHandler::SetPlaceholderProperty(*this, map);
1607 void Controller::GetPlaceholderProperty(Property::Map& map)
1609 PlaceholderHandler::GetPlaceholderProperty(*this, map);
1612 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1614 // Make sure the model is up-to-date before layouting
1615 ProcessModifyEvents();
1617 if(mImpl->mUpdateTextDirection)
1619 // Operations that can be done only once until the text changes.
1620 const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
1628 // Set the update info to relayout the whole text.
1629 mImpl->mTextUpdateInfo.mParagraphCharacterIndex = 0u;
1630 mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count();
1632 // Make sure the model is up-to-date before layouting
1633 mImpl->UpdateModel(onlyOnceOperations);
1635 Vector3 naturalSize;
1636 DoRelayout(Size(MAX_FLOAT, MAX_FLOAT),
1637 static_cast<OperationsMask>(onlyOnceOperations |
1638 LAYOUT | REORDER | UPDATE_DIRECTION),
1639 naturalSize.GetVectorXY());
1641 // Do not do again the only once operations.
1642 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending & ~onlyOnceOperations);
1644 // Clear the update info. This info will be set the next time the text is updated.
1645 mImpl->mTextUpdateInfo.Clear();
1647 // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
1648 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1650 mImpl->mUpdateTextDirection = false;
1653 return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
1656 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1658 return mImpl->mModel->GetVerticalLineAlignment();
1661 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1663 mImpl->mModel->mVerticalLineAlignment = alignment;
1666 // public : Relayout.
1668 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1670 return Relayouter::Relayout(*this, size, layoutDirection);
1673 void Controller::RequestRelayout()
1675 mImpl->RequestRelayout();
1678 // public : Input style change signals.
1680 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1682 return (NULL == mImpl->mEventData) || (0u == mImpl->mEventData->mInputStyleChangedQueue.Count());
1685 void Controller::ProcessInputStyleChangedSignals()
1687 if(NULL == mImpl->mEventData)
1693 for(Vector<InputStyle::Mask>::ConstIterator it = mImpl->mEventData->mInputStyleChangedQueue.Begin(),
1694 endIt = mImpl->mEventData->mInputStyleChangedQueue.End();
1698 const InputStyle::Mask mask = *it;
1700 if(NULL != mImpl->mEditableControlInterface)
1702 // Emit the input style changed signal.
1703 mImpl->mEditableControlInterface->InputStyleChanged(mask);
1707 mImpl->mEventData->mInputStyleChangedQueue.Clear();
1710 // public : Text-input Event Queuing.
1712 void Controller::KeyboardFocusGainEvent()
1714 EventHandler::KeyboardFocusGainEvent(*this);
1717 void Controller::KeyboardFocusLostEvent()
1719 EventHandler::KeyboardFocusLostEvent(*this);
1722 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1724 return EventHandler::KeyEvent(*this, keyEvent);
1727 void Controller::AnchorEvent(float x, float y)
1729 EventHandler::AnchorEvent(*this, x, y);
1732 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1734 EventHandler::TapEvent(*this, tapCount, x, y);
1737 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1739 EventHandler::PanEvent(*this, state, displacement);
1742 void Controller::LongPressEvent(GestureState state, float x, float y)
1744 EventHandler::LongPressEvent(*this, state, x, y);
1747 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1749 EventHandler::SelectEvent(*this, x, y, selectType);
1752 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1754 if(mImpl->mEventData)
1756 mImpl->mEventData->mCheckScrollAmount = true;
1757 mImpl->mEventData->mIsLeftHandleSelected = true;
1758 mImpl->mEventData->mIsRightHandleSelected = true;
1759 mImpl->SetTextSelectionRange(start, end);
1760 mImpl->RequestRelayout();
1761 KeyboardFocusGainEvent();
1765 Uint32Pair Controller::GetTextSelectionRange() const
1767 return mImpl->GetTextSelectionRange();
1770 CharacterIndex Controller::GetPrimaryCursorPosition() const
1772 return mImpl->GetPrimaryCursorPosition();
1775 bool Controller::SetPrimaryCursorPosition(CharacterIndex index)
1777 if(mImpl->mEventData)
1779 mImpl->mEventData->mCheckScrollAmount = true;
1780 mImpl->mEventData->mIsLeftHandleSelected = true;
1781 mImpl->mEventData->mIsRightHandleSelected = true;
1782 mImpl->mEventData->mCheckScrollAmount = true;
1783 if(mImpl->SetPrimaryCursorPosition(index))
1785 KeyboardFocusGainEvent();
1792 void Controller::SelectWholeText()
1794 SelectEvent(0.f, 0.f, SelectionType::ALL);
1797 void Controller::SelectNone()
1799 SelectEvent(0.f, 0.f, SelectionType::NONE);
1802 string Controller::GetSelectedText() const
1805 if(EventData::SELECTING == mImpl->mEventData->mState)
1807 mImpl->RetrieveSelection(text, false);
1812 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1814 return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1817 void Controller::PasteClipboardItemEvent()
1819 EventHandler::PasteClipboardItemEvent(*this);
1822 // protected : Inherit from Text::Decorator::ControllerInterface.
1824 void Controller::GetTargetSize(Vector2& targetSize)
1826 targetSize = mImpl->mModel->mVisualModel->mControlSize;
1829 void Controller::AddDecoration(Actor& actor, bool needsClipping)
1831 if(NULL != mImpl->mEditableControlInterface)
1833 mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
1837 bool Controller::IsEditable() const
1839 return mImpl->IsEditable();
1842 void Controller::SetEditable(bool editable)
1844 mImpl->SetEditable(editable);
1845 if(mImpl->mEventData && mImpl->mEventData->mDecorator)
1847 mImpl->mEventData->mDecorator->SetEditable(editable);
1851 void Controller::ScrollBy(Vector2 scroll)
1853 if(mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0))
1855 const Vector2& layoutSize = mImpl->mModel->mVisualModel->GetLayoutSize();
1856 const Vector2 currentScroll = mImpl->mModel->mScrollPosition;
1858 scroll.x = -scroll.x;
1859 scroll.y = -scroll.y;
1861 if(fabs(scroll.x) > Math::MACHINE_EPSILON_0)
1863 mImpl->mModel->mScrollPosition.x += scroll.x;
1864 mImpl->ClampHorizontalScroll(layoutSize);
1867 if(fabs(scroll.y) > Math::MACHINE_EPSILON_0)
1869 mImpl->mModel->mScrollPosition.y += scroll.y;
1870 mImpl->ClampVerticalScroll(layoutSize);
1873 if(mImpl->mModel->mScrollPosition != currentScroll)
1875 mImpl->mEventData->mDecorator->UpdatePositions(mImpl->mModel->mScrollPosition - currentScroll);
1876 mImpl->RequestRelayout();
1881 float Controller::GetHorizontalScrollPosition()
1883 if(mImpl->mEventData)
1885 //scroll values are negative internally so we convert them to positive numbers
1886 return -mImpl->mModel->mScrollPosition.x;
1891 float Controller::GetVerticalScrollPosition()
1893 if(mImpl->mEventData)
1895 //scroll values are negative internally so we convert them to positive numbers
1896 return -mImpl->mModel->mScrollPosition.y;
1901 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1903 EventHandler::DecorationEvent(*this, handleType, state, x, y);
1906 // protected : Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
1908 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1910 EventHandler::TextPopupButtonTouched(*this, button);
1913 void Controller::DisplayTimeExpired()
1915 mImpl->mEventData->mUpdateCursorPosition = true;
1916 // Apply modifications to the model
1917 mImpl->mOperationsPending = ALL_OPERATIONS;
1919 mImpl->RequestRelayout();
1922 // private : Update.
1924 void Controller::InsertText(const std::string& text, Controller::InsertType type)
1926 TextUpdater::InsertText(*this, text, type);
1929 void Controller::PasteText(const std::string& stringToPaste)
1931 TextUpdater::PasteText(*this, stringToPaste);
1934 bool Controller::RemoveText(int cursorOffset,
1935 int numberOfCharacters,
1936 UpdateInputStyleType type)
1938 return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
1941 bool Controller::RemoveSelectedText()
1943 return TextUpdater::RemoveSelectedText(*this);
1946 void Controller::InsertTextAnchor(int numberOfCharacters,
1947 CharacterIndex previousCursorIndex)
1949 TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
1952 void Controller::RemoveTextAnchor(int cursorOffset,
1953 int numberOfCharacters,
1954 CharacterIndex previousCursorIndex)
1956 TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
1959 // private : Relayout.
1961 bool Controller::DoRelayout(const Size& size,
1962 OperationsMask operationsRequired,
1965 return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
1968 void Controller::CalculateVerticalOffset(const Size& controlSize)
1970 Relayouter::CalculateVerticalOffset(*this, controlSize);
1973 // private : Events.
1975 void Controller::ProcessModifyEvents()
1977 EventHandler::ProcessModifyEvents(*this);
1980 void Controller::TextReplacedEvent()
1982 EventHandler::TextReplacedEvent(*this);
1985 void Controller::TextInsertedEvent()
1987 EventHandler::TextInsertedEvent(*this);
1990 void Controller::TextDeletedEvent()
1992 EventHandler::TextDeletedEvent(*this);
1995 bool Controller::DeleteEvent(int keyCode)
1997 return EventHandler::DeleteEvent(*this, keyCode);
2000 // private : Helpers.
2002 void Controller::ResetText()
2004 TextUpdater::ResetText(*this);
2007 void Controller::ShowPlaceholderText()
2009 PlaceholderHandler::ShowPlaceholderText(*this);
2012 void Controller::ClearFontData()
2014 if(mImpl->mFontDefaults)
2016 mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
2019 // Set flags to update the model.
2020 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
2021 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
2022 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
2024 mImpl->mTextUpdateInfo.mClearAll = true;
2025 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
2026 mImpl->mRecalculateNaturalSize = true;
2028 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
2034 UPDATE_LAYOUT_SIZE |
2039 void Controller::ClearStyleData()
2041 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
2042 mImpl->mModel->mLogicalModel->ClearFontDescriptionRuns();
2045 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
2047 // Reset the cursor position
2048 if(NULL != mImpl->mEventData)
2050 mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
2052 // Update the cursor if it's in editing mode.
2053 if(EventData::IsEditingState(mImpl->mEventData->mState))
2055 mImpl->mEventData->mUpdateCursorPosition = true;
2060 CharacterIndex Controller::GetCursorPosition()
2062 if(!mImpl->mEventData)
2065 return mImpl->mEventData->mPrimaryCursorPosition;
2068 void Controller::ResetScrollPosition()
2070 if(NULL != mImpl->mEventData)
2072 // Reset the scroll position.
2073 mImpl->mModel->mScrollPosition = Vector2::ZERO;
2074 mImpl->mEventData->mScrollAfterUpdatePosition = true;
2078 void Controller::SetControlInterface(ControlInterface* controlInterface)
2080 mImpl->mControlInterface = controlInterface;
2083 void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
2085 mImpl->mAnchorControlInterface = anchorControlInterface;
2088 bool Controller::ShouldClearFocusOnEscape() const
2090 return mImpl->mShouldClearFocusOnEscape;
2093 Actor Controller::CreateBackgroundActor()
2095 return mImpl->CreateBackgroundActor();
2098 // private : Private contructors & copy operator.
2100 Controller::Controller()
2101 : Controller(nullptr, nullptr, nullptr, nullptr)
2105 Controller::Controller(ControlInterface* controlInterface)
2106 : Controller(controlInterface, nullptr, nullptr, nullptr)
2110 Controller::Controller(ControlInterface* controlInterface,
2111 EditableControlInterface* editableControlInterface,
2112 SelectableControlInterface* selectableControlInterface,
2113 AnchorControlInterface* anchorControlInterface)
2114 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
2118 // The copy constructor and operator are left unimplemented.
2120 // protected : Destructor.
2122 Controller::~Controller()
2129 } // namespace Toolkit