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)
80 return ControllerPtr(new Controller(controlInterface,
81 editableControlInterface,
82 selectableControlInterface));
85 // public : Configure the text controller.
87 void Controller::EnableTextInput(DecoratorPtr decorator, InputMethodContext& inputMethodContext)
91 delete mImpl->mEventData;
92 mImpl->mEventData = NULL;
94 // Nothing else to do.
98 if(NULL == mImpl->mEventData)
100 mImpl->mEventData = new EventData(decorator, inputMethodContext);
104 void Controller::SetGlyphType(TextAbstraction::GlyphType glyphType)
106 // Metrics for bitmap & vector based glyphs are different
107 mImpl->mMetrics->SetGlyphType(glyphType);
109 // Clear the font-specific data
112 mImpl->RequestRelayout();
115 void Controller::SetMarkupProcessorEnabled(bool enable)
117 if(enable != mImpl->mMarkupProcessorEnabled)
119 //If Text was already set, call the SetText again for enabling or disabling markup
120 mImpl->mMarkupProcessorEnabled = enable;
127 bool Controller::IsMarkupProcessorEnabled() const
129 return mImpl->mMarkupProcessorEnabled;
132 void Controller::SetAutoScrollEnabled(bool enable)
134 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);
136 if(mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX)
140 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n");
141 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
150 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
151 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
158 mImpl->mIsAutoScrollEnabled = enable;
159 mImpl->RequestRelayout();
163 DALI_LOG_WARNING("Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n");
164 mImpl->mIsAutoScrollEnabled = false;
168 bool Controller::IsAutoScrollEnabled() const
170 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled ? "true" : "false");
172 return mImpl->mIsAutoScrollEnabled;
175 CharacterDirection Controller::GetAutoScrollDirection() const
177 return mImpl->mIsTextDirectionRTL;
180 float Controller::GetAutoScrollLineAlignment() const
184 if(mImpl->mModel->mVisualModel &&
185 (0u != mImpl->mModel->mVisualModel->mLines.Count()))
187 offset = (*mImpl->mModel->mVisualModel->mLines.Begin()).alignmentOffset;
193 void Controller::SetHorizontalScrollEnabled(bool enable)
195 if((NULL != mImpl->mEventData) &&
196 mImpl->mEventData->mDecorator)
198 mImpl->mEventData->mDecorator->SetHorizontalScrollEnabled(enable);
201 bool Controller::IsHorizontalScrollEnabled() const
203 if((NULL != mImpl->mEventData) &&
204 mImpl->mEventData->mDecorator)
206 return mImpl->mEventData->mDecorator->IsHorizontalScrollEnabled();
212 void Controller::SetVerticalScrollEnabled(bool enable)
214 if((NULL != mImpl->mEventData) &&
215 mImpl->mEventData->mDecorator)
217 if(mImpl->mEventData->mDecorator)
219 mImpl->mEventData->mDecorator->SetVerticalScrollEnabled(enable);
224 bool Controller::IsVerticalScrollEnabled() const
226 if((NULL != mImpl->mEventData) &&
227 mImpl->mEventData->mDecorator)
229 return mImpl->mEventData->mDecorator->IsVerticalScrollEnabled();
235 void Controller::SetSmoothHandlePanEnabled(bool enable)
237 if((NULL != mImpl->mEventData) &&
238 mImpl->mEventData->mDecorator)
240 mImpl->mEventData->mDecorator->SetSmoothHandlePanEnabled(enable);
244 bool Controller::IsSmoothHandlePanEnabled() const
246 if((NULL != mImpl->mEventData) &&
247 mImpl->mEventData->mDecorator)
249 return mImpl->mEventData->mDecorator->IsSmoothHandlePanEnabled();
255 void Controller::SetMaximumNumberOfCharacters(Length maxCharacters)
257 mImpl->mMaximumNumberOfCharacters = maxCharacters;
260 int Controller::GetMaximumNumberOfCharacters()
262 return mImpl->mMaximumNumberOfCharacters;
265 void Controller::SetEnableCursorBlink(bool enable)
267 DALI_ASSERT_DEBUG(NULL != mImpl->mEventData && "TextInput disabled");
269 if(NULL != mImpl->mEventData)
271 mImpl->mEventData->mCursorBlinkEnabled = enable;
274 mImpl->mEventData->mDecorator)
276 mImpl->mEventData->mDecorator->StopCursorBlink();
281 bool Controller::GetEnableCursorBlink() const
283 if(NULL != mImpl->mEventData)
285 return mImpl->mEventData->mCursorBlinkEnabled;
291 void Controller::SetMultiLineEnabled(bool enable)
293 const Layout::Engine::Type layout = enable ? Layout::Engine::MULTI_LINE_BOX : Layout::Engine::SINGLE_LINE_BOX;
295 if(layout != mImpl->mLayoutEngine.GetLayout())
297 // Set the layout type.
298 mImpl->mLayoutEngine.SetLayout(layout);
300 // Set the flags to redo the layout operations
301 const OperationsMask layoutOperations = static_cast<OperationsMask>(LAYOUT |
306 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
307 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | layoutOperations);
309 // Need to recalculate natural size
310 mImpl->mRecalculateNaturalSize = true;
312 mImpl->RequestRelayout();
316 bool Controller::IsMultiLineEnabled() const
318 return Layout::Engine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
321 void Controller::SetHorizontalAlignment(Text::HorizontalAlignment::Type alignment)
323 if(alignment != mImpl->mModel->mHorizontalAlignment)
325 // Set the alignment.
326 mImpl->mModel->mHorizontalAlignment = alignment;
328 // Set the flag to redo the alignment operation.
329 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
331 if(mImpl->mEventData)
333 mImpl->mEventData->mUpdateAlignment = true;
335 // Update the cursor if it's in editing mode
336 if(EventData::IsEditingState(mImpl->mEventData->mState))
338 mImpl->ChangeState(EventData::EDITING);
339 mImpl->mEventData->mUpdateCursorPosition = true;
343 mImpl->RequestRelayout();
347 Text::HorizontalAlignment::Type Controller::GetHorizontalAlignment() const
349 return mImpl->mModel->mHorizontalAlignment;
352 void Controller::SetVerticalAlignment(VerticalAlignment::Type alignment)
354 if(alignment != mImpl->mModel->mVerticalAlignment)
356 // Set the alignment.
357 mImpl->mModel->mVerticalAlignment = alignment;
359 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | ALIGN);
361 mImpl->RequestRelayout();
365 VerticalAlignment::Type Controller::GetVerticalAlignment() const
367 return mImpl->mModel->mVerticalAlignment;
370 bool Controller::IsIgnoreSpacesAfterText() const
372 return mImpl->mModel->mIgnoreSpacesAfterText;
375 void Controller::SetIgnoreSpacesAfterText(bool ignore)
377 mImpl->mModel->mIgnoreSpacesAfterText = ignore;
380 bool Controller::IsMatchSystemLanguageDirection() const
382 return mImpl->mModel->mMatchSystemLanguageDirection;
385 void Controller::SetMatchSystemLanguageDirection(bool match)
387 mImpl->mModel->mMatchSystemLanguageDirection = match;
390 void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
392 mImpl->mLayoutDirection = layoutDirection;
395 bool Controller::IsShowingRealText() const
397 return mImpl->IsShowingRealText();
400 void Controller::SetLineWrapMode(Text::LineWrap::Mode lineWrapMode)
402 if(lineWrapMode != mImpl->mModel->mLineWrapMode)
404 // Set the text wrap mode.
405 mImpl->mModel->mLineWrapMode = lineWrapMode;
407 // Update Text layout for applying wrap mode
408 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
413 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
414 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
415 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
418 mImpl->RequestRelayout();
422 Text::LineWrap::Mode Controller::GetLineWrapMode() const
424 return mImpl->mModel->mLineWrapMode;
427 void Controller::SetTextElideEnabled(bool enabled)
429 mImpl->mModel->mElideEnabled = enabled;
432 bool Controller::IsTextElideEnabled() const
434 return mImpl->mModel->mElideEnabled;
437 void Controller::SetTextFitEnabled(bool enabled)
439 mImpl->mTextFitEnabled = enabled;
442 bool Controller::IsTextFitEnabled() const
444 return mImpl->mTextFitEnabled;
447 void Controller::SetTextFitMinSize(float minSize, FontSizeType type)
453 mImpl->mTextFitMinSize = minSize;
458 mImpl->mTextFitMinSize = ConvertPixelToPint(minSize);
464 float Controller::GetTextFitMinSize() const
466 return mImpl->mTextFitMinSize;
469 void Controller::SetTextFitMaxSize(float maxSize, FontSizeType type)
475 mImpl->mTextFitMaxSize = maxSize;
480 mImpl->mTextFitMaxSize = ConvertPixelToPint(maxSize);
486 float Controller::GetTextFitMaxSize() const
488 return mImpl->mTextFitMaxSize;
491 void Controller::SetTextFitStepSize(float step, FontSizeType type)
497 mImpl->mTextFitStepSize = step;
502 mImpl->mTextFitStepSize = ConvertPixelToPint(step);
508 float Controller::GetTextFitStepSize() const
510 return mImpl->mTextFitStepSize;
513 void Controller::SetTextFitContentSize(Vector2 size)
515 mImpl->mTextFitContentSize = size;
518 Vector2 Controller::GetTextFitContentSize() const
520 return mImpl->mTextFitContentSize;
523 void Controller::SetPlaceholderTextElideEnabled(bool enabled)
525 PlaceholderHandler::SetPlaceholderTextElideEnabled(*this, enabled);
528 bool Controller::IsPlaceholderTextElideEnabled() const
530 return PlaceholderHandler::IsPlaceholderTextElideEnabled(*this);
533 void Controller::SetSelectionEnabled(bool enabled)
535 mImpl->mEventData->mSelectionEnabled = enabled;
538 bool Controller::IsSelectionEnabled() const
540 return mImpl->mEventData->mSelectionEnabled;
543 void Controller::SetShiftSelectionEnabled(bool enabled)
545 mImpl->mEventData->mShiftSelectionFlag = enabled;
548 bool Controller::IsShiftSelectionEnabled() const
550 return mImpl->mEventData->mShiftSelectionFlag;
553 void Controller::SetGrabHandleEnabled(bool enabled)
555 mImpl->mEventData->mGrabHandleEnabled = enabled;
558 bool Controller::IsGrabHandleEnabled() const
560 return mImpl->mEventData->mGrabHandleEnabled;
563 void Controller::SetGrabHandlePopupEnabled(bool enabled)
565 mImpl->mEventData->mGrabHandlePopupEnabled = enabled;
568 bool Controller::IsGrabHandlePopupEnabled() const
570 return mImpl->mEventData->mGrabHandlePopupEnabled;
575 void Controller::SetText(const std::string& text)
577 TextUpdater::SetText(*this, text);
580 void Controller::GetText(std::string& text) const
582 if(!mImpl->IsShowingPlaceholderText())
584 // Retrieves the text string.
585 mImpl->GetText(0u, text);
589 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::GetText %p empty (but showing placeholder)\n", this);
593 void Controller::SetPlaceholderText(PlaceholderType type, const std::string& text)
595 PlaceholderHandler::SetPlaceholderText(*this, type, text);
598 void Controller::GetPlaceholderText(PlaceholderType type, std::string& text) const
600 PlaceholderHandler::GetPlaceholderText(*this, type, text);
603 void Controller::UpdateAfterFontChange(const std::string& newDefaultFont)
605 DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n");
607 if(!mImpl->mFontDefaults->familyDefined) // If user defined font then should not update when system font changes
609 DALI_LOG_INFO(gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str());
610 mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
614 mImpl->RequestRelayout();
618 void Controller::RetrieveSelection(std::string& selectedText) const
620 mImpl->RetrieveSelection(selectedText, false);
623 void Controller::SetSelection(int start, int end)
625 mImpl->SetSelection(start, end);
628 std::pair<int, int> Controller::GetSelectionIndexes() const
630 return mImpl->GetSelectionIndexes();
633 void Controller::CopyStringToClipboard(const std::string& source)
635 mImpl->CopyStringToClipboard(source);
638 void Controller::SendSelectionToClipboard(bool deleteAfterSending)
640 mImpl->SendSelectionToClipboard(deleteAfterSending);
643 // public : Default style & Input style
645 void Controller::SetDefaultFontFamily(const std::string& defaultFontFamily)
647 if(NULL == mImpl->mFontDefaults)
649 mImpl->mFontDefaults = new FontDefaults();
652 mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
653 DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
654 mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
656 if(mImpl->mEventData)
658 // Update the cursor position if it's in editing mode
659 if(EventData::IsEditingState(mImpl->mEventData->mState))
661 mImpl->mEventData->mDecoratorUpdated = true;
662 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font family is updated.
666 // Clear the font-specific data
669 mImpl->RequestRelayout();
672 const std::string& Controller::GetDefaultFontFamily() const
674 if(NULL != mImpl->mFontDefaults)
676 return mImpl->mFontDefaults->mFontDescription.family;
682 void Controller::SetPlaceholderFontFamily(const std::string& placeholderTextFontFamily)
684 PlaceholderHandler::SetPlaceholderFontFamily(*this, placeholderTextFontFamily);
687 const std::string& Controller::GetPlaceholderFontFamily() const
689 return PlaceholderHandler::GetPlaceholderFontFamily(*this);
692 void Controller::SetDefaultFontWeight(FontWeight weight)
694 if(NULL == mImpl->mFontDefaults)
696 mImpl->mFontDefaults = new FontDefaults();
699 mImpl->mFontDefaults->mFontDescription.weight = weight;
700 mImpl->mFontDefaults->weightDefined = true;
702 if(mImpl->mEventData)
704 // Update the cursor position if it's in editing mode
705 if(EventData::IsEditingState(mImpl->mEventData->mState))
707 mImpl->mEventData->mDecoratorUpdated = true;
708 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font weight is updated.
712 // Clear the font-specific data
715 mImpl->RequestRelayout();
718 bool Controller::IsDefaultFontWeightDefined() const
720 if(NULL != mImpl->mFontDefaults)
722 return mImpl->mFontDefaults->weightDefined;
728 FontWeight Controller::GetDefaultFontWeight() const
730 if(NULL != mImpl->mFontDefaults)
732 return mImpl->mFontDefaults->mFontDescription.weight;
735 return TextAbstraction::FontWeight::NORMAL;
738 void Controller::SetPlaceholderTextFontWeight(FontWeight weight)
740 PlaceholderHandler::SetPlaceholderTextFontWeight(*this, weight);
743 bool Controller::IsPlaceholderTextFontWeightDefined() const
745 return PlaceholderHandler::IsPlaceholderTextFontWeightDefined(*this);
749 FontWeight Controller::GetPlaceholderTextFontWeight() const
751 return PlaceholderHandler::GetPlaceholderTextFontWeight(*this);
754 void Controller::SetDefaultFontWidth(FontWidth width)
756 if(NULL == mImpl->mFontDefaults)
758 mImpl->mFontDefaults = new FontDefaults();
761 mImpl->mFontDefaults->mFontDescription.width = width;
762 mImpl->mFontDefaults->widthDefined = true;
764 if(mImpl->mEventData)
766 // Update the cursor position if it's in editing mode
767 if(EventData::IsEditingState(mImpl->mEventData->mState))
769 mImpl->mEventData->mDecoratorUpdated = true;
770 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font width is updated.
774 // Clear the font-specific data
777 mImpl->RequestRelayout();
780 bool Controller::IsDefaultFontWidthDefined() const
782 if(NULL != mImpl->mFontDefaults)
784 return mImpl->mFontDefaults->widthDefined;
790 FontWidth Controller::GetDefaultFontWidth() const
792 if(NULL != mImpl->mFontDefaults)
794 return mImpl->mFontDefaults->mFontDescription.width;
797 return TextAbstraction::FontWidth::NORMAL;
800 void Controller::SetPlaceholderTextFontWidth(FontWidth width)
802 PlaceholderHandler::SetPlaceholderTextFontWidth(*this, width);
805 bool Controller::IsPlaceholderTextFontWidthDefined() const
807 return PlaceholderHandler::IsPlaceholderTextFontWidthDefined(*this);
810 FontWidth Controller::GetPlaceholderTextFontWidth() const
812 return PlaceholderHandler::GetPlaceholderTextFontWidth(*this);
815 void Controller::SetDefaultFontSlant(FontSlant slant)
817 if(NULL == mImpl->mFontDefaults)
819 mImpl->mFontDefaults = new FontDefaults();
822 mImpl->mFontDefaults->mFontDescription.slant = slant;
823 mImpl->mFontDefaults->slantDefined = true;
825 if(mImpl->mEventData)
827 // Update the cursor position if it's in editing mode
828 if(EventData::IsEditingState(mImpl->mEventData->mState))
830 mImpl->mEventData->mDecoratorUpdated = true;
831 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font slant is updated.
835 // Clear the font-specific data
838 mImpl->RequestRelayout();
841 bool Controller::IsDefaultFontSlantDefined() const
843 if(NULL != mImpl->mFontDefaults)
845 return mImpl->mFontDefaults->slantDefined;
850 FontSlant Controller::GetDefaultFontSlant() const
852 if(NULL != mImpl->mFontDefaults)
854 return mImpl->mFontDefaults->mFontDescription.slant;
857 return TextAbstraction::FontSlant::NORMAL;
860 void Controller::SetPlaceholderTextFontSlant(FontSlant slant)
862 PlaceholderHandler::SetPlaceholderTextFontSlant(*this, slant);
865 bool Controller::IsPlaceholderTextFontSlantDefined() const
867 return PlaceholderHandler::IsPlaceholderTextFontSlantDefined(*this);
870 FontSlant Controller::GetPlaceholderTextFontSlant() const
872 return PlaceholderHandler::GetPlaceholderTextFontSlant(*this);
875 void Controller::SetFontSizeScale(float scale)
877 mImpl->mFontSizeScale = scale;
879 if(mImpl->mEventData)
881 // Update the cursor position if it's in editing mode
882 if(EventData::IsEditingState(mImpl->mEventData->mState))
884 mImpl->mEventData->mDecoratorUpdated = true;
885 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
889 // Clear the font-specific data
892 mImpl->RequestRelayout();
895 float Controller::GetFontSizeScale() const
897 if(nullptr != mImpl->mFontDefaults)
899 return mImpl->mFontSizeScale;
905 void Controller::SetDefaultFontSize(float fontSize, FontSizeType type)
907 if(NULL == mImpl->mFontDefaults)
909 mImpl->mFontDefaults = new FontDefaults();
916 mImpl->mFontDefaults->mDefaultPointSize = fontSize;
917 mImpl->mFontDefaults->sizeDefined = true;
922 // Point size = Pixel size * 72.f / DPI
923 unsigned int horizontalDpi = 0u;
924 unsigned int verticalDpi = 0u;
925 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
926 fontClient.GetDpi(horizontalDpi, verticalDpi);
928 mImpl->mFontDefaults->mDefaultPointSize = (fontSize * 72.f) / static_cast<float>(horizontalDpi);
929 mImpl->mFontDefaults->sizeDefined = true;
934 if(mImpl->mEventData)
936 // Update the cursor position if it's in editing mode
937 if(EventData::IsEditingState(mImpl->mEventData->mState))
939 mImpl->mEventData->mDecoratorUpdated = true;
940 mImpl->mEventData->mUpdateCursorPosition = true; // Cursor position should be updated when the font size is updated.
944 // Clear the font-specific data
947 mImpl->RequestRelayout();
950 float Controller::GetDefaultFontSize(FontSizeType type) const
953 if(NULL != mImpl->mFontDefaults)
959 value = mImpl->mFontDefaults->mDefaultPointSize;
964 // Pixel size = Point size * DPI / 72.f
965 unsigned int horizontalDpi = 0u;
966 unsigned int verticalDpi = 0u;
967 TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
968 fontClient.GetDpi(horizontalDpi, verticalDpi);
970 value = mImpl->mFontDefaults->mDefaultPointSize * static_cast<float>(horizontalDpi) / 72.f;
980 void Controller::SetPlaceholderTextFontSize(float fontSize, FontSizeType type)
982 PlaceholderHandler::SetPlaceholderTextFontSize(*this, fontSize, type);
985 float Controller::GetPlaceholderTextFontSize(FontSizeType type) const
987 return PlaceholderHandler::GetPlaceholderTextFontSize(*this, type);
990 void Controller::SetDefaultColor(const Vector4& color)
992 mImpl->mTextColor = color;
994 if(!mImpl->IsShowingPlaceholderText())
996 mImpl->mModel->mVisualModel->SetTextColor(color);
998 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
1000 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1002 mImpl->RequestRelayout();
1006 const Vector4& Controller::GetDefaultColor() const
1008 return mImpl->mTextColor;
1011 void Controller::SetPlaceholderTextColor(const Vector4& textColor)
1013 PlaceholderHandler::SetPlaceholderTextColor(*this, textColor);
1016 const Vector4& Controller::GetPlaceholderTextColor() const
1018 return PlaceholderHandler::GetPlaceholderTextColor(*this);
1021 void Controller::SetShadowOffset(const Vector2& shadowOffset)
1023 mImpl->mModel->mVisualModel->SetShadowOffset(shadowOffset);
1025 mImpl->RequestRelayout();
1028 const Vector2& Controller::GetShadowOffset() const
1030 return mImpl->mModel->mVisualModel->GetShadowOffset();
1033 void Controller::SetShadowColor(const Vector4& shadowColor)
1035 mImpl->mModel->mVisualModel->SetShadowColor(shadowColor);
1037 mImpl->RequestRelayout();
1040 const Vector4& Controller::GetShadowColor() const
1042 return mImpl->mModel->mVisualModel->GetShadowColor();
1045 void Controller::SetShadowBlurRadius(const float& shadowBlurRadius)
1047 if(fabsf(GetShadowBlurRadius() - shadowBlurRadius) > Math::MACHINE_EPSILON_1)
1049 mImpl->mModel->mVisualModel->SetShadowBlurRadius(shadowBlurRadius);
1051 mImpl->RequestRelayout();
1055 const float& Controller::GetShadowBlurRadius() const
1057 return mImpl->mModel->mVisualModel->GetShadowBlurRadius();
1060 void Controller::SetUnderlineColor(const Vector4& color)
1062 mImpl->mModel->mVisualModel->SetUnderlineColor(color);
1064 mImpl->RequestRelayout();
1067 const Vector4& Controller::GetUnderlineColor() const
1069 return mImpl->mModel->mVisualModel->GetUnderlineColor();
1072 void Controller::SetUnderlineEnabled(bool enabled)
1074 mImpl->mModel->mVisualModel->SetUnderlineEnabled(enabled);
1076 mImpl->RequestRelayout();
1079 bool Controller::IsUnderlineEnabled() const
1081 return mImpl->mModel->mVisualModel->IsUnderlineEnabled();
1084 void Controller::SetUnderlineHeight(float height)
1086 mImpl->mModel->mVisualModel->SetUnderlineHeight(height);
1088 mImpl->RequestRelayout();
1091 float Controller::GetUnderlineHeight() const
1093 return mImpl->mModel->mVisualModel->GetUnderlineHeight();
1096 void Controller::SetOutlineColor(const Vector4& color)
1098 mImpl->mModel->mVisualModel->SetOutlineColor(color);
1100 mImpl->RequestRelayout();
1103 const Vector4& Controller::GetOutlineColor() const
1105 return mImpl->mModel->mVisualModel->GetOutlineColor();
1108 void Controller::SetOutlineWidth(uint16_t width)
1110 mImpl->mModel->mVisualModel->SetOutlineWidth(width);
1112 mImpl->RequestRelayout();
1115 uint16_t Controller::GetOutlineWidth() const
1117 return mImpl->mModel->mVisualModel->GetOutlineWidth();
1120 void Controller::SetBackgroundColor(const Vector4& color)
1122 mImpl->mModel->mVisualModel->SetBackgroundColor(color);
1124 mImpl->RequestRelayout();
1127 const Vector4& Controller::GetBackgroundColor() const
1129 return mImpl->mModel->mVisualModel->GetBackgroundColor();
1132 void Controller::SetBackgroundEnabled(bool enabled)
1134 mImpl->mModel->mVisualModel->SetBackgroundEnabled(enabled);
1136 mImpl->RequestRelayout();
1139 bool Controller::IsBackgroundEnabled() const
1141 return mImpl->mModel->mVisualModel->IsBackgroundEnabled();
1144 void Controller::SetDefaultEmbossProperties(const std::string& embossProperties)
1146 if(NULL == mImpl->mEmbossDefaults)
1148 mImpl->mEmbossDefaults = new EmbossDefaults();
1151 mImpl->mEmbossDefaults->properties = embossProperties;
1154 const std::string& Controller::GetDefaultEmbossProperties() const
1156 if(NULL != mImpl->mEmbossDefaults)
1158 return mImpl->mEmbossDefaults->properties;
1161 return EMPTY_STRING;
1164 void Controller::SetDefaultOutlineProperties(const std::string& outlineProperties)
1166 if(NULL == mImpl->mOutlineDefaults)
1168 mImpl->mOutlineDefaults = new OutlineDefaults();
1171 mImpl->mOutlineDefaults->properties = outlineProperties;
1174 const std::string& Controller::GetDefaultOutlineProperties() const
1176 if(NULL != mImpl->mOutlineDefaults)
1178 return mImpl->mOutlineDefaults->properties;
1181 return EMPTY_STRING;
1184 bool Controller::SetDefaultLineSpacing(float lineSpacing)
1186 if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
1188 mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
1189 mImpl->mRecalculateNaturalSize = true;
1195 float Controller::GetDefaultLineSpacing() const
1197 return mImpl->mLayoutEngine.GetDefaultLineSpacing();
1200 bool Controller::SetDefaultLineSize(float lineSize)
1202 if(std::fabs(lineSize - mImpl->mLayoutEngine.GetDefaultLineSize()) > Math::MACHINE_EPSILON_1000)
1204 mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
1205 mImpl->mRecalculateNaturalSize = true;
1211 float Controller::GetDefaultLineSize() const
1213 return mImpl->mLayoutEngine.GetDefaultLineSize();
1216 void Controller::SetInputColor(const Vector4& color)
1218 if(NULL != mImpl->mEventData)
1220 mImpl->mEventData->mInputStyle.textColor = color;
1221 mImpl->mEventData->mInputStyle.isDefaultColor = false;
1223 if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState)
1225 const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
1227 // Get start and end position of selection
1228 const CharacterIndex startOfSelectedText = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
1229 const Length lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
1231 // Add the color run.
1232 const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
1233 mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
1235 ColorRun& colorRun = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
1236 colorRun.color = color;
1237 colorRun.characterRun.characterIndex = startOfSelectedText;
1238 colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
1240 // Request to relayout.
1241 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
1242 mImpl->RequestRelayout();
1244 mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
1245 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
1246 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText;
1251 const Vector4& Controller::GetInputColor() const
1253 if(NULL != mImpl->mEventData)
1255 return mImpl->mEventData->mInputStyle.textColor;
1258 // Return the default text's color if there is no EventData.
1259 return mImpl->mTextColor;
1262 void Controller::SetInputFontFamily(const std::string& fontFamily)
1264 InputFontHandler::SetInputFontFamily(*this, fontFamily);
1267 const std::string& Controller::GetInputFontFamily() const
1269 return InputFontHandler::GetInputFontFamily(*this);
1272 void Controller::SetInputFontWeight(FontWeight weight)
1274 InputFontHandler::SetInputFontWeight(*this, weight);
1277 bool Controller::IsInputFontWeightDefined() const
1279 return InputFontHandler::IsInputFontWeightDefined(*this);
1282 FontWeight Controller::GetInputFontWeight() const
1284 return InputFontHandler::GetInputFontWeight(*this);
1287 void Controller::SetInputFontWidth(FontWidth width)
1289 InputFontHandler::SetInputFontWidth(*this, width);
1292 bool Controller::IsInputFontWidthDefined() const
1294 return InputFontHandler::IsInputFontWidthDefined(*this);
1297 FontWidth Controller::GetInputFontWidth() const
1299 return InputFontHandler::GetInputFontWidth(*this);
1302 void Controller::SetInputFontSlant(FontSlant slant)
1304 InputFontHandler::SetInputFontSlant(*this, slant);
1307 bool Controller::IsInputFontSlantDefined() const
1309 return InputFontHandler::IsInputFontSlantDefined(*this);
1312 FontSlant Controller::GetInputFontSlant() const
1314 return InputFontHandler::GetInputFontSlant(*this);
1317 void Controller::SetInputFontPointSize(float size)
1319 InputFontHandler::SetInputFontPointSize(*this, size);
1322 float Controller::GetInputFontPointSize() const
1324 return InputFontHandler::GetInputFontPointSize(*this);
1327 void Controller::SetInputLineSpacing(float lineSpacing)
1329 if(NULL != mImpl->mEventData)
1331 mImpl->mEventData->mInputStyle.lineSpacing = lineSpacing;
1332 mImpl->mEventData->mInputStyle.isLineSpacingDefined = true;
1336 float Controller::GetInputLineSpacing() const
1338 if(NULL != mImpl->mEventData)
1340 return mImpl->mEventData->mInputStyle.lineSpacing;
1346 void Controller::SetInputShadowProperties(const std::string& shadowProperties)
1348 if(NULL != mImpl->mEventData)
1350 mImpl->mEventData->mInputStyle.shadowProperties = shadowProperties;
1354 const std::string& Controller::GetInputShadowProperties() const
1356 if(NULL != mImpl->mEventData)
1358 return mImpl->mEventData->mInputStyle.shadowProperties;
1361 return EMPTY_STRING;
1364 void Controller::SetInputUnderlineProperties(const std::string& underlineProperties)
1366 if(NULL != mImpl->mEventData)
1368 mImpl->mEventData->mInputStyle.underlineProperties = underlineProperties;
1372 const std::string& Controller::GetInputUnderlineProperties() const
1374 if(NULL != mImpl->mEventData)
1376 return mImpl->mEventData->mInputStyle.underlineProperties;
1379 return EMPTY_STRING;
1382 void Controller::SetInputEmbossProperties(const std::string& embossProperties)
1384 if(NULL != mImpl->mEventData)
1386 mImpl->mEventData->mInputStyle.embossProperties = embossProperties;
1390 const std::string& Controller::GetInputEmbossProperties() const
1392 if(NULL != mImpl->mEventData)
1394 return mImpl->mEventData->mInputStyle.embossProperties;
1397 return GetDefaultEmbossProperties();
1400 void Controller::SetInputOutlineProperties(const std::string& outlineProperties)
1402 if(NULL != mImpl->mEventData)
1404 mImpl->mEventData->mInputStyle.outlineProperties = outlineProperties;
1408 const std::string& Controller::GetInputOutlineProperties() const
1410 if(NULL != mImpl->mEventData)
1412 return mImpl->mEventData->mInputStyle.outlineProperties;
1415 return GetDefaultOutlineProperties();
1418 void Controller::SetInputModePassword(bool passwordInput)
1420 if(NULL != mImpl->mEventData)
1422 mImpl->mEventData->mPasswordInput = passwordInput;
1426 bool Controller::IsInputModePassword()
1428 if(NULL != mImpl->mEventData)
1430 return mImpl->mEventData->mPasswordInput;
1435 void Controller::SetNoTextDoubleTapAction(NoTextTap::Action action)
1437 if(NULL != mImpl->mEventData)
1439 mImpl->mEventData->mDoubleTapAction = action;
1443 Controller::NoTextTap::Action Controller::GetNoTextDoubleTapAction() const
1445 NoTextTap::Action action = NoTextTap::NO_ACTION;
1447 if(NULL != mImpl->mEventData)
1449 action = mImpl->mEventData->mDoubleTapAction;
1455 void Controller::SetNoTextLongPressAction(NoTextTap::Action action)
1457 if(NULL != mImpl->mEventData)
1459 mImpl->mEventData->mLongPressAction = action;
1463 Controller::NoTextTap::Action Controller::GetNoTextLongPressAction() const
1465 NoTextTap::Action action = NoTextTap::NO_ACTION;
1467 if(NULL != mImpl->mEventData)
1469 action = mImpl->mEventData->mLongPressAction;
1475 bool Controller::IsUnderlineSetByString()
1477 return mImpl->mUnderlineSetByString;
1480 void Controller::UnderlineSetByString(bool setByString)
1482 mImpl->mUnderlineSetByString = setByString;
1485 bool Controller::IsShadowSetByString()
1487 return mImpl->mShadowSetByString;
1490 void Controller::ShadowSetByString(bool setByString)
1492 mImpl->mShadowSetByString = setByString;
1495 bool Controller::IsOutlineSetByString()
1497 return mImpl->mOutlineSetByString;
1500 void Controller::OutlineSetByString(bool setByString)
1502 mImpl->mOutlineSetByString = setByString;
1505 bool Controller::IsFontStyleSetByString()
1507 return mImpl->mFontStyleSetByString;
1510 void Controller::FontStyleSetByString(bool setByString)
1512 mImpl->mFontStyleSetByString = setByString;
1515 // public : Queries & retrieves.
1517 Layout::Engine& Controller::GetLayoutEngine()
1519 return mImpl->mLayoutEngine;
1522 View& Controller::GetView()
1524 return mImpl->mView;
1527 Vector3 Controller::GetNaturalSize()
1529 return Relayouter::GetNaturalSize(*this);
1532 bool Controller::CheckForTextFit(float pointSize, Size& layoutSize)
1534 return Relayouter::CheckForTextFit(*this, pointSize, layoutSize);
1537 void Controller::FitPointSizeforLayout(Size layoutSize)
1539 Relayouter::FitPointSizeforLayout(*this, layoutSize);
1542 float Controller::GetHeightForWidth(float width)
1544 return Relayouter::GetHeightForWidth(*this, width);
1547 int Controller::GetLineCount(float width)
1549 GetHeightForWidth(width);
1550 int numberofLines = mImpl->mModel->GetNumberOfLines();
1551 return numberofLines;
1554 const ModelInterface* const Controller::GetTextModel() const
1556 return mImpl->mModel.Get();
1559 float Controller::GetScrollAmountByUserInput()
1561 float scrollAmount = 0.0f;
1563 if(NULL != mImpl->mEventData && mImpl->mEventData->mCheckScrollAmount)
1565 scrollAmount = mImpl->mModel->mScrollPosition.y - mImpl->mModel->mScrollPositionLast.y;
1566 mImpl->mEventData->mCheckScrollAmount = false;
1568 return scrollAmount;
1571 bool Controller::GetTextScrollInfo(float& scrollPosition, float& controlHeight, float& layoutHeight)
1573 const Vector2& layout = mImpl->mModel->mVisualModel->GetLayoutSize();
1576 controlHeight = mImpl->mModel->mVisualModel->mControlSize.height;
1577 layoutHeight = layout.height;
1578 scrollPosition = mImpl->mModel->mScrollPosition.y;
1579 isScrolled = !Equals(mImpl->mModel->mScrollPosition.y, mImpl->mModel->mScrollPositionLast.y, Math::MACHINE_EPSILON_1);
1583 void Controller::SetHiddenInputOption(const Property::Map& options)
1585 if(NULL == mImpl->mHiddenInput)
1587 mImpl->mHiddenInput = new HiddenText(this);
1589 mImpl->mHiddenInput->SetProperties(options);
1592 void Controller::GetHiddenInputOption(Property::Map& options)
1594 if(NULL != mImpl->mHiddenInput)
1596 mImpl->mHiddenInput->GetProperties(options);
1600 void Controller::SetPlaceholderProperty(const Property::Map& map)
1602 PlaceholderHandler::SetPlaceholderProperty(*this, map);
1605 void Controller::GetPlaceholderProperty(Property::Map& map)
1607 PlaceholderHandler::GetPlaceholderProperty(*this, map);
1610 Toolkit::DevelText::TextDirection::Type Controller::GetTextDirection()
1612 // Make sure the model is up-to-date before layouting
1613 ProcessModifyEvents();
1615 if(mImpl->mUpdateTextDirection)
1617 // Operations that can be done only once until the text changes.
1618 const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
1626 // Set the update info to relayout the whole text.
1627 mImpl->mTextUpdateInfo.mParagraphCharacterIndex = 0u;
1628 mImpl->mTextUpdateInfo.mRequestedNumberOfCharacters = mImpl->mModel->mLogicalModel->mText.Count();
1630 // Make sure the model is up-to-date before layouting
1631 mImpl->UpdateModel(onlyOnceOperations);
1633 Vector3 naturalSize;
1634 DoRelayout(Size(MAX_FLOAT, MAX_FLOAT),
1635 static_cast<OperationsMask>(onlyOnceOperations |
1636 LAYOUT | REORDER | UPDATE_DIRECTION),
1637 naturalSize.GetVectorXY());
1639 // Do not do again the only once operations.
1640 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending & ~onlyOnceOperations);
1642 // Clear the update info. This info will be set the next time the text is updated.
1643 mImpl->mTextUpdateInfo.Clear();
1645 // FullRelayoutNeeded should be true because DoRelayout is MAX_FLOAT, MAX_FLOAT.
1646 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
1648 mImpl->mUpdateTextDirection = false;
1651 return mImpl->mIsTextDirectionRTL ? Toolkit::DevelText::TextDirection::RIGHT_TO_LEFT : Toolkit::DevelText::TextDirection::LEFT_TO_RIGHT;
1654 Toolkit::DevelText::VerticalLineAlignment::Type Controller::GetVerticalLineAlignment() const
1656 return mImpl->mModel->GetVerticalLineAlignment();
1659 void Controller::SetVerticalLineAlignment(Toolkit::DevelText::VerticalLineAlignment::Type alignment)
1661 mImpl->mModel->mVerticalLineAlignment = alignment;
1664 // public : Relayout.
1666 Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
1668 return Relayouter::Relayout(*this, size, layoutDirection);
1671 void Controller::RequestRelayout()
1673 mImpl->RequestRelayout();
1676 // public : Input style change signals.
1678 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
1680 return (NULL == mImpl->mEventData) || (0u == mImpl->mEventData->mInputStyleChangedQueue.Count());
1683 void Controller::ProcessInputStyleChangedSignals()
1685 if(NULL == mImpl->mEventData)
1691 for(Vector<InputStyle::Mask>::ConstIterator it = mImpl->mEventData->mInputStyleChangedQueue.Begin(),
1692 endIt = mImpl->mEventData->mInputStyleChangedQueue.End();
1696 const InputStyle::Mask mask = *it;
1698 if(NULL != mImpl->mEditableControlInterface)
1700 // Emit the input style changed signal.
1701 mImpl->mEditableControlInterface->InputStyleChanged(mask);
1705 mImpl->mEventData->mInputStyleChangedQueue.Clear();
1708 // public : Text-input Event Queuing.
1710 void Controller::KeyboardFocusGainEvent()
1712 EventHandler::KeyboardFocusGainEvent(*this);
1715 void Controller::KeyboardFocusLostEvent()
1717 EventHandler::KeyboardFocusLostEvent(*this);
1720 bool Controller::KeyEvent(const Dali::KeyEvent& keyEvent)
1722 return EventHandler::KeyEvent(*this, keyEvent);
1725 void Controller::TapEvent(unsigned int tapCount, float x, float y)
1727 EventHandler::TapEvent(*this, tapCount, x, y);
1730 void Controller::PanEvent(GestureState state, const Vector2& displacement)
1732 EventHandler::PanEvent(*this, state, displacement);
1735 void Controller::LongPressEvent(GestureState state, float x, float y)
1737 EventHandler::LongPressEvent(*this, state, x, y);
1740 void Controller::SelectEvent(float x, float y, SelectionType selectType)
1742 EventHandler::SelectEvent(*this, x, y, selectType);
1745 void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1747 if(mImpl->mEventData)
1749 mImpl->mEventData->mCheckScrollAmount = true;
1750 mImpl->mEventData->mIsLeftHandleSelected = true;
1751 mImpl->mEventData->mIsRightHandleSelected = true;
1752 mImpl->SetTextSelectionRange(start, end);
1753 mImpl->RequestRelayout();
1754 KeyboardFocusGainEvent();
1758 Uint32Pair Controller::GetTextSelectionRange() const
1760 return mImpl->GetTextSelectionRange();
1763 CharacterIndex Controller::GetPrimaryCursorPosition() const
1765 return mImpl->GetPrimaryCursorPosition();
1768 bool Controller::SetPrimaryCursorPosition(CharacterIndex index)
1770 if(mImpl->mEventData)
1772 mImpl->mEventData->mCheckScrollAmount = true;
1773 mImpl->mEventData->mIsLeftHandleSelected = true;
1774 mImpl->mEventData->mIsRightHandleSelected = true;
1775 mImpl->mEventData->mCheckScrollAmount = true;
1776 if(mImpl->SetPrimaryCursorPosition(index))
1778 KeyboardFocusGainEvent();
1785 void Controller::SelectWholeText()
1787 SelectEvent(0.f, 0.f, SelectionType::ALL);
1790 void Controller::SelectNone()
1792 SelectEvent(0.f, 0.f, SelectionType::NONE);
1795 string Controller::GetSelectedText() const
1798 if(EventData::SELECTING == mImpl->mEventData->mState)
1800 mImpl->RetrieveSelection(text, false);
1805 InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1807 return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);
1810 void Controller::PasteClipboardItemEvent()
1812 EventHandler::PasteClipboardItemEvent(*this);
1815 // protected : Inherit from Text::Decorator::ControllerInterface.
1817 void Controller::GetTargetSize(Vector2& targetSize)
1819 targetSize = mImpl->mModel->mVisualModel->mControlSize;
1822 void Controller::AddDecoration(Actor& actor, bool needsClipping)
1824 if(NULL != mImpl->mEditableControlInterface)
1826 mImpl->mEditableControlInterface->AddDecoration(actor, needsClipping);
1830 bool Controller::IsEditable() const
1832 return mImpl->IsEditable();
1835 void Controller::SetEditable(bool editable)
1837 mImpl->SetEditable(editable);
1838 if(mImpl->mEventData && mImpl->mEventData->mDecorator)
1840 mImpl->mEventData->mDecorator->SetEditable(editable);
1844 void Controller::ScrollBy(Vector2 scroll)
1846 if(mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0))
1848 const Vector2& layoutSize = mImpl->mModel->mVisualModel->GetLayoutSize();
1849 const Vector2 currentScroll = mImpl->mModel->mScrollPosition;
1851 scroll.x = -scroll.x;
1852 scroll.y = -scroll.y;
1854 if(fabs(scroll.x) > Math::MACHINE_EPSILON_0)
1856 mImpl->mModel->mScrollPosition.x += scroll.x;
1857 mImpl->ClampHorizontalScroll(layoutSize);
1860 if(fabs(scroll.y) > Math::MACHINE_EPSILON_0)
1862 mImpl->mModel->mScrollPosition.y += scroll.y;
1863 mImpl->ClampVerticalScroll(layoutSize);
1866 if(mImpl->mModel->mScrollPosition != currentScroll)
1868 mImpl->mEventData->mDecorator->UpdatePositions(mImpl->mModel->mScrollPosition - currentScroll);
1869 mImpl->RequestRelayout();
1874 float Controller::GetHorizontalScrollPosition()
1876 if(mImpl->mEventData)
1878 //scroll values are negative internally so we convert them to positive numbers
1879 return -mImpl->mModel->mScrollPosition.x;
1884 float Controller::GetVerticalScrollPosition()
1886 if(mImpl->mEventData)
1888 //scroll values are negative internally so we convert them to positive numbers
1889 return -mImpl->mModel->mScrollPosition.y;
1894 void Controller::DecorationEvent(HandleType handleType, HandleState state, float x, float y)
1896 EventHandler::DecorationEvent(*this, handleType, state, x, y);
1899 // protected : Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
1901 void Controller::TextPopupButtonTouched(Dali::Toolkit::TextSelectionPopup::Buttons button)
1903 EventHandler::TextPopupButtonTouched(*this, button);
1906 void Controller::DisplayTimeExpired()
1908 mImpl->mEventData->mUpdateCursorPosition = true;
1909 // Apply modifications to the model
1910 mImpl->mOperationsPending = ALL_OPERATIONS;
1912 mImpl->RequestRelayout();
1915 // private : Update.
1917 void Controller::InsertText(const std::string& text, Controller::InsertType type)
1919 TextUpdater::InsertText(*this, text, type);
1922 void Controller::PasteText(const std::string& stringToPaste)
1924 TextUpdater::PasteText(*this, stringToPaste);
1927 bool Controller::RemoveText(int cursorOffset,
1928 int numberOfCharacters,
1929 UpdateInputStyleType type)
1931 return TextUpdater::RemoveText(*this, cursorOffset, numberOfCharacters, type);
1934 bool Controller::RemoveSelectedText()
1936 return TextUpdater::RemoveSelectedText(*this);
1939 // private : Relayout.
1941 bool Controller::DoRelayout(const Size& size,
1942 OperationsMask operationsRequired,
1945 return Relayouter::DoRelayout(*this, size, operationsRequired, layoutSize);
1948 void Controller::CalculateVerticalOffset(const Size& controlSize)
1950 Relayouter::CalculateVerticalOffset(*this, controlSize);
1953 // private : Events.
1955 void Controller::ProcessModifyEvents()
1957 EventHandler::ProcessModifyEvents(*this);
1960 void Controller::TextReplacedEvent()
1962 EventHandler::TextReplacedEvent(*this);
1965 void Controller::TextInsertedEvent()
1967 EventHandler::TextInsertedEvent(*this);
1970 void Controller::TextDeletedEvent()
1972 EventHandler::TextDeletedEvent(*this);
1975 bool Controller::DeleteEvent(int keyCode)
1977 return EventHandler::DeleteEvent(*this, keyCode);
1980 // private : Helpers.
1982 void Controller::ResetText()
1984 TextUpdater::ResetText(*this);
1987 void Controller::ShowPlaceholderText()
1989 PlaceholderHandler::ShowPlaceholderText(*this);
1992 void Controller::ClearFontData()
1994 if(mImpl->mFontDefaults)
1996 mImpl->mFontDefaults->mFontId = 0u; // Remove old font ID
1999 // Set flags to update the model.
2000 mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
2001 mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
2002 mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
2004 mImpl->mTextUpdateInfo.mClearAll = true;
2005 mImpl->mTextUpdateInfo.mFullRelayoutNeeded = true;
2006 mImpl->mRecalculateNaturalSize = true;
2008 mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
2014 UPDATE_LAYOUT_SIZE |
2019 void Controller::ClearStyleData()
2021 mImpl->mModel->mLogicalModel->mColorRuns.Clear();
2022 mImpl->mModel->mLogicalModel->ClearFontDescriptionRuns();
2025 void Controller::ResetCursorPosition(CharacterIndex cursorIndex)
2027 // Reset the cursor position
2028 if(NULL != mImpl->mEventData)
2030 mImpl->mEventData->mPrimaryCursorPosition = cursorIndex;
2032 // Update the cursor if it's in editing mode.
2033 if(EventData::IsEditingState(mImpl->mEventData->mState))
2035 mImpl->mEventData->mUpdateCursorPosition = true;
2040 CharacterIndex Controller::GetCursorPosition()
2042 if(!mImpl->mEventData)
2045 return mImpl->mEventData->mPrimaryCursorPosition;
2048 void Controller::ResetScrollPosition()
2050 if(NULL != mImpl->mEventData)
2052 // Reset the scroll position.
2053 mImpl->mModel->mScrollPosition = Vector2::ZERO;
2054 mImpl->mEventData->mScrollAfterUpdatePosition = true;
2058 void Controller::SetControlInterface(ControlInterface* controlInterface)
2060 mImpl->mControlInterface = controlInterface;
2063 bool Controller::ShouldClearFocusOnEscape() const
2065 return mImpl->mShouldClearFocusOnEscape;
2068 Actor Controller::CreateBackgroundActor()
2070 return mImpl->CreateBackgroundActor();
2073 // private : Private contructors & copy operator.
2075 Controller::Controller()
2076 : Controller(nullptr, nullptr, nullptr)
2080 Controller::Controller(ControlInterface* controlInterface)
2081 : Controller(controlInterface, nullptr, nullptr)
2085 Controller::Controller(ControlInterface* controlInterface,
2086 EditableControlInterface* editableControlInterface,
2087 SelectableControlInterface* selectableControlInterface)
2088 : mImpl(new Controller::Impl(controlInterface, editableControlInterface, selectableControlInterface))
2092 // The copy constructor and operator are left unimplemented.
2094 // protected : Destructor.
2096 Controller::~Controller()
2103 } // namespace Toolkit