+void Controller::SetMaximumNumberOfCharacters( Length maxCharacters )
+{
+ mImpl->mMaximumNumberOfCharacters = maxCharacters;
+}
+
+int Controller::GetMaximumNumberOfCharacters()
+{
+ return mImpl->mMaximumNumberOfCharacters;
+}
+
+void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
+{
+ if( NULL == mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
+ mImpl->mFontDefaults->familyDefined = !defaultFontFamily.empty();
+
+ // Clear the font-specific data
+ ClearFontData();
+
+ mImpl->RequestRelayout();
+}
+
+const std::string& Controller::GetDefaultFontFamily() const
+{
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mFontDescription.family;
+ }
+
+ return EMPTY_STRING;
+}
+
+void Controller::SetDefaultFontWeight( FontWeight weight )
+{
+ if( NULL == mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mFontDescription.weight = weight;
+ mImpl->mFontDefaults->weightDefined = true;
+
+ // Clear the font-specific data
+ ClearFontData();
+
+ mImpl->RequestRelayout();
+}
+
+bool Controller::IsDefaultFontWeightDefined() const
+{
+ return mImpl->mFontDefaults->weightDefined;
+}
+
+FontWeight Controller::GetDefaultFontWeight() const
+{
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mFontDescription.weight;
+ }
+
+ return TextAbstraction::FontWeight::NORMAL;
+}
+
+void Controller::SetDefaultFontWidth( FontWidth width )
+{
+ if( NULL == mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mFontDescription.width = width;
+ mImpl->mFontDefaults->widthDefined = true;
+
+ // Clear the font-specific data
+ ClearFontData();
+
+ mImpl->RequestRelayout();
+}
+
+bool Controller::IsDefaultFontWidthDefined() const
+{
+ return mImpl->mFontDefaults->widthDefined;
+}
+
+FontWidth Controller::GetDefaultFontWidth() const
+{
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mFontDescription.width;
+ }
+
+ return TextAbstraction::FontWidth::NORMAL;
+}
+
+void Controller::SetDefaultFontSlant( FontSlant slant )
+{
+ if( NULL == mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mFontDescription.slant = slant;
+ mImpl->mFontDefaults->slantDefined = true;
+
+ // Clear the font-specific data
+ ClearFontData();
+
+ mImpl->RequestRelayout();
+}
+
+bool Controller::IsDefaultFontSlantDefined() const
+{
+ return mImpl->mFontDefaults->slantDefined;
+}
+
+FontSlant Controller::GetDefaultFontSlant() const
+{
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mFontDescription.slant;
+ }
+
+ return TextAbstraction::FontSlant::NORMAL;
+}
+
+void Controller::SetDefaultPointSize( float pointSize )
+{
+ if( NULL == mImpl->mFontDefaults )
+ {
+ mImpl->mFontDefaults = new FontDefaults();
+ }
+
+ mImpl->mFontDefaults->mDefaultPointSize = pointSize;
+ mImpl->mFontDefaults->sizeDefined = true;
+
+ // Clear the font-specific data
+ ClearFontData();
+
+ mImpl->RequestRelayout();
+}
+
+float Controller::GetDefaultPointSize() const
+{
+ if( NULL != mImpl->mFontDefaults )
+ {
+ return mImpl->mFontDefaults->mDefaultPointSize;
+ }
+
+ return 0.0f;
+}
+
+void Controller::UpdateAfterFontChange( const std::string& newDefaultFont )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange\n");
+
+ if( !mImpl->mFontDefaults->familyDefined ) // If user defined font then should not update when system font changes
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str() );
+ mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
+
+ ClearFontData();
+
+ mImpl->RequestRelayout();
+ }
+}
+
+void Controller::SetTextColor( const Vector4& textColor )
+{
+ mImpl->mTextColor = textColor;
+
+ if( !mImpl->IsShowingPlaceholderText() )
+ {
+ mImpl->mVisualModel->SetTextColor( textColor );
+
+ mImpl->RequestRelayout();
+ }
+}
+
+const Vector4& Controller::GetTextColor() const
+{
+ return mImpl->mTextColor;
+}
+
+bool Controller::RemoveText( int cursorOffset,
+ int numberOfCharacters,
+ UpdateInputStyleType type )
+{
+ bool removed = false;
+
+ if( NULL == mImpl->mEventData )
+ {
+ return removed;
+ }
+
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p mText.Count() %d cursor %d cursorOffset %d numberOfCharacters %d\n",
+ this, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition, cursorOffset, numberOfCharacters );
+
+ if( !mImpl->IsShowingPlaceholderText() )
+ {
+ // Delete at current cursor position
+ Vector<Character>& currentText = mImpl->mLogicalModel->mText;
+ CharacterIndex& oldCursorIndex = mImpl->mEventData->mPrimaryCursorPosition;
+
+ CharacterIndex cursorIndex = oldCursorIndex;
+
+ // Validate the cursor position & number of characters
+ if( static_cast< CharacterIndex >( std::abs( cursorOffset ) ) <= cursorIndex )
+ {
+ cursorIndex = oldCursorIndex + cursorOffset;
+ }
+
+ if( ( cursorIndex + numberOfCharacters ) > currentText.Count() )
+ {
+ numberOfCharacters = currentText.Count() - cursorIndex;
+ }
+
+ if( ( cursorIndex + numberOfCharacters ) <= mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters )
+ {
+ // Mark the paragraphs to be updated.
+ mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
+ mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove += numberOfCharacters;
+
+ // Update the input style and remove the text's style before removing the text.
+
+ if( UPDATE_INPUT_STYLE == type )
+ {
+ // Set first the default input style.
+ mImpl->RetrieveDefaultInputStyle( mImpl->mEventData->mInputStyle );
+
+ // Update the input style.
+ mImpl->mLogicalModel->RetrieveStyle( cursorIndex, mImpl->mEventData->mInputStyle );
+ }
+
+ // Updates the text style runs by removing characters. Runs with no characters are removed.
+ mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, -numberOfCharacters );
+
+ // Remove the characters.
+ Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
+ Vector<Character>::Iterator last = first + numberOfCharacters;
+
+ currentText.Erase( first, last );
+
+ // Cursor position retreat
+ oldCursorIndex = cursorIndex;
+
+ mImpl->mEventData->mScrollAfterDelete = true;
+
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfCharacters );
+ removed = true;
+ }
+ }
+
+ return removed;
+}
+
+void Controller::SetPlaceholderTextColor( const Vector4& textColor )
+{
+ if( NULL != mImpl->mEventData )
+ {
+ mImpl->mEventData->mPlaceholderTextColor = textColor;
+ }
+
+ if( mImpl->IsShowingPlaceholderText() )
+ {
+ mImpl->mVisualModel->SetTextColor( textColor );
+ mImpl->RequestRelayout();
+ }
+}
+
+const Vector4& Controller::GetPlaceholderTextColor() const
+{
+ if( NULL != mImpl->mEventData )
+ {
+ return mImpl->mEventData->mPlaceholderTextColor;
+ }
+
+ return Color::BLACK;
+}
+
+void Controller::SetShadowOffset( const Vector2& shadowOffset )
+{
+ mImpl->mVisualModel->SetShadowOffset( shadowOffset );
+
+ mImpl->RequestRelayout();
+}
+
+const Vector2& Controller::GetShadowOffset() const
+{
+ return mImpl->mVisualModel->GetShadowOffset();
+}
+
+void Controller::SetShadowColor( const Vector4& shadowColor )
+{
+ mImpl->mVisualModel->SetShadowColor( shadowColor );
+
+ mImpl->RequestRelayout();
+}
+
+const Vector4& Controller::GetShadowColor() const
+{
+ return mImpl->mVisualModel->GetShadowColor();
+}
+
+void Controller::SetDefaultShadowProperties( const std::string& shadowProperties )
+{
+ if( NULL == mImpl->mShadowDefaults )
+ {
+ mImpl->mShadowDefaults = new ShadowDefaults();
+ }
+
+ mImpl->mShadowDefaults->properties = shadowProperties;
+}
+
+const std::string& Controller::GetDefaultShadowProperties() const
+{
+ if( NULL != mImpl->mShadowDefaults )
+ {
+ return mImpl->mShadowDefaults->properties;
+ }
+
+ return EMPTY_STRING;
+}
+
+void Controller::SetUnderlineColor( const Vector4& color )
+{
+ mImpl->mVisualModel->SetUnderlineColor( color );
+
+ mImpl->RequestRelayout();
+}
+
+const Vector4& Controller::GetUnderlineColor() const
+{
+ return mImpl->mVisualModel->GetUnderlineColor();
+}
+
+void Controller::SetUnderlineEnabled( bool enabled )
+{
+ mImpl->mVisualModel->SetUnderlineEnabled( enabled );
+
+ mImpl->RequestRelayout();
+}
+
+bool Controller::IsUnderlineEnabled() const
+{
+ return mImpl->mVisualModel->IsUnderlineEnabled();
+}
+
+void Controller::SetUnderlineHeight( float height )
+{
+ mImpl->mVisualModel->SetUnderlineHeight( height );
+
+ mImpl->RequestRelayout();
+}
+
+float Controller::GetUnderlineHeight() const
+{
+ return mImpl->mVisualModel->GetUnderlineHeight();
+}
+
+void Controller::SetDefaultUnderlineProperties( const std::string& underlineProperties )
+{
+ if( NULL == mImpl->mUnderlineDefaults )
+ {
+ mImpl->mUnderlineDefaults = new UnderlineDefaults();
+ }
+
+ mImpl->mUnderlineDefaults->properties = underlineProperties;
+}
+
+const std::string& Controller::GetDefaultUnderlineProperties() const
+{
+ if( NULL != mImpl->mUnderlineDefaults )
+ {
+ return mImpl->mUnderlineDefaults->properties;
+ }
+
+ return EMPTY_STRING;
+}
+
+void Controller::SetDefaultEmbossProperties( const std::string& embossProperties )
+{
+ if( NULL == mImpl->mEmbossDefaults )
+ {
+ mImpl->mEmbossDefaults = new EmbossDefaults();
+ }
+
+ mImpl->mEmbossDefaults->properties = embossProperties;
+}
+
+const std::string& Controller::GetDefaultEmbossProperties() const
+{
+ if( NULL != mImpl->mEmbossDefaults )
+ {
+ return mImpl->mEmbossDefaults->properties;
+ }
+
+ return EMPTY_STRING;
+}
+
+void Controller::SetDefaultOutlineProperties( const std::string& outlineProperties )
+{
+ if( NULL == mImpl->mOutlineDefaults )
+ {
+ mImpl->mOutlineDefaults = new OutlineDefaults();
+ }
+
+ mImpl->mOutlineDefaults->properties = outlineProperties;
+}
+
+const std::string& Controller::GetDefaultOutlineProperties() const
+{
+ if( NULL != mImpl->mOutlineDefaults )
+ {
+ return mImpl->mOutlineDefaults->properties;
+ }
+
+ return EMPTY_STRING;
+}
+
+void Controller::SetDefaultLineSpacing( float lineSpacing )
+{
+ //TODO finish implementation
+ mImpl->mLayoutEngine.SetDefaultLineSpacing( lineSpacing );
+}
+
+float Controller::GetDefaultLineSpacing() const
+{
+ return mImpl->mLayoutEngine.GetDefaultLineSpacing();
+}
+
+void Controller::SetInputColor( const Vector4& color )
+{
+ if( NULL != mImpl->mEventData )
+ {
+ mImpl->mEventData->mInputStyle.textColor = color;
+ mImpl->mEventData->mInputStyle.isDefaultColor = false;
+
+ 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;
+
+ // Add the color run.
+ const VectorBase::SizeType numberOfRuns = mImpl->mLogicalModel->mColorRuns.Count();
+ mImpl->mLogicalModel->mColorRuns.Resize( numberOfRuns + 1u );
+
+ ColorRun& colorRun = *( mImpl->mLogicalModel->mColorRuns.Begin() + numberOfRuns );
+ colorRun.color = color;
+ colorRun.characterRun.characterIndex = startOfSelectedText;
+ colorRun.characterRun.numberOfCharacters = lengthOfSelectedText;
+
+ // 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;
+ }
+ }
+}
+
+const Vector4& Controller::GetInputColor() const