Added TEXT_COLOR, UNDERLINE_ENABLED and UNDERLINE_COLOR to properties and atlas renderer
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
index 151539c..15d79a1 100644 (file)
@@ -126,7 +126,7 @@ struct Controller::TextInput
     mCursorBlinkEnabled( true ),
     mGrabHandleEnabled( true ),
     mGrabHandlePopupEnabled( true ),
-    mSelectionEnabled( false ),
+    mSelectionEnabled( true ),
     mHorizontalScrollingEnabled( true ),
     mVerticalScrollingEnabled( false ),
     mUpdateCursorPosition( false )
@@ -254,6 +254,8 @@ struct Controller::TextInput
              2u == tapCount )
     {
       ChangeState( SELECTING );
+
+      RepositionSelectionHandles( event.p2.mFloat, event.p3.mFloat );
     }
   }
 
@@ -337,6 +339,36 @@ struct Controller::TextInput
     }
   }
 
+  void RepositionSelectionHandles( float visualX, float visualY )
+  {
+    // TODO - Find which word was selected
+
+    const Vector<GlyphInfo>& glyphs = mVisualModel->mGlyphs;
+    const Vector<Vector2>::SizeType glyphCount = glyphs.Count();
+
+    const Vector<Vector2>& positions = mVisualModel->mGlyphPositions;
+    const Vector<Vector2>::SizeType positionCount = positions.Count();
+
+    // Guard against glyphs which did not fit inside the layout
+    const Vector<Vector2>::SizeType count = (positionCount < glyphCount) ? positionCount : glyphCount;
+
+    if( count )
+    {
+      float primaryX   = positions[0].x;
+      float secondaryX = positions[count-1].x + glyphs[count-1].width;
+
+      // TODO - multi-line selection
+      const Vector<LineRun>& lines = mVisualModel->mLines;
+      float height = lines.Count() ? lines[0].lineSize.height : 0.0f;
+
+      mDecorator->SetPosition( PRIMARY_SELECTION_HANDLE,   primaryX,   0.0f, height );
+      mDecorator->SetPosition( SECONDARY_SELECTION_HANDLE, secondaryX, 0.0f, height );
+
+      mDecorator->ClearHighlights();
+      mDecorator->AddHighlight( primaryX, 0.0f, secondaryX, height );
+    }
+  }
+
   void ChangeState( State newState )
   {
     if( mState != newState )
@@ -618,6 +650,12 @@ struct Controller::Impl
     mFontClient = TextAbstraction::FontClient::Get();
 
     mView.SetVisualModel( mVisualModel );
+
+    // Set the text properties to default
+    mVisualModel->SetTextColor( Color::WHITE );
+    mVisualModel->SetShadowOffset( Vector2::ZERO );
+    mVisualModel->SetShadowColor( Vector4::ZERO );
+    mVisualModel->SetUnderlineEnabled( false );
   }
 
   ~Impl()
@@ -813,6 +851,56 @@ void Controller::GetDefaultFonts( Vector<FontRun>& fonts, Length numberOfCharact
   }
 }
 
+const Vector4& Controller::GetTextColor() const
+{
+  return mImpl->mVisualModel->GetTextColor();
+}
+
+const Vector2& Controller::GetShadowOffset() const
+{
+  return mImpl->mVisualModel->GetShadowOffset();
+}
+
+const Vector4& Controller::GetShadowColor() const
+{
+  return mImpl->mVisualModel->GetShadowColor();
+}
+
+const Vector4& Controller::GetUnderlineColor() const
+{
+  return mImpl->mVisualModel->GetUnderlineColor();
+}
+
+bool Controller::IsUnderlineEnabled() const
+{
+  return mImpl->mVisualModel->IsUnderlineEnabled();
+}
+
+void Controller::SetTextColor( const Vector4& textColor )
+{
+  mImpl->mVisualModel->SetTextColor( textColor );
+}
+
+void Controller::SetShadowOffset( const Vector2& shadowOffset )
+{
+  mImpl->mVisualModel->SetShadowOffset( shadowOffset );
+}
+
+void Controller::SetShadowColor( const Vector4& shadowColor )
+{
+  mImpl->mVisualModel->SetShadowColor( shadowColor );
+}
+
+void Controller::SetUnderlineColor( const Vector4& color )
+{
+  mImpl->mVisualModel->SetUnderlineColor( color );
+}
+
+void Controller::SetUnderlineEnabled( bool enabled )
+{
+  mImpl->mVisualModel->SetUnderlineEnabled( enabled );
+}
+
 void Controller::EnableTextInput( DecoratorPtr decorator )
 {
   if( !mImpl->mTextInput )
@@ -1334,6 +1422,10 @@ void Controller::UpdateModel( OperationsMask operationsRequired )
                glyphs,
                glyphsToCharactersMap,
                charactersPerGlyph );
+
+    // Create the 'number of glyphs' per character and the glyph to character conversion tables.
+    mImpl->mVisualModel->CreateGlyphsPerCharacterTable( numberOfCharacters );
+    mImpl->mVisualModel->CreateCharacterToGlyphTable( numberOfCharacters );
   }
 
   const Length numberOfGlyphs = glyphs.Count();
@@ -1342,13 +1434,6 @@ void Controller::UpdateModel( OperationsMask operationsRequired )
   {
     mImpl->mFontClient.GetGlyphMetrics( glyphs.Begin(), numberOfGlyphs );
   }
-
-  if( 0u != numberOfGlyphs )
-  {
-    // Create the glyph to character conversion table and the 'number of glyphs' per character.
-    mImpl->mVisualModel->CreateCharacterToGlyphTable(numberOfCharacters );
-    mImpl->mVisualModel->CreateGlyphsPerCharacterTable( numberOfCharacters );
-  }
 }
 
 bool Controller::DoRelayout( const Size& size,
@@ -1483,49 +1568,66 @@ bool Controller::DoRelayout( const Size& size,
 
 void Controller::CalculateTextAlignment( const Size& size )
 {
-  // TODO : Calculate the vertical offset.
-
   // Get the direction of the first character.
   const CharacterDirection firstParagraphDirection = mImpl->mLogicalModel->GetCharacterDirection( 0u );
 
   const Size& actualSize = mImpl->mVisualModel->GetActualSize();
 
   // If the first paragraph is right to left swap ALIGN_BEGIN and ALIGN_END;
-  LayoutEngine::Alignment alignment = mImpl->mLayoutEngine.GetAlignment();
+  LayoutEngine::HorizontalAlignment horizontalAlignment = mImpl->mLayoutEngine.GetHorizontalAlignment();
   if( firstParagraphDirection &&
-      ( LayoutEngine::ALIGN_CENTER != alignment ) )
+      ( LayoutEngine::HORIZONTAL_ALIGN_CENTER != horizontalAlignment ) )
   {
-    if( LayoutEngine::ALIGN_BEGIN == alignment )
+    if( LayoutEngine::HORIZONTAL_ALIGN_BEGIN == horizontalAlignment )
     {
-      alignment = LayoutEngine::ALIGN_END;
+      horizontalAlignment = LayoutEngine::HORIZONTAL_ALIGN_END;
     }
     else
     {
-      alignment = LayoutEngine::ALIGN_BEGIN;
+      horizontalAlignment = LayoutEngine::HORIZONTAL_ALIGN_BEGIN;
     }
   }
 
-  switch( alignment )
+  switch( horizontalAlignment )
   {
-    case LayoutEngine::ALIGN_BEGIN:
+    case LayoutEngine::HORIZONTAL_ALIGN_BEGIN:
     {
-      mImpl->mAlignmentOffset = Vector2::ZERO;
+      mImpl->mAlignmentOffset.x = 0.f;
       break;
     }
-    case LayoutEngine::ALIGN_CENTER:
+    case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
     {
-      mImpl->mAlignmentOffset.y = 0.f;
       const int intOffset = static_cast<int>( 0.5f * ( size.width - actualSize.width ) ); // try to avoid pixel alignment.
       mImpl->mAlignmentOffset.x = static_cast<float>( intOffset );
       break;
     }
-    case LayoutEngine::ALIGN_END:
+    case LayoutEngine::HORIZONTAL_ALIGN_END:
     {
-      mImpl->mAlignmentOffset.y = 0.f;
       mImpl->mAlignmentOffset.x = size.width - actualSize.width;
       break;
     }
   }
+
+  const LayoutEngine::VerticalAlignment verticalAlignment = mImpl->mLayoutEngine.GetVerticalAlignment();
+  switch( verticalAlignment )
+  {
+    case LayoutEngine::VERTICAL_ALIGN_TOP:
+    {
+      mImpl->mAlignmentOffset.y = 0.f;
+      break;
+    }
+    case LayoutEngine::VERTICAL_ALIGN_CENTER:
+    {
+      const int intOffset = static_cast<int>( 0.5f * ( size.height - actualSize.height ) ); // try to avoid pixel alignment.
+      mImpl->mAlignmentOffset.y = static_cast<float>( intOffset );
+      break;
+    }
+    case LayoutEngine::VERTICAL_ALIGN_BOTTOM:
+    {
+      mImpl->mAlignmentOffset.y = size.height - actualSize.height;
+      break;
+    }
+  }
 }
 
 View& Controller::GetView()