Merge "Fix for text's highlight box." into devel/master
authorPaul Wisbey <p.wisbey@samsung.com>
Fri, 15 Jul 2016 14:47:50 +0000 (07:47 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Fri, 15 Jul 2016 14:47:51 +0000 (07:47 -0700)
dali-toolkit/internal/text/decorator/text-decorator.cpp
dali-toolkit/internal/text/decorator/text-decorator.h
dali-toolkit/internal/text/text-controller-impl.cpp

index a33a9bc..281e43d 100644 (file)
@@ -47,12 +47,10 @@ namespace
 const char* VERTEX_SHADER = MAKE_SHADER(
 attribute mediump vec2    aPosition;
 uniform   mediump mat4    uMvpMatrix;
-uniform   mediump vec3    uSize;
 
 void main()
 {
   mediump vec4 position = vec4( aPosition, 0.0, 1.0 );
-  position.xyz *= uSize;
   gl_Position = uMvpMatrix * position;
 }
 );
@@ -1042,8 +1040,8 @@ struct Decorator::Impl : public ConnectionTracker
 #ifdef DECORATOR_DEBUG
       mHighlightActor.SetName( "HighlightActor" );
 #endif
+      mHighlightActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
       mHighlightActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-      mHighlightActor.SetSize( 1.0f, 1.0f );
       mHighlightActor.SetColor( mHighlightColor );
       mHighlightActor.SetColorMode( USE_OWN_COLOR );
     }
@@ -1056,37 +1054,57 @@ struct Decorator::Impl : public ConnectionTracker
   {
     if ( mHighlightActor )
     {
-      if( !mHighlightQuadList.empty() )
+      // Sets the position of the highlight actor inside the decorator.
+      mHighlightActor.SetPosition( mHighlightPosition.x,
+                                   mHighlightPosition.y );
+
+      const unsigned int numberOfQuads = mHighlightQuadList.size();
+      if( 0u != numberOfQuads )
       {
-        Vector< Vector2 > vertices;
-        Vector< unsigned short> indices;
-        Vector2 vertex;
+        // Set the size of the highlighted text to the actor.
+        mHighlightActor.SetSize( mHighlightSize );
+
+        // Used to translate the vertices given in decorator's coords to the mHighlightActor's local coords.
+        const float offsetX = mHighlightPosition.x + 0.5f * mHighlightSize.width;
+        const float offsetY = mHighlightPosition.y + 0.5f * mHighlightSize.height;
 
-        std::vector<QuadCoordinates>::iterator iter = mHighlightQuadList.begin();
-        std::vector<QuadCoordinates>::iterator endIter = mHighlightQuadList.end();
+        Vector<Vector2> vertices;
+        Vector<unsigned short> indices;
 
-        for( std::size_t v = 0; iter != endIter; ++iter,v+=4 )
+        vertices.Reserve( 4u * numberOfQuads );
+        indices.Reserve( 6u * numberOfQuads );
+
+        // Index to the vertex.
+        unsigned int v = 0u;
+
+        // Traverse all quads.
+        for( std::vector<QuadCoordinates>::iterator it = mHighlightQuadList.begin(),
+               endIt = mHighlightQuadList.end();
+             it != endIt;
+             ++it, v += 4u )
         {
-          QuadCoordinates& quad = *iter;
+          QuadCoordinates& quad = *it;
+
+          Vector2 vertex;
 
           // top-left (v+0)
-          vertex.x = quad.min.x;
-          vertex.y = quad.min.y;
+          vertex.x = quad.min.x - offsetX;
+          vertex.y = quad.min.y - offsetY;
           vertices.PushBack( vertex );
 
           // top-right (v+1)
-          vertex.x = quad.max.x;
-          vertex.y = quad.min.y;
+          vertex.x = quad.max.x - offsetX;
+          vertex.y = quad.min.y - offsetY;
           vertices.PushBack( vertex );
 
           // bottom-left (v+2)
-          vertex.x = quad.min.x;
-          vertex.y = quad.max.y;
+          vertex.x = quad.min.x - offsetX;
+          vertex.y = quad.max.y - offsetY;
           vertices.PushBack( vertex );
 
           // bottom-right (v+3)
-          vertex.x = quad.max.x;
-          vertex.y = quad.max.y;
+          vertex.x = quad.max.x - offsetX;
+          vertex.y = quad.max.y - offsetY;
           vertices.PushBack( vertex );
 
           // triangle A (3, 1, 0)
@@ -1121,9 +1139,6 @@ struct Decorator::Impl : public ConnectionTracker
         }
       }
 
-      mHighlightActor.SetPosition( mHighlightPosition.x,
-                                   mHighlightPosition.y );
-
       mHighlightQuadList.clear();
 
       if( mHighlightRenderer )
@@ -1768,7 +1783,8 @@ struct Decorator::Impl : public ConnectionTracker
   Vector4             mBoundingBox;               ///< The bounding box in world coords.
   Vector4             mHighlightColor;            ///< Color of the highlight
   Vector2             mHighlightPosition;         ///< The position of the highlight actor.
-  Vector2             mControlSize;               ///< The control's size. Set by the Relayout.
+  Size                mHighlightSize;             ///< The size of the highlighted text.
+  Size                mControlSize;               ///< The control's size. Set by the Relayout.
 
   unsigned int        mActiveCursor;
   unsigned int        mCursorBlinkInterval;
@@ -2042,6 +2058,12 @@ void Decorator::AddHighlight( float x1, float y1, float x2, float y2 )
   mImpl->mHighlightQuadList.push_back( QuadCoordinates(x1, y1, x2, y2) );
 }
 
+void Decorator::SetHighLightBox( const Vector2& position, const Size& size )
+{
+  mImpl->mHighlightPosition = position;
+  mImpl->mHighlightSize = size;
+}
+
 void Decorator::ClearHighlights()
 {
   mImpl->mHighlightQuadList.clear();
index c52b7d0..a868958 100644 (file)
@@ -435,7 +435,7 @@ public:
   void SetSelectionHandleFlipState( bool indicesSwapped, bool left, bool right );
 
   /**
-   * @brief Adds a quad to the existing selection highlights.
+   * @brief Adds a quad to the existing selection highlights. Vertices are in decorator's coordinates.
    *
    * @param[in] x1 The top-left x position.
    * @param[in] y1 The top-left y position.
@@ -445,6 +445,18 @@ public:
   void AddHighlight( float x1, float y1, float x2, float y2 );
 
   /**
+   * @brief Sets the min 'x,y' coordinates and the size of the highlighted box.
+   *
+   * It's used to set the size and position of the highlight's actor and to translate each highlight quad from
+   * decorator's coordinates to the local coords of the highlight's actor.
+   *
+   * @param[in] position The position of the highlighted text in decorator's coords.
+   * @param[in] size The size of the highlighted text.
+   */
+  void SetHighLightBox( const Vector2& position,
+                        const Size& size );
+
+  /**
    * @brief Removes all of the previously added highlights.
    */
   void ClearHighlights();
index 9a57431..e4029b3 100644 (file)
@@ -1733,11 +1733,19 @@ void Controller::Impl::RepositionSelectionHandles()
   selectionBoxInfo->minX = MAX_FLOAT;
   selectionBoxInfo->maxX = MIN_FLOAT;
 
+  // Keep the min and max 'x' position to calculate the size and position of the highlighed text.
+  float minHighlightX = std::numeric_limits<float>::max();
+  float maxHighlightX = std::numeric_limits<float>::min();
+  Size highLightSize;
+  Vector2 highLightPosition; // The highlight position in decorator's coords.
+
   // Retrieve the first line and get the line's vertical offset, the line's height and the index to the last glyph.
 
   // The line's vertical offset of all the lines before the line where the first glyph is laid-out.
   selectionBoxInfo->lineOffset = CalculateLineOffset( mVisualModel->mLines,
                                                       firstLineIndex );
+
+  // Transform to decorator's (control) coords.
   selectionBoxInfo->lineOffset += mScrollPosition.y;
 
   lineRun += firstLineIndex;
@@ -1873,6 +1881,21 @@ void Controller::Impl::RepositionSelectionHandles()
     }
   }
 
+  // Traverses all the lines and updates the min and max 'x' positions and the total height.
+  // The final width is calculated after 'boxifying' the selection.
+  for( Vector<SelectionBoxInfo>::ConstIterator it = selectionBoxLinesInfo.Begin(),
+         endIt = selectionBoxLinesInfo.End();
+       it != endIt;
+       ++it )
+  {
+    const SelectionBoxInfo& info = *it;
+
+    // Update the size of the highlighted text.
+    highLightSize.height += selectionBoxInfo->lineHeight;
+    minHighlightX = std::min( minHighlightX, info.minX );
+    maxHighlightX = std::max( maxHighlightX, info.maxX );
+  }
+
   // Add extra geometry to 'boxify' the selection.
 
   if( 1u < numberOfLines )
@@ -1891,6 +1914,9 @@ void Controller::Impl::RepositionSelectionHandles()
                                             firstSelectionBoxLineInfo.lineOffset,
                                             firstSelectionBoxLineInfo.minX,
                                             firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight );
+
+      // Update the size of the highlighted text.
+      minHighlightX = 0.f;
     }
 
     if( boxifyEnd )
@@ -1900,6 +1926,9 @@ void Controller::Impl::RepositionSelectionHandles()
                                             firstSelectionBoxLineInfo.lineOffset,
                                             mVisualModel->mControlSize.width,
                                             firstSelectionBoxLineInfo.lineOffset + firstSelectionBoxLineInfo.lineHeight );
+
+      // Update the size of the highlighted text.
+      maxHighlightX = mVisualModel->mControlSize.width;
     }
 
     // Boxify the central lines.
@@ -1922,6 +1951,10 @@ void Controller::Impl::RepositionSelectionHandles()
                                               mVisualModel->mControlSize.width,
                                               info.lineOffset + info.lineHeight );
       }
+
+      // Update the size of the highlighted text.
+      minHighlightX = 0.f;
+      maxHighlightX = mVisualModel->mControlSize.width;
     }
 
     // Boxify the last line.
@@ -1938,6 +1971,9 @@ void Controller::Impl::RepositionSelectionHandles()
                                             lastSelectionBoxLineInfo.lineOffset,
                                             lastSelectionBoxLineInfo.minX,
                                             lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight );
+
+      // Update the size of the highlighted text.
+      minHighlightX = 0.f;
     }
 
     if( boxifyEnd )
@@ -1947,9 +1983,22 @@ void Controller::Impl::RepositionSelectionHandles()
                                             lastSelectionBoxLineInfo.lineOffset,
                                             mVisualModel->mControlSize.width,
                                             lastSelectionBoxLineInfo.lineOffset + lastSelectionBoxLineInfo.lineHeight );
+
+      // Update the size of the highlighted text.
+      maxHighlightX = mVisualModel->mControlSize.width;
     }
   }
 
+  // Sets the highlight's size and position. In decorator's coords.
+  // The highlight's height has been calculated above (before 'boxifying' the highlight).
+  highLightSize.width = maxHighlightX - minHighlightX;
+
+  highLightPosition.x = minHighlightX;
+  const SelectionBoxInfo& firstSelectionBoxLineInfo = *( selectionBoxLinesInfo.Begin() );
+  highLightPosition.y = firstSelectionBoxLineInfo.lineOffset;
+
+  mEventData->mDecorator->SetHighLightBox( highLightPosition, highLightSize );
+
   if( !mEventData->mDecorator->IsSmoothHandlePanEnabled() )
   {
     CursorInfo primaryCursorInfo;