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;
128 mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
131 bool Controller::IsMarkupProcessorEnabled() const
133 return mImpl->mMarkupProcessorEnabled;
136 void Controller::SetAutoScrollEnabled(bool enable)
138 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);
140 if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
144 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n");
145 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
154 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
155 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
162 mImpl->mIsAutoScrollEnabled = enable;
163 mImpl->RequestRelayout();
167 DALI_LOG_WARNING("Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n");
168 mImpl->mIsAutoScrollEnabled = false;
172 bool Controller::IsAutoScrollEnabled() const
174 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
176 return mImpl->mIsAutoScrollEnabled;
179 CharacterDirection Controller::GetAutoScrollDirection() const
181 return mImpl->mIsTextDirectionRTL;
184 float Controller::GetAutoScrollLineAlignment() const
188 if(mImpl->mModel->mVisualModel &&
189 (0u != mImpl->mModel->mVisualModel->mLines.Count()))
191 offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
197 void Controller::SetHorizontalScrollEnabled(bool enable)
199 if((NULL != mImpl->mEventData) &&
200 mImpl->mEventData->mDecorator)
202 mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
205 bool Controller::IsHorizontalScrollEnabled() const
207 if((NULL != mImpl->mEventData) &&
208 mImpl->mEventData->mDecorator)
210 return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
216 void Controller::SetVerticalScrollEnabled(bool enable)
218 if((NULL != mImpl->mEventData) &&
219 mImpl->mEventData->mDecorator)
221 if(mImpl->mEventData->mDecorator)
223 mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
228 bool Controller::IsVerticalScrollEnabled() const
230 if((NULL != mImpl->mEventData) &&
231 mImpl->mEventData->mDecorator)
233 return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
239 void Controller::SetSmoothHandlePanEnabled(bool enable)
241 if((NULL != mImpl->mEventData) &&
242 mImpl->mEventData->mDecorator)
244 mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
248 bool Controller::IsSmoothHandlePanEnabled() const
250 if((NULL != mImpl->mEventData) &&
251 mImpl->mEventData->mDecorator)
253 return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
259 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
261 mImpl->mMaximumNumberOfCharacters = maxCharacters;
264 int Controller::GetMaximumNumberOfCharacters()
266 return mImpl->mMaximumNumberOfCharacters;
269 void Controller::SetEnableCursorBlink(bool enable)
271 DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled");
273 if(NULL != mImpl->mEventData)
275 mImpl->mEventData->mCursorBlinkEnabled = enable;
278 mImpl->mEventData->mDecorator)
280 mImpl->mEventData->mDecorator->StopCursorBlink();
285 bool Controller::GetEnableCursorBlink() const
287 if(NULL != mImpl->mEventData)
289 return mImpl->mEventData->mCursorBlinkEnabled;
295 void Controller::SetMultiLineEnabled(bool enable)
297 const Layout::Engine::Type layout = enable ? Layout::Engine::MULTI_LINE_BOX : Layout::Engine::SINGLE_LINE_BOX;
299 if(layout != mImpl->mLayoutEngine.GetLayout())
301 // Set the layout type.
302 mImpl->mLayoutEngine.SetLayout(layout);
304 // Set the flags to redo the layout operations
305 const OperationsMask layoutOperations = static_cast<OperationsMask>(LAYOUT |
310 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
311 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | layoutOperations);
313 // Need to recalculate natural size
314 mImpl->mRecalculateNaturalSize = true;
316 mImpl->RequestRelayout();
320 bool Controller::IsMultiLineEnabled() const
322 return Layout::Engine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
325 void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment)
327 if(alignment != mImpl->mModel->mHorizontalAlignment)
329 // Set the alignment.
330 mImpl->mModel->mHorizontalAlignment = alignment;
332 // Set the flag to redo the alignment operation.
333 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
335 if(mImpl->mEventData)
337 mImpl->mEventData->mUpdateAlignment = true;
339 // Update the cursor if it's in editing mode
340 if(EventData::IsEditingState(mImpl->mEventData->mState))
342 mImpl->ChangeState(EventData::EDITING);
343 mImpl->mEventData->mUpdateCursorPosition = true;
347 mImpl->RequestRelayout();
351 Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const
353 return mImpl->mModel->mHorizontalAlignment;
356 void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment)
358 if(alignment != mImpl->mModel->mVerticalAlignment)
360 // Set the alignment.
361 mImpl->mModel->mVerticalAlignment = alignment;
363 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
365 mImpl->RequestRelayout();
369 VerticalAlignment::Type Controller::GetVerticalAlignment() const
371 return mImpl->mModel->mVerticalAlignment;
374 bool Controller::IsIgnoreSpacesAfterText() const
376 return mImpl->mModel->mIgnoreSpacesAfterText;
379 void Controller::SetIgnoreSpacesAfterText(bool ignore)
381 mImpl->mModel->mIgnoreSpacesAfterText = ignore;
384 bool Controller::IsMatchSystemLanguageDirection() const
386 return mImpl->mModel->mMatchSystemLanguageDirection;
389 void Controller::SetMatchSystemLanguageDirection(bool match)
391 mImpl->mModel->mMatchSystemLanguageDirection = match;
394 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
396 mImpl->mLayoutDirection = layoutDirection;
399 bool Controller::IsShowingRealText() const
401 return mImpl->IsShowingRealText();
404 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
406 if(lineWrapMode != mImpl->mModel->mLineWrapMode)
408 // Set the text wrap mode.
409 mImpl->mModel->mLineWrapMode = lineWrapMode;
411 // Update Text layout for applying wrap mode
412 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
417 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
418 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
419 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
422 mImpl->RequestRelayout();
426 Text::LineWrap::Mode Controller::GetLineWrapMode() const
428 return mImpl->mModel->mLineWrapMode;
431 void Controller::SetTextElideEnabled(bool enabled)
433 mImpl->mModel->mElideEnabled = enabled;
436 bool Controller::IsTextElideEnabled() const
438 return mImpl->mModel->mElideEnabled;
441 void Controller::SetTextFitEnabled(bool enabled)
443 mImpl->mTextFitEnabled = enabled;
446 bool Controller::IsTextFitEnabled() const
448 return mImpl->mTextFitEnabled;
451 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
457 mImpl->mTextFitMinSize = minSize;
462 mImpl->mTextFitMinSize = ConvertPixelToPint(minSize);
468 float Controller::GetTextFitMinSize() const
470 return mImpl->mTextFitMinSize;
473 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
479 mImpl->mTextFitMaxSize = maxSize;
484 mImpl->mTextFitMaxSize = ConvertPixelToPint(maxSize);
490 float Controller::GetTextFitMaxSize() const
492 return mImpl->mTextFitMaxSize;
495 void Controller::SetTextFitStepSize(float step, FontSizeType type)
501 mImpl->mTextFitStepSize = step;
506 mImpl->mTextFitStepSize = ConvertPixelToPint(step);
512 float Controller::GetTextFitStepSize() const
514 return mImpl->mTextFitStepSize;
517 void Controller::SetTextFitContentSize(Vector2 size)
519 mImpl->mTextFitContentSize = size;
522 Vector2 Controller::GetTextFitContentSize() const
524 return mImpl->mTextFitContentSize;
527 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
529 PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
532 bool Controller::IsPlaceholderTextElideEnabled() const
534 return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
537 void Controller::SetSelectionEnabled(bool enabled)
539 mImpl->mEventData->mSelectionEnabled = enabled;
542 bool Controller::IsSelectionEnabled() const
544 return mImpl->mEventData->mSelectionEnabled;
547 void Controller::SetShiftSelectionEnabled(bool enabled)
549 mImpl->mEventData->mShiftSelectionFlag = enabled;
552 bool Controller::IsShiftSelectionEnabled() const
554 return mImpl->mEventData->mShiftSelectionFlag;
557 void Controller::SetGrabHandleEnabled(bool enabled)
559 mImpl->mEventData->mGrabHandleEnabled = enabled;
562 bool Controller::IsGrabHandleEnabled() const
564 return mImpl->mEventData->mGrabHandleEnabled;
567 void Controller::SetGrabHandlePopupEnabled(bool enabled)
569 mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
572 bool Controller::IsGrabHandlePopupEnabled() const
574 return mImpl->mEventData->mGrabHandlePopupEnabled;
579 void Controller::SetText(const std::string& text)
581 TextUpdater::SetText(*this, text);
584 void Controller::GetText(std::string& text) const
586 if(!mImpl->IsShowingPlaceholderText())
588 // Retrieves the text string.
589 mImpl->GetText(0u, text);
593 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this);
597 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
599 PlaceholderHandler::SetPlaceholderText(*this, type, text);
602 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
604 PlaceholderHandler::GetPlaceholderText(*this, type, text);
607 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
609 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n");
611 if(!mImpl->mFontDefaults->familyDefined) // If user defined font then should not update when system font changes
613 DALI_LOG_INFO(gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str());
614 mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
618 mImpl->RequestRelayout();
622 void Controller::RetrieveSelection(std::string& selectedText) const
624 mImpl->RetrieveSelection(selectedText, false);
627 void Controller::SetSelection(int start, int end)
629 mImpl->SetSelection(start, end);
632 std::pair<int, int> Controller::GetSelectionIndexes() const
634 return mImpl->GetSelectionIndexes();
637 void Controller::CopyStringToClipboard(const std::string& source)
639 mImpl->CopyStringToClipboard(source);
642 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
644 mImpl->SendSelectionToClipboard(deleteAfterSending);
647 // public : Default style & Input style
649 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
651 if(NULL == mImpl->mFontDefaults)
653 mImpl->mFontDefaults = new FontDefaults();
656 mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
657 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
658 mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
660 if(mImpl->mEventData)
662 // Update the cursor position if it's in editing mode
663 if(EventData::IsEditingState(mImpl->mEventData->mState))
665 mImpl->mEventData->mDecoratorUpdated = true;
666 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated.
670 // Clear the font-specific data
673 mImpl->RequestRelayout();
676 const std::string& Controller::GetDefaultFontFamily() const
678 if(NULL != mImpl->mFontDefaults)
680 return mImpl->mFontDefaults->mFontDescription.family;
686 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
688 PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
691 const std::string& Controller::GetPlaceholderFontFamily() const
693 return PlaceholderHandler::GetPlaceholderFontFamily(*this);
696 void Controller::SetDefaultFontWeight(FontWeight weight)
698 if(NULL == mImpl->mFontDefaults)
700 mImpl->mFontDefaults = new FontDefaults();
703 mImpl->mFontDefaults->mFontDescription.weight = weight;
704 mImpl->mFontDefaults->weightDefined = true;
706 if(mImpl->mEventData)
708 // Update the cursor position if it's in editing mode
709 if(EventData::IsEditingState(mImpl->mEventData->mState))
711 mImpl->mEventData->mDecoratorUpdated = true;
712 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated.
716 // Clear the font-specific data
719 mImpl->RequestRelayout();
722 bool Controller::IsDefaultFontWeightDefined() const
724 if(NULL != mImpl->mFontDefaults)
726 return mImpl->mFontDefaults->weightDefined;
732 FontWeight Controller::GetDefaultFontWeight() const
734 if(NULL != mImpl->mFontDefaults)
736 return mImpl->mFontDefaults->mFontDescription.weight;
739 return TextAbstraction::FontWeight::NORMAL;
742 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
744 PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
747 bool Controller::IsPlaceholderTextFontWeightDefined() const
749 return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
753 FontWeight Controller::GetPlaceholderTextFontWeight() const
755 return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
758 void Controller::SetDefaultFontWidth(FontWidth width)
760 if(NULL == mImpl->mFontDefaults)
762 mImpl->mFontDefaults = new FontDefaults();
765 mImpl->mFontDefaults->mFontDescription.width = width;
766 mImpl->mFontDefaults->widthDefined = true;
768 if(mImpl->mEventData)
770 // Update the cursor position if it's in editing mode
771 if(EventData::IsEditingState(mImpl->mEventData->mState))
773 mImpl->mEventData->mDecoratorUpdated = true;
774 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated.
778 // Clear the font-specific data
781 mImpl->RequestRelayout();
784 bool Controller::IsDefaultFontWidthDefined() const
786 if(NULL != mImpl->mFontDefaults)
788 return mImpl->mFontDefaults->widthDefined;
794 FontWidth Controller::GetDefaultFontWidth() const
796 if(NULL != mImpl->mFontDefaults)
798 return mImpl->mFontDefaults->mFontDescription.width;
801 return TextAbstraction::FontWidth::NORMAL;
804 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
806 PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
809 bool Controller::IsPlaceholderTextFontWidthDefined() const
811 return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
814 FontWidth Controller::GetPlaceholderTextFontWidth() const
816 return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
819 void Controller::SetDefaultFontSlant(FontSlant slant)
821 if(NULL == mImpl->mFontDefaults)
823 mImpl->mFontDefaults = new FontDefaults();
826 mImpl->mFontDefaults->mFontDescription.slant = slant;
827 mImpl->mFontDefaults->slantDefined = true;
829 if(mImpl->mEventData)
831 // Update the cursor position if it's in editing mode
832 if(EventData::IsEditingState(mImpl->mEventData->mState))
834 mImpl->mEventData->mDecoratorUpdated = true;
835 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated.
839 // Clear the font-specific data
842 mImpl->RequestRelayout();
845 bool Controller::IsDefaultFontSlantDefined() const
847 if(NULL != mImpl->mFontDefaults)
849 return mImpl->mFontDefaults->slantDefined;
854 FontSlant Controller::GetDefaultFontSlant() const
856 if(NULL != mImpl->mFontDefaults)
858 return mImpl->mFontDefaults->mFontDescription.slant;
861 return TextAbstraction::FontSlant::NORMAL;
864 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
866 PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
869 bool Controller::IsPlaceholderTextFontSlantDefined() const
871 return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
874 FontSlant Controller::GetPlaceholderTextFontSlant() const
876 return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
879 void Controller::SetFontSizeScale(float scale)
881 mImpl->mFontSizeScale = scale;
883 if(mImpl->mEventData)
885 // Update the cursor position if it's in editing mode
886 if(EventData::IsEditingState(mImpl->mEventData->mState))
888 mImpl->mEventData->mDecoratorUpdated = true;
889 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
893 // Clear the font-specific data
896 mImpl->RequestRelayout();
899 float Controller::GetFontSizeScale() const
901 if(nullptr != mImpl->mFontDefaults)
903 return mImpl->mFontSizeScale;
909 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
911 if(NULL == mImpl->mFontDefaults)
913 mImpl->mFontDefaults = new FontDefaults();
920 mImpl->mFontDefaults->mDefaultPointSize = fontSize;
921 mImpl->mFontDefaults->sizeDefined = true;
926 // Point size = Pixel size * 72.f / DPI
927 unsigned int horizontalDpi = 0u;
928 unsigned int verticalDpi = 0u;
929 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
930 fontClient.GetDpi(horizontalDpi, verticalDpi);
932 mImpl->mFontDefaults->mDefaultPointSize = (fontSize * 72.f) / static_cast<float>(horizontalDpi);
933 mImpl->mFontDefaults->sizeDefined = true;
938 if(mImpl->mEventData)
940 // Update the cursor position if it's in editing mode
941 if(EventData::IsEditingState(mImpl->mEventData->mState))
943 mImpl->mEventData->mDecoratorUpdated = true;
944 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
948 // Clear the font-specific data
951 mImpl->RequestRelayout();
954 float Controller::GetDefaultFontSize(FontSizeType type) const
957 if(NULL != mImpl->mFontDefaults)
963 value = mImpl->mFontDefaults->mDefaultPointSize;
968 // Pixel size = Point size * DPI / 72.f
969 unsigned int horizontalDpi = 0u;
970 unsigned int verticalDpi = 0u;
971 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
972 fontClient.GetDpi(horizontalDpi, verticalDpi);
974 value = mImpl->mFontDefaults->mDefaultPointSize * static_cast<float>(horizontalDpi) / 72.f;
984 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
986 PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
989 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
991 return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
994 void Controller::SetDefaultColor(const Vector4& color)
996 mImpl->mTextColor = color;
998 if(!mImpl->IsShowingPlaceholderText())
1000 mImpl->mModel->mVisualModel->SetTextColor(color);
1002 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
1004 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1006 mImpl->RequestRelayout();
1010 const Vector4& Controller::GetDefaultColor() const
1012 return mImpl->mTextColor;
1015 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
1017 PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
1020 const Vector4& Controller::GetPlaceholderTextColor() const
1022 return PlaceholderHandler::GetPlaceholderTextColor(*this);
1025 void Controller::SetShadowOffset(const Vector2& shadowOffset)
1027 mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
1029 mImpl->RequestRelayout();
1032 const Vector2& Controller::GetShadowOffset() const
1034 return mImpl->mModel->mVisualModel->GetShadowOffset();
1037 void Controller::SetShadowColor(const Vector4& shadowColor)
1039 mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
1041 mImpl->RequestRelayout();
1044 const Vector4& Controller::GetShadowColor() const
1046 return mImpl->mModel->mVisualModel->GetShadowColor();
1049 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
1051 if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
1053 mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
1055 mImpl->RequestRelayout();
1059 const float& Controller::GetShadowBlurRadius() const
1061 return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
1064 void Controller::SetUnderlineColor(const Vector4& color)
1066 mImpl->mModel->mVisualModel->SetUnderlineColor(color);
1068 mImpl->RequestRelayout();
1071 const Vector4& Controller::GetUnderlineColor() const
1073 return mImpl->mModel->mVisualModel->GetUnderlineColor();
1076 void Controller::SetUnderlineEnabled(bool enabled)
1078 mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
1080 mImpl->RequestRelayout();
1083 bool Controller::IsUnderlineEnabled() const
1085 return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
1088 void Controller::SetUnderlineHeight(float height)
1090 mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
1092 mImpl->RequestRelayout();
1095 float Controller::GetUnderlineHeight() const
1097 return mImpl->mModel->mVisualModel->GetUnderlineHeight();
1100 void Controller::SetOutlineColor(const Vector4& color)
1102 mImpl->mModel->mVisualModel->SetOutlineColor(color);
1104 mImpl->RequestRelayout();
1107 const Vector4& Controller::GetOutlineColor() const
1109 return mImpl->mModel->mVisualModel->GetOutlineColor();
1112 void Controller::SetOutlineWidth(uint16_t width)
1114 mImpl->mModel->mVisualModel->SetOutlineWidth(width);
1116 mImpl->RequestRelayout();
1119 uint16_t Controller::GetOutlineWidth() const
1121 return mImpl->mModel->mVisualModel->GetOutlineWidth();
1124 void Controller::SetBackgroundColor(const Vector4& color)
1126 mImpl->mModel->mVisualModel->SetBackgroundColor(color);
1128 mImpl->RequestRelayout();
1131 const Vector4& Controller::GetBackgroundColor() const
1133 return mImpl->mModel->mVisualModel->GetBackgroundColor();
1136 void Controller::SetBackgroundEnabled(bool enabled)
1138 mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
1140 mImpl->RequestRelayout();
1143 bool Controller::IsBackgroundEnabled() const
1145 return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
1148 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
1150 if(NULL == mImpl->mEmbossDefaults)
1152 mImpl->mEmbossDefaults = new EmbossDefaults();
1155 mImpl->mEmbossDefaults->properties = embossProperties;
1158 const std::string& Controller::GetDefaultEmbossProperties() const
1160 if(NULL != mImpl->mEmbossDefaults)
1162 return mImpl->mEmbossDefaults->properties;
1165 return EMPTY_STRING;
1168 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
1170 if(NULL == mImpl->mOutlineDefaults)
1172 mImpl->mOutlineDefaults = new OutlineDefaults();
1175 mImpl->mOutlineDefaults->properties = outlineProperties;
1178 const std::string& Controller::GetDefaultOutlineProperties() const
1180 if(NULL != mImpl->mOutlineDefaults)
1182 return mImpl->mOutlineDefaults->properties;
1185 return EMPTY_STRING;
1188 bool Controller::SetDefaultLineSpacing(float lineSpacing)
1190 if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
1192 mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
1193 mImpl->mRecalculateNaturalSize = true;
1199 float Controller::GetDefaultLineSpacing() const
1201 return mImpl->mLayoutEngine.GetDefaultLineSpacing();
1204 bool Controller::SetDefaultLineSize(float lineSize)
1206 if(std::fabs(lineSize - mImpl->mLayoutEngine.GetDefaultLineSize()) > Math::MACHINE_EPSILON_1000)
1208 mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
1209 mImpl->mRecalculateNaturalSize = true;
1215 float Controller::GetDefaultLineSize() const
1217 return mImpl->mLayoutEngine.GetDefaultLineSize();
1220 void Controller::SetInputColor(const Vector4& color)
1222 if(NULL != mImpl->mEventData)
1224 mImpl->mEventData->mInputStyle.textColor = color;
1225 mImpl->mEventData->mInputStyle.isDefaultColor = false;
1227 if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState)
1229 const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
1231 // Get start and end position of selection
1232 const CharacterIndex startOfSelectedText = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
1233 const Length lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
1235 // Add the color run.
1236 const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
1237 mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
1239 ColorRun& colorRun = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
1240 colorRun.color = color;
1241 colorRun.characterRun.characterIndex = startOfSelectedText;
1242 colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
1244 // Request to relayout.
1245 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1246 mImpl->RequestRelayout();
1248 mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
1249 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
1250 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText;
1255 const Vector4& Controller::GetInputColor() const
1257 if(NULL != mImpl->mEventData)
1259 return mImpl->mEventData->mInputStyle.textColor;
1262 // Return the default text's color if there is no EventData.
1263 return mImpl->mTextColor;
1266 void Controller::SetInputFontFamily(const std::string& fontFamily)
1268 InputFontHandler::SetInputFontFamily(*this, fontFamily);
1271 const std::string& Controller::GetInputFontFamily() const
1273 return InputFontHandler::GetInputFontFamily(*this);
1276 void Controller::SetInputFontWeight(FontWeight weight)
1278 InputFontHandler::SetInputFontWeight(*this, weight);
1281 bool Controller::IsInputFontWeightDefined() const
1283 return InputFontHandler::IsInputFontWeightDefined(*this);
1286 FontWeight Controller::GetInputFontWeight() const
1288 return InputFontHandler::GetInputFontWeight(*this);
1291 void Controller::SetInputFontWidth(FontWidth width)
1293 InputFontHandler::SetInputFontWidth(*this, width);
1296 bool Controller::IsInputFontWidthDefined() const
1298 return InputFontHandler::IsInputFontWidthDefined(*this);
1301 FontWidth Controller::GetInputFontWidth() const
1303 return InputFontHandler::GetInputFontWidth(*this);
1306 void Controller::SetInputFontSlant(FontSlant slant)
1308 InputFontHandler::SetInputFontSlant(*this, slant);
1311 bool Controller::IsInputFontSlantDefined() const
1313 return InputFontHandler::IsInputFontSlantDefined(*this);
1316 FontSlant Controller::GetInputFontSlant() const
1318 return InputFontHandler::GetInputFontSlant(*this);
1321 void Controller::SetInputFontPointSize(float size)
1323 InputFontHandler::SetInputFontPointSize(*this, size);
1326 float Controller::GetInputFontPointSize() const
1328 return InputFontHandler::GetInputFontPointSize(*this);
1331 void Controller::SetInputLineSpacing(float lineSpacing)
1333 if(NULL != mImpl->mEventData)
1335 mImpl->mEventData->mInputStyle.lineSpacing = lineSpacing;
1336 mImpl->mEventData->mInputStyle.isLineSpacingDefined = true;
1340 float Controller::GetInputLineSpacing() const
1342 if(NULL != mImpl->mEventData)
1344 return mImpl->mEventData->mInputStyle.lineSpacing;
1350 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
1352 if(NULL != mImpl->mEventData)
1354 mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties;
1358 const std::string& Controller::GetInputShadowProperties() const
1360 if(NULL != mImpl->mEventData)
1362 return mImpl->mEventData->mInputStyle.shadowProperties;
1365 return EMPTY_STRING;
1368 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
1370 if(NULL != mImpl->mEventData)
1372 mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties;
1376 const std::string& Controller::GetInputUnderlineProperties() const
1378 if(NULL != mImpl->mEventData)
1380 return mImpl->mEventData->mInputStyle.underlineProperties;
1383 return EMPTY_STRING;
1386 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1388 if(NULL != mImpl->mEventData)
1390 mImpl->mEventData->mInputStyle.embossProperties = embossProperties;
1394 const std::string& Controller::GetInputEmbossProperties() const
1396 if(NULL != mImpl->mEventData)
1398 return mImpl->mEventData->mInputStyle.embossProperties;
1401 return GetDefaultEmbossProperties();
1404 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1406 if(NULL != mImpl->mEventData)
1408 mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties;
1412 const std::string& Controller::GetInputOutlineProperties() const
1414 if(NULL != mImpl->mEventData)
1416 return mImpl->mEventData->mInputStyle.outlineProperties;
1419 return GetDefaultOutlineProperties();
1422 void Controller::SetInputModePassword(bool passwordInput)
1424 if(NULL != mImpl->mEventData)
1426 mImpl->mEventData->mPasswordInput = passwordInput;
1430 bool Controller::IsInputModePassword()
1432 if(NULL != mImpl->mEventData)
1434 return mImpl->mEventData->mPasswordInput;
1439 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1441 if(NULL != mImpl->mEventData)
1443 mImpl->mEventData->mDoubleTapAction = action;
1447 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1449 NoTextTap::Action action = NoTextTap::NO_ACTION;
1451 if(NULL != mImpl->mEventData)
1453 action = mImpl->mEventData->mDoubleTapAction;
1459 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1461 if(NULL != mImpl->mEventData)
1463 mImpl->mEventData->mLongPressAction = action;
1467 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1469 NoTextTap::Action action = NoTextTap::NO_ACTION;
1471 if(NULL != mImpl->mEventData)
1473 action = mImpl->mEventData->mLongPressAction;
1479 bool Controller::IsUnderlineSetByString()
1481 return mImpl->mUnderlineSetByString;
1484 void Controller::UnderlineSetByString(bool setByString)
1486 mImpl->mUnderlineSetByString = setByString;
1489 bool Controller::IsShadowSetByString()
1491 return mImpl->mShadowSetByString;
1494 void Controller::ShadowSetByString(bool setByString)
1496 mImpl->mShadowSetByString = setByString;
1499 bool Controller::IsOutlineSetByString()
1501 return mImpl->mOutlineSetByString;
1504 void Controller::OutlineSetByString(bool setByString)
1506 mImpl->mOutlineSetByString = setByString;
1509 bool Controller::IsFontStyleSetByString()
1511 return mImpl->mFontStyleSetByString;
1514 void Controller::FontStyleSetByString(bool setByString)
1516 mImpl->mFontStyleSetByString = setByString;
1519 // public : Queries & retrieves.
1521 Layout::Engine& Controller::GetLayoutEngine()
1523 return mImpl->mLayoutEngine;
1526 View& Controller::GetView()
1528 return mImpl->mView;
1531 Vector3 Controller::GetNaturalSize()
1533 return Relayouter::GetNaturalSize(*this);
1536 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1538 return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1541 void Controller::FitPointSizeforLayout(Size layoutSize)
1543 Relayouter::FitPointSizeforLayout(*this, layoutSize);
1546 float Controller::GetHeightForWidth(float width)
1548 return Relayouter::GetHeightForWidth(*this, width);
1551 int Controller::GetLineCount(float width)
1553 GetHeightForWidth(width);
1554 int numberofLines = mImpl->mModel->GetNumberOfLines();
1555 return numberofLines;
1558 const ModelInterface* const Controller::GetTextModel() const
1560 return mImpl->mModel.Get();
1563 float Controller::GetScrollAmountByUserInput()
1565 float scrollAmount = 0.0f;
1567 if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1569 scrollAmount = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1570 mImpl->mEventData->mCheckScrollAmount = false;
1572 return scrollAmount;
1575 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1577 const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1580 controlHeight = mImpl->mModel->mVisualModel->mControlSize.height;
1581 layoutHeight = layout.height;
1582 scrollPosition = mImpl->mModel->mScrollPosition.y;
1583 isScrolled = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1587 void Controller::SetHiddenInputOption(const Property::Map& options)
1589 if(NULL == mImpl->mHiddenInput)
1591 mImpl->mHiddenInput = new HiddenText(this);
1593 mImpl->mHiddenInput->SetProperties(options);
1596 void Controller::GetHiddenInputOption(Property::Map& options)
1598 if(NULL != mImpl->mHiddenInput)
1600 mImpl->mHiddenInput->GetProperties(options);
1604 void Controller::SetPlaceholderProperty(const Property::Map& map)
1606 PlaceholderHandler::SetPlaceholderProperty(*this, map);
1609 void Controller::GetPlaceholderProperty(Property::Map& map)
1611 PlaceholderHandler::GetPlaceholderProperty(*this, map);
1614 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1616 // Make sure the model is up-to-date before layouting
1617 ProcessModifyEvents();
1619 if(mImpl->mUpdateTextDirection)
1621 // Operations that can be done only once until the text changes.
1622 const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
1630 // Set the update info to relayout the whole text.
1631 mImpl->mTextUpdateInfo.mParagraphCharacterIndex = 0u;
1632 mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count();
1634 // Make sure the model is up-to-date before layouting
1635 mImpl->UpdateModel(onlyOnceOperations);
1637 Vector3 naturalSize;
1638 DoRelayout(Size(MAX_FLOAT, MAX_FLOAT),
1639 static_cast<OperationsMask>(onlyOnceOperations |
1640 LAYOUT | REORDER | UPDATE_DIRECTION),
1641 naturalSize.GetVectorXY());
1643 // Do not do again the only once operations.
1644 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending & ~onlyOnceOperations);
1646 // Clear the update info. This info will be set the next time the text is updated.
1647 mImpl->mTextUpdateInfo.Clear();
1649 // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
1650 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1652 mImpl->mUpdateTextDirection = false;
1655 return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
1658 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1660 return mImpl->mModel->GetVerticalLineAlignment();
1663 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1665 mImpl->mModel->mVerticalLineAlignment = alignment;
1668 // public : Relayout.
1670 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1672 return Relayouter::Relayout(*this, size, layoutDirection);
1675 void Controller::RequestRelayout()
1677 mImpl->RequestRelayout();
1680 // public : Input style change signals.
1682 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1684 return (NULL == mImpl->mEventData) || (0u == mImpl->mEventData->mInputStyleChangedQueue.Count());
1687 void Controller::ProcessInputStyleChangedSignals()
1689 if(NULL == mImpl->mEventData)
1695 for(Vector<InputStyle::Mask>::ConstIterator it = mImpl->mEventData->mInputStyleChangedQueue.Begin(),
1696 endIt = mImpl->mEventData->mInputStyleChangedQueue.End();
1700 const InputStyle::Mask mask = *it;
1702 if(NULL != mImpl->mEditableControlInterface)
1704 // Emit the input style changed signal.
1705 mImpl->mEditableControlInterface->InputStyleChanged(mask);
1709 mImpl->mEventData->mInputStyleChangedQueue.Clear();
1712 // public : Text-input Event Queuing.
1714 void Controller::KeyboardFocusGainEvent()
1716 EventHandler::KeyboardFocusGainEvent(*this);
1719 void Controller::KeyboardFocusLostEvent()
1721 EventHandler::KeyboardFocusLostEvent(*this);
1724 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1726 return EventHandler::KeyEvent(*this, keyEvent);
1729 void Controller::AnchorEvent(float x, float y)
1731 EventHandler::AnchorEvent(*this, x, y);
1734 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1736 EventHandler::TapEvent(*this, tapCount, x, y);
1739 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1741 EventHandler::PanEvent(*this, state, displacement);
1744 void Controller::LongPressEvent(GestureState state, float x, float y)
1746 EventHandler::LongPressEvent(*this, state, x, y);
1749 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1751 EventHandler::SelectEvent(*this, x, y, selectType);
1754 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1756 if(mImpl->mEventData)
1758 mImpl->mEventData->mCheckScrollAmount = true;
1759 mImpl->mEventData->mIsLeftHandleSelected = true;
1760 mImpl->mEventData->mIsRightHandleSelected = true;
1761 mImpl->SetTextSelectionRange(start, end);
1762 mImpl->RequestRelayout();
1763 KeyboardFocusGainEvent();
1767 Uint32Pair Controller::GetTextSelectionRange() const
1769 return mImpl->GetTextSelectionRange();
1772 CharacterIndex Controller::GetPrimaryCursorPosition() const
1774 return mImpl->GetPrimaryCursorPosition();
1777 bool Controller::SetPrimaryCursorPosition(CharacterIndex index)
1779 if(mImpl->mEventData)
1781 mImpl->mEventData->mCheckScrollAmount = true;
1782 mImpl->mEventData->mIsLeftHandleSelected = true;
1783 mImpl->mEventData->mIsRightHandleSelected = true;
1784 mImpl->mEventData->mCheckScrollAmount = true;
1785 if(mImpl->SetPrimaryCursorPosition(index))
1787 KeyboardFocusGainEvent();
1794 void Controller::SelectWholeText()
1796 SelectEvent(0.f, 0.f, SelectionType::ALL);
1799 void Controller::SelectNone()
1801 SelectEvent(0.f, 0.f, SelectionType::NONE);
1804 string Controller::GetSelectedText() const
1807 if(EventData::SELECTING == mImpl->mEventData->mState)
1809 mImpl->RetrieveSelection(text, false);
1814 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1816 return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1819 void Controller::PasteClipboardItemEvent()
1821 EventHandler::PasteClipboardItemEvent(*this);
1824 // protected : Inherit from Text::Decorator::ControllerInterface.
1826 void Controller::GetTargetSize(Vector2& targetSize)
1828 targetSize = mImpl->mModel->mVisualModel->mControlSize;
1831 void Controller::AddDecoration(Actor& actor, bool needsClipping)
1833 if(NULL != mImpl->mEditableControlInterface)
1835 mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
1839 bool Controller::IsEditable() const
1841 return mImpl->IsEditable();
1844 void Controller::SetEditable(bool editable)
1846 mImpl->SetEditable(editable);
1847 if(mImpl->mEventData && mImpl->mEventData->mDecorator)
1849 mImpl->mEventData->mDecorator->SetEditable(editable);
1853 void Controller::ScrollBy(Vector2 scroll)
1855 if(mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0))
1857 const Vector2& layoutSize = mImpl->mModel->mVisualModel->GetLayoutSize();
1858 const Vector2 currentScroll = mImpl->mModel->mScrollPosition;
1860 scroll.x = -scroll.x;
1861 scroll.y = -scroll.y;
1863 if(fabs(scroll.x) > Math::MACHINE_EPSILON_0)
1865 mImpl->mModel->mScrollPosition.x += scroll.x;
1866 mImpl->ClampHorizontalScroll(layoutSize);
1869 if(fabs(scroll.y) > Math::MACHINE_EPSILON_0)
1871 mImpl->mModel->mScrollPosition.y += scroll.y;
1872 mImpl->ClampVerticalScroll(layoutSize);
1875 if(mImpl->mModel->mScrollPosition != currentScroll)
1877 mImpl->mEventData->mDecorator->UpdatePositions(mImpl->mModel->mScrollPosition - currentScroll);
1878 mImpl->RequestRelayout();
1883 float Controller::GetHorizontalScrollPosition()
1885 if(mImpl->mEventData)
1887 //scroll values are negative internally so we convert them to positive numbers
1888 return -mImpl->mModel->mScrollPosition.x;
1893 float Controller::GetVerticalScrollPosition()
1895 if(mImpl->mEventData)
1897 //scroll values are negative internally so we convert them to positive numbers
1898 return -mImpl->mModel->mScrollPosition.y;
1903 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1905 EventHandler::DecorationEvent(*this, handleType, state, x, y);
1908 // protected : Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
1910 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1912 EventHandler::TextPopupButtonTouched(*this, button);
1915 void Controller::DisplayTimeExpired()
1917 mImpl->mEventData->mUpdateCursorPosition = true;
1918 // Apply modifications to the model
1919 mImpl->mOperationsPending = ALL_OPERATIONS;
1921 mImpl->RequestRelayout();
1924 // private : Update.
1926 void Controller::InsertText(const std::string& text, Controller::InsertType type)
1928 TextUpdater::InsertText(*this, text, type);
1931 void Controller::PasteText(const std::string& stringToPaste)
1933 TextUpdater::PasteText(*this, stringToPaste);
1936 bool Controller::RemoveText(int cursorOffset,
1937 int numberOfCharacters,
1938 UpdateInputStyleType type)
1940 return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
1943 bool Controller::RemoveSelectedText()
1945 return TextUpdater::RemoveSelectedText(*this);
1948 void Controller::InsertTextAnchor(int numberOfCharacters,
1949 CharacterIndex previousCursorIndex)
1951 TextUpdater::InsertTextAnchor(*this, numberOfCharacters, previousCursorIndex);
1954 void Controller::RemoveTextAnchor(int cursorOffset,
1955 int numberOfCharacters,
1956 CharacterIndex previousCursorIndex)
1958 TextUpdater::RemoveTextAnchor(*this, cursorOffset, numberOfCharacters, previousCursorIndex);
1961 // private : Relayout.
1963 bool Controller::DoRelayout(const Size& size,
1964 OperationsMask operationsRequired,
1967 return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
1970 void Controller::CalculateVerticalOffset(const Size& controlSize)
1972 Relayouter::CalculateVerticalOffset(*this, controlSize);
1975 // private : Events.
1977 void Controller::ProcessModifyEvents()
1979 EventHandler::ProcessModifyEvents(*this);
1982 void Controller::TextReplacedEvent()
1984 EventHandler::TextReplacedEvent(*this);
1987 void Controller::TextInsertedEvent()
1989 EventHandler::TextInsertedEvent(*this);
1992 void Controller::TextDeletedEvent()
1994 EventHandler::TextDeletedEvent(*this);
1997 bool Controller::DeleteEvent(int keyCode)
1999 return EventHandler::DeleteEvent(*this, keyCode);
2002 // private : Helpers.
2004 void Controller::ResetText()
2006 TextUpdater::ResetText(*this);
2009 void Controller::ShowPlaceholderText()
2011 PlaceholderHandler::ShowPlaceholderText(*this);
2014 void Controller::ClearFontData()
2016 if(mImpl->mFontDefaults)
2018 mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
2021 // Set flags to update the model.
2022 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
2023 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
2024 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
2026 mImpl->mTextUpdateInfo.mClearAll = true;
2027 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
2028 mImpl->mRecalculateNaturalSize = true;
2030 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
2036 UPDATE_LAYOUT_SIZE |
2041 void Controller::ClearStyleData()
2043 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
2044 mImpl->mModel->mLogicalModel->ClearFontDescriptionRuns();
2047 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
2049 // Reset the cursor position
2050 if(NULL != mImpl->mEventData)
2052 mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
2054 // Update the cursor if it's in editing mode.
2055 if(EventData::IsEditingState(mImpl->mEventData->mState))
2057 mImpl->mEventData->mUpdateCursorPosition = true;
2062 CharacterIndex Controller::GetCursorPosition()
2064 if(!mImpl->mEventData)
2067 return mImpl->mEventData->mPrimaryCursorPosition;
2070 void Controller::ResetScrollPosition()
2072 if(NULL != mImpl->mEventData)
2074 // Reset the scroll position.
2075 mImpl->mModel->mScrollPosition = Vector2::ZERO;
2076 mImpl->mEventData->mScrollAfterUpdatePosition = true;
2080 void Controller::SetControlInterface(ControlInterface* controlInterface)
2082 mImpl->mControlInterface = controlInterface;
2085 void Controller::SetAnchorControlInterface(AnchorControlInterface* anchorControlInterface)
2087 mImpl->mAnchorControlInterface = anchorControlInterface;
2090 bool Controller::ShouldClearFocusOnEscape() const
2092 return mImpl->mShouldClearFocusOnEscape;
2095 Actor Controller::CreateBackgroundActor()
2097 return mImpl->CreateBackgroundActor();
2100 // private : Private contructors & copy operator.
2102 Controller::Controller()
2103 : Controller(nullptr, nullptr, nullptr, nullptr)
2107 Controller::Controller(ControlInterface* controlInterface)
2108 : Controller(controlInterface, nullptr, nullptr, nullptr)
2112 Controller::Controller(ControlInterface* controlInterface,
2113 EditableControlInterface* editableControlInterface,
2114 SelectableControlInterface* selectableControlInterface,
2115 AnchorControlInterface* anchorControlInterface)
2116 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface, anchorControlInterface))
2120 // The copy constructor and operator are left unimplemented.
2122 // protected : Destructor.
2124 Controller::~Controller()
2131 } // namespace Toolkit