#include <dali-toolkit/internal/text/text-controller.h>
// EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
#include <dali/integration-api/debug.h>
#include <memory.h>
#include <cmath>
#include <limits>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/text/text-enumerations-devel.h>
#include <dali-toolkit/internal/text/text-controller-event-handler.h>
#include <dali-toolkit/internal/text/text-controller-impl.h>
#include <dali-toolkit/internal/text/text-controller-input-font-handler.h>
GetText(text);
SetText(text);
}
+
+ mImpl->mModel->mVisualModel->SetMarkupProcessorEnabled(enable);
}
bool Controller::IsMarkupProcessorEnabled() const
return mImpl->mMarkupProcessorEnabled;
}
+bool Controller::HasAnchors() const
+{
+ return (mImpl->mMarkupProcessorEnabled && mImpl->mModel->mLogicalModel->mAnchors.Count() && mImpl->IsShowingRealText());
+}
+
void Controller::SetAutoScrollEnabled(bool enable)
{
DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable) ? "true" : "false", (mImpl->mLayoutEngine.GetLayout() == Layout::Engine::SINGLE_LINE_BOX) ? "true" : "false", this);
mImpl->mModel->mIgnoreSpacesAfterText = ignore;
}
-bool Controller::IsMatchSystemLanguageDirection() const
+void Controller::ChangedLayoutDirection()
+{
+ mImpl->mIsLayoutDirectionChanged = true;
+}
+
+void Controller::SetMatchLayoutDirection(DevelText::MatchLayoutDirection type)
{
- return mImpl->mModel->mMatchSystemLanguageDirection;
+ mImpl->mModel->mMatchLayoutDirection = type;
}
-void Controller::SetMatchSystemLanguageDirection(bool match)
+DevelText::MatchLayoutDirection Controller::GetMatchLayoutDirection() const
{
- mImpl->mModel->mMatchSystemLanguageDirection = match;
+ return mImpl->mModel->mMatchLayoutDirection;
}
void Controller::SetLayoutDirection(Dali::LayoutDirection::Type layoutDirection)
mImpl->mLayoutDirection = layoutDirection;
}
+Dali::LayoutDirection::Type Controller::GetLayoutDirection(Dali::Actor& actor) const
+{
+ if(mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::LOCALE ||
+ (mImpl->mModel->mMatchLayoutDirection == DevelText::MatchLayoutDirection::INHERIT && !mImpl->mIsLayoutDirectionChanged))
+ {
+ return static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(actor).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+ }
+ else
+ {
+ return static_cast<Dali::LayoutDirection::Type>(actor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+ }
+}
+
bool Controller::IsShowingRealText() const
{
return mImpl->IsShowingRealText();
{
if(lineWrapMode != mImpl->mModel->mLineWrapMode)
{
- // Set the text wrap mode.
- mImpl->mModel->mLineWrapMode = lineWrapMode;
-
// Update Text layout for applying wrap mode
- mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
+ mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending |
ALIGN |
LAYOUT |
UPDATE_LAYOUT_SIZE |
REORDER);
+
+ if((mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::HYPHENATION) ||
+ (mImpl->mModel->mLineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED) || (lineWrapMode == (Text::LineWrap::Mode)DevelText::LineWrap::MIXED)) // hyphen is treated as line break
+ {
+ mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | GET_LINE_BREAKS);
+ }
+
+ // Set the text wrap mode.
+ mImpl->mModel->mLineWrapMode = lineWrapMode;
+
mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
void Controller::SetTextElideEnabled(bool enabled)
{
mImpl->mModel->mElideEnabled = enabled;
+ mImpl->mModel->mVisualModel->SetTextElideEnabled(enabled);
}
bool Controller::IsTextElideEnabled() const
return EMPTY_STRING;
}
+void Controller::RelayoutForNewLineSize()
+{
+ // relayout all characters
+ mImpl->mTextUpdateInfo.mCharacterIndex = 0;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
+ mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | LAYOUT);
+
+ //remove selection
+ if((mImpl->mEventData != nullptr) && (mImpl->mEventData->mState == EventData::SELECTING))
+ {
+ mImpl->ChangeState(EventData::EDITING);
+ }
+
+ mImpl->RequestRelayout();
+}
+
bool Controller::SetDefaultLineSpacing(float lineSpacing)
{
if(std::fabs(lineSpacing - mImpl->mLayoutEngine.GetDefaultLineSpacing()) > Math::MACHINE_EPSILON_1000)
{
mImpl->mLayoutEngine.SetDefaultLineSpacing(lineSpacing);
mImpl->mRecalculateNaturalSize = true;
+
+ RelayoutForNewLineSize();
return true;
}
return false;
{
mImpl->mLayoutEngine.SetDefaultLineSize(lineSize);
mImpl->mRecalculateNaturalSize = true;
+
+ RelayoutForNewLineSize();
return true;
}
return false;
if(EventData::SELECTING == mImpl->mEventData->mState || EventData::EDITING == mImpl->mEventData->mState || EventData::INACTIVE == mImpl->mEventData->mState)
{
- const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
+ if(EventData::SELECTING == mImpl->mEventData->mState)
+ {
+ const bool handlesCrossed = mImpl->mEventData->mLeftSelectionPosition > mImpl->mEventData->mRightSelectionPosition;
- // Get start and end position of selection
- const CharacterIndex startOfSelectedText = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
- const Length lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
+ // Get start and end position of selection
+ const CharacterIndex startOfSelectedText = handlesCrossed ? mImpl->mEventData->mRightSelectionPosition : mImpl->mEventData->mLeftSelectionPosition;
+ const Length lengthOfSelectedText = (handlesCrossed ? mImpl->mEventData->mLeftSelectionPosition : mImpl->mEventData->mRightSelectionPosition) - startOfSelectedText;
- // Add the color run.
- const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
- mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
+ // Add the color run.
+ const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
+ mImpl->mModel->mLogicalModel->mColorRuns.Resize(numberOfRuns + 1u);
- ColorRun& colorRun = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
- colorRun.color = color;
- colorRun.characterRun.characterIndex = startOfSelectedText;
- colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
+ ColorRun& colorRun = *(mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns);
+ colorRun.color = color;
+ colorRun.characterRun.characterIndex = startOfSelectedText;
+ colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
+
+ mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText;
+ }
+ else
+ {
+ mImpl->mTextUpdateInfo.mCharacterIndex = 0;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = mImpl->mModel->mLogicalModel->mText.Count();
+ }
// Request to relayout.
mImpl->mOperationsPending = static_cast<OperationsMask>(mImpl->mOperationsPending | COLOR);
mImpl->RequestRelayout();
-
- mImpl->mTextUpdateInfo.mCharacterIndex = startOfSelectedText;
- mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = lengthOfSelectedText;
- mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = lengthOfSelectedText;
}
}
}
}
}
+void Controller::SetInputFilterOption(const Property::Map& options)
+{
+ if(!mImpl->mInputFilter)
+ {
+ mImpl->mInputFilter = std::unique_ptr<InputFilter>(new InputFilter());
+ }
+ mImpl->mInputFilter->SetProperties(options);
+}
+
+void Controller::GetInputFilterOption(Property::Map& options)
+{
+ if(NULL != mImpl->mInputFilter)
+ {
+ mImpl->mInputFilter->GetProperties(options);
+ }
+}
+
void Controller::SetPlaceholderProperty(const Property::Map& map)
{
PlaceholderHandler::SetPlaceholderProperty(*this, map);
mImpl->mModel->mVerticalLineAlignment = alignment;
}
+Toolkit::DevelText::EllipsisPosition::Type Controller::GetEllipsisPosition() const
+{
+ return mImpl->mModel->GetEllipsisPosition();
+}
+
+void Controller::SetEllipsisPosition(Toolkit::DevelText::EllipsisPosition::Type ellipsisPosition)
+{
+ mImpl->mModel->mEllipsisPosition = ellipsisPosition;
+ mImpl->mModel->mVisualModel->SetEllipsisPosition(ellipsisPosition);
+}
+
// public : Relayout.
Controller::UpdateTextType Controller::Relayout(const Size& size, Dali::LayoutDirection::Type layoutDirection)
EventHandler::SelectEvent(*this, x, y, selectType);
}
+void Controller::SelectEvent(const uint32_t start, const uint32_t end, SelectionType selectType)
+{
+ EventHandler::SelectEvent(*this, start, end, selectType);
+}
+
void Controller::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
{
if(mImpl->mEventData)
return mImpl->GetPrimaryCursorPosition();
}
-bool Controller::SetPrimaryCursorPosition(CharacterIndex index)
+bool Controller::SetPrimaryCursorPosition(CharacterIndex index, bool focused)
{
if(mImpl->mEventData)
{
mImpl->mEventData->mIsLeftHandleSelected = true;
mImpl->mEventData->mIsRightHandleSelected = true;
mImpl->mEventData->mCheckScrollAmount = true;
- if(mImpl->SetPrimaryCursorPosition(index))
+ if(mImpl->SetPrimaryCursorPosition(index, focused) && focused)
{
KeyboardFocusGainEvent();
return true;
SelectEvent(0.f, 0.f, SelectionType::NONE);
}
+void Controller::SelectText(const uint32_t start, const uint32_t end)
+{
+ SelectEvent(start, end, SelectionType::RANGE);
+}
+
string Controller::GetSelectedText() const
{
string text;
return text;
}
+string Controller::CopyText()
+{
+ string text;
+ mImpl->RetrieveSelection(text, false);
+ mImpl->SendSelectionToClipboard(false); // Text not modified
+
+ mImpl->mEventData->mUpdateCursorPosition = true;
+
+ mImpl->RequestRelayout(); // Cursor, Handles, Selection Highlight, Popup
+
+ return text;
+}
+
+string Controller::CutText()
+{
+ string text;
+ mImpl->RetrieveSelection(text, false);
+
+ if(!IsEditable())
+ {
+ return "";
+ }
+
+ mImpl->SendSelectionToClipboard(true); // Synchronous call to modify text
+ mImpl->mOperationsPending = ALL_OPERATIONS;
+
+ if((0u != mImpl->mModel->mLogicalModel->mText.Count()) ||
+ !mImpl->IsPlaceholderAvailable())
+ {
+ mImpl->QueueModifyEvent(ModifyEvent::TEXT_DELETED);
+ }
+ else
+ {
+ ShowPlaceholderText();
+ }
+
+ mImpl->mEventData->mUpdateCursorPosition = true;
+ mImpl->mEventData->mScrollAfterDelete = true;
+
+ mImpl->RequestRelayout();
+
+ if(nullptr != mImpl->mEditableControlInterface)
+ {
+ mImpl->mEditableControlInterface->TextChanged(true);
+ }
+ return text;
+}
+
+void Controller::PasteText()
+{
+ mImpl->RequestGetTextFromClipboard(); // Request clipboard service to retrieve an item
+}
+
InputMethodContext::CallbackData Controller::OnInputMethodContextEvent(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
{
return EventHandler::OnInputMethodContextEvent(*this, inputMethodContext, inputMethodContextEvent);