if( mRenderableActor )
{
- // TODO: Scroll and alignment needs to be refactored.
- const Vector2& alignmentOffset = mController->GetAlignmentOffset();
const Vector2& scrollOffset = mController->GetScrollPosition();
- mRenderableActor.SetPosition( scrollOffset.x, alignmentOffset.y + scrollOffset.y );
+ mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
Actor clipRootActor;
if( mClipper )
if( mRenderableActor )
{
- // TODO: Scroll and alignment needs to be refactored.
- const Vector2& alignmentOffset = mController->GetAlignmentOffset();
const Vector2& scrollOffset = mController->GetScrollPosition();
- mRenderableActor.SetPosition( scrollOffset.x, alignmentOffset.y + scrollOffset.y );
+ mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
Actor clipRootActor;
if( mClipper )
if( renderableActor )
{
- // TODO: Scroll and alignment needs to be refactored.
- const Vector2& alignmentOffset = mController->GetAlignmentOffset();
- renderableActor.SetPosition( 0.f, alignmentOffset.y );
+ const Vector2& scrollOffset = mController->GetScrollPosition();
+ renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
self.Add( renderableActor );
}
{
const Size& controlSize = mController->GetView().GetControlSize();
const Size offScreenSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only.
- const Vector2& alignmentOffset = mController->GetAlignmentOffset();
+ const float alignmentOffset = mController->GetAutoScrollLineAlignment();
const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
- DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f,%f] offScreenSize[%f,%f] controlSize[%f,%f]\n",
- alignmentOffset.x, alignmentOffset.y, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y);
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n",
+ alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y );
if ( !mTextScroller )
{
- DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n");
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n" );
// If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
mTextScroller = Text::TextScroller::New( *this );
{
const LineRun& lineRun = lines[lineIndex];
totalHeight += lineRun.ascender + -lineRun.descender;
+
if( visualY < totalHeight )
{
return lineIndex;
// Find which line is closest.
const LineIndex lineIndex = Text::GetClosestLine( visualModel,
visualY );
- const LineRun& line = visualModel->mLines[lineIndex];
+
+ // Convert from text's coords to line's coords.
+ const LineRun& line = *( visualModel->mLines.Begin() + lineIndex );
+ visualX -= line.alignmentOffset;
// Get the positions of the glyphs.
const Vector<Vector2>& positions = visualModel->mGlyphPositions;
glyphAdvance = static_cast<float>( numberOfGlyphAdvance ) * glyphMetrics.advance / static_cast<float>( primaryNumberOfCharacters );
}
- // Get the glyph position and x bearing.
+ // Get the glyph position and x bearing (in the line's coords).
const Vector2& primaryPosition = *( glyphPositionsBuffer + primaryGlyphIndex );
// Set the primary cursor's height.
cursorInfo.primaryPosition.x = -glyphMetrics.xBearing + primaryPosition.x + glyphAdvance;
cursorInfo.primaryPosition.y = line.ascender - glyphMetrics.ascender;
+ // Transform the cursor info from line's coords to text's coords.
+ cursorInfo.primaryPosition.x += line.alignmentOffset;
+
// Calculate the secondary cursor.
if( cursorInfo.isSecondaryCursor )
// Set the secondary cursor's position.
cursorInfo.secondaryPosition.x = -glyphMetrics.xBearing + secondaryPosition.x + ( isCurrentRightToLeft ? 0.f : glyphMetrics.advance );
cursorInfo.secondaryPosition.y = cursorInfo.lineHeight - cursorInfo.secondaryCursorHeight - line.descender - ( glyphMetrics.fontHeight - glyphMetrics.ascender );
+
+ // Transform the cursor info from line's coords to text's coords.
+ cursorInfo.secondaryPosition.x += line.alignmentOffset;
}
}
~CursorInfo()
{}
- Vector2 primaryPosition; ///< The primary cursor's position.
- Vector2 secondaryPosition; ///< The secondary cursor's position.
+ Vector2 primaryPosition; ///< The primary cursor's position (in text's coords).
+ Vector2 secondaryPosition; ///< The secondary cursor's position (in text's coords).
float lineOffset; ///< The vertical offset where the line containing the cursor starts.
float lineHeight; ///< The height of the line where the cursor is placed.
float primaryCursorHeight; ///< The primary cursor's height.
*
* It returns the first line if the touch point is above the text and the last line if the touch point is below.
*
+ * @param[in] visualModel The visual model.
+ * @param[in] visualY The touch point 'y' in text's coords.
+ *
* @return A line index.
*/
LineIndex GetClosestLine( VisualModelPtr visualModel,
* @param[in] visualModel The visual model.
* @param[in] logicalModel The logical model.
* @param[in] metrics A wrapper around FontClient used to get metrics.
- * @param[in] visualX The touch point x.
- * @param[in] visualY The touch point y.
+ * @param[in] visualX The touch point 'x' in text's coords.
+ * @param[in] visualY The touch point 'y' in text's coords.
*
* @return The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
*/
* It retrieves as well the line's height and the cursor's height and
* if there is a valid alternative cursor, its position and height.
*
+ * @param[in] visualModel The visual model.
+ * @param[in] logicalModel The logical model.
+ * @param[in] metrics A wrapper around FontClient used to get metrics.
* @param[in] logical The logical cursor position (in characters). 0 is just before the first character, a value equal to the number of characters is just after the last character.
* @param[out] cursorInfo The line's height, the cursor's height, the cursor's position and whether there is an alternative cursor.
*/
CursorInfo& cursorInfo );
/**
+ * @brief Find the indices to the first and last characters of a word for the given touch point.
*
+ * @param[in] visualModel The visual model.
+ * @param[in] logicalModel The logical model.
+ * @param[in] metrics A wrapper around FontClient used to get metrics.
+ * @param[in] visualX The touch point 'x' in text's coords.
+ * @param[in] visualY The touch point 'y' in text's coords.
+ * @param[out] startIndex Index to the first character of the selected word.
+ * @param[out] endIndex Index to the last character of the selected word.
*/
void FindSelectionIndices( VisualModelPtr visualModel,
LogicalModelPtr logicalModel,
mPlaceholderTextInactive(),
mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ),
mEventQueue(),
- mScrollPosition(),
mState( INACTIVE ),
mPrimaryCursorPosition( 0u ),
mLeftSelectionPosition( 0u ),
{
if( IsShowingRealText() )
{
- const float xPosition = event.p2.mFloat - mEventData->mScrollPosition.x - mAlignmentOffset.x;
- const float yPosition = event.p3.mFloat - mEventData->mScrollPosition.y - mAlignmentOffset.y;
+ // Convert from control's coords to text's coords.
+ const float xPosition = event.p2.mFloat - mScrollPosition.x;
+ const float yPosition = event.p3.mFloat - mScrollPosition.y;
mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel,
mLogicalModel,
int state = event.p1.mInt;
- if( Gesture::Started == state ||
- Gesture::Continuing == state )
+ if( ( Gesture::Started == state ) ||
+ ( Gesture::Continuing == state ) )
{
const Vector2& actualSize = mVisualModel->GetLayoutSize();
- const Vector2 currentScroll = mEventData->mScrollPosition;
+ const Vector2 currentScroll = mScrollPosition;
if( mEventData->mHorizontalScrollingEnabled )
{
const float displacementX = event.p2.mFloat;
- mEventData->mScrollPosition.x += displacementX;
+ mScrollPosition.x += displacementX;
ClampHorizontalScroll( actualSize );
}
if( mEventData->mVerticalScrollingEnabled )
{
const float displacementY = event.p3.mFloat;
- mEventData->mScrollPosition.y += displacementY;
+ mScrollPosition.y += displacementY;
ClampVerticalScroll( actualSize );
}
if( mEventData->mDecorator )
{
- mEventData->mDecorator->UpdatePositions( mEventData->mScrollPosition - currentScroll );
+ mEventData->mDecorator->UpdatePositions( mScrollPosition - currentScroll );
}
}
}
if( HANDLE_PRESSED == state )
{
- // The event.p2 and event.p3 are in decorator coords. Need to transforms to text coords.
- const float xPosition = event.p2.mFloat - mEventData->mScrollPosition.x - mAlignmentOffset.x;
- const float yPosition = event.p3.mFloat - mEventData->mScrollPosition.y - mAlignmentOffset.y;
+ // Convert from decorator's coords to text's coords.
+ const float xPosition = event.p2.mFloat - mScrollPosition.x;
+ const float yPosition = event.p3.mFloat - mScrollPosition.y;
const CharacterIndex handleNewPosition = Text::GetClosestCursorIndex( mVisualModel,
mLogicalModel,
CharacterIndex handlePosition = 0u;
if( handleStopScrolling )
{
- // The event.p2 and event.p3 are in decorator coords. Need to transforms to text coords.
- const float xPosition = event.p2.mFloat - mEventData->mScrollPosition.x - mAlignmentOffset.x;
- const float yPosition = event.p3.mFloat - mEventData->mScrollPosition.y - mAlignmentOffset.y;
+ // Convert from decorator's coords to text's coords.
+ const float xPosition = event.p2.mFloat - mScrollPosition.x;
+ const float yPosition = event.p3.mFloat - mScrollPosition.y;
handlePosition = Text::GetClosestCursorIndex( mVisualModel,
mLogicalModel,
{
const float xSpeed = event.p2.mFloat;
const Vector2& actualSize = mVisualModel->GetLayoutSize();
- const Vector2 currentScrollPosition = mEventData->mScrollPosition;
+ const Vector2 currentScrollPosition = mScrollPosition;
- mEventData->mScrollPosition.x += xSpeed;
+ mScrollPosition.x += xSpeed;
ClampHorizontalScroll( actualSize );
bool endOfScroll = false;
- if( Vector2::ZERO == ( currentScrollPosition - mEventData->mScrollPosition ) )
+ if( Vector2::ZERO == ( currentScrollPosition - mScrollPosition ) )
{
// Notify the decorator there is no more text to scroll.
// The decorator won't send more scroll events.
position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width;
// Get the new handle position.
- // The grab handle's position is in decorator coords. Need to transforms to text coords.
+ // The grab handle's position is in decorator's coords. Need to transforms to text's coords.
const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mVisualModel,
mLogicalModel,
mMetrics,
- position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x,
- position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y );
+ position.x - mScrollPosition.x,
+ position.y - mScrollPosition.y );
mEventData->mUpdateCursorPosition = mEventData->mPrimaryCursorPosition != handlePosition;
mEventData->mScrollAfterUpdatePosition = mEventData->mUpdateCursorPosition;
position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width;
// Get the new handle position.
- // The selection handle's position is in decorator coords. Need to transforms to text coords.
+ // The selection handle's position is in decorator's coords. Need to transform to text's coords.
const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mVisualModel,
mLogicalModel,
mMetrics,
- position.x - mEventData->mScrollPosition.x - mAlignmentOffset.x,
- position.y - mEventData->mScrollPosition.y - mAlignmentOffset.y );
+ position.x - mScrollPosition.x,
+ position.y - mScrollPosition.y );
if( leftSelectionHandleEvent )
{
if( mEventData->mSelectionEnabled )
{
- // The event.p2 and event.p3 are in decorator coords. Need to transforms to text coords.
- const float xPosition = event.p2.mFloat - mEventData->mScrollPosition.x - mAlignmentOffset.x;
- const float yPosition = event.p3.mFloat - mEventData->mScrollPosition.y - mAlignmentOffset.y;
+ // Convert from control's coords to text's coords.
+ const float xPosition = event.p2.mFloat - mScrollPosition.x;
+ const float yPosition = event.p3.mFloat - mScrollPosition.y;
// Calculates the logical position from the x,y coords.
RepositionSelectionHandles( xPosition,
const Length numberOfCharactersEnd = *( charactersPerGlyphBuffer + glyphEnd );
bool splitEndGlyph = ( glyphStart != glyphEnd ) && ( numberOfCharactersEnd > 1u ) && HasLigatureMustBreak( mLogicalModel->GetScript( selectionEndMinusOne ) );
- const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset;
-
// Traverse the glyphs.
for( GlyphIndex index = glyphStart; index <= glyphEnd; ++index )
{
// Calculate the number of characters selected.
const Length numberOfCharacters = ( glyphStart == glyphEnd ) ? ( selectionEnd - selectionStart ) : ( numberOfCharactersStart - interGlyphIndex );
- const float xPosition = position.x - glyph.xBearing + offset.x + glyphAdvance * static_cast<float>( isCurrentRightToLeft ? ( numberOfCharactersStart - interGlyphIndex - numberOfCharacters ) : interGlyphIndex );
+ const float xPosition = firstLine.alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + glyphAdvance * static_cast<float>( isCurrentRightToLeft ? ( numberOfCharactersStart - interGlyphIndex - numberOfCharacters ) : interGlyphIndex );
mEventData->mDecorator->AddHighlight( xPosition,
- offset.y,
+ mScrollPosition.y,
xPosition + static_cast<float>( numberOfCharacters ) * glyphAdvance,
- offset.y + height );
+ mScrollPosition.y + height );
splitStartGlyph = false;
continue;
const Length numberOfCharacters = numberOfCharactersEnd - interGlyphIndex;
- const float xPosition = position.x - glyph.xBearing + offset.x + ( isCurrentRightToLeft ? ( glyphAdvance * static_cast<float>( numberOfCharacters ) ) : 0.f );
+ const float xPosition = firstLine.alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x + ( isCurrentRightToLeft ? ( glyphAdvance * static_cast<float>( numberOfCharacters ) ) : 0.f );
mEventData->mDecorator->AddHighlight( xPosition,
- offset.y,
+ mScrollPosition.y,
xPosition + static_cast<float>( interGlyphIndex ) * glyphAdvance,
- offset.y + height );
+ mScrollPosition.y + height );
splitEndGlyph = false;
continue;
}
- const float xPosition = position.x - glyph.xBearing + offset.x;
+ const float xPosition = firstLine.alignmentOffset + position.x - glyph.xBearing + mScrollPosition.x;
mEventData->mDecorator->AddHighlight( xPosition,
- offset.y,
+ mScrollPosition.y,
xPosition + glyph.advance,
- offset.y + height );
+ mScrollPosition.y + height );
}
CursorInfo primaryCursorInfo;
GetCursorPosition( mEventData->mRightSelectionPosition,
secondaryCursorInfo );
- const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + offset;
- const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + offset;
+ const Vector2 primaryPosition = primaryCursorInfo.primaryPosition + mScrollPosition;
+ const Vector2 secondaryPosition = secondaryCursorInfo.primaryPosition + mScrollPosition;
mEventData->mDecorator->SetPosition( LEFT_SELECTION_HANDLE,
primaryPosition.x,
- primaryCursorInfo.lineOffset + offset.y,
+ primaryCursorInfo.lineOffset + mScrollPosition.y,
primaryCursorInfo.lineHeight );
mEventData->mDecorator->SetPosition( RIGHT_SELECTION_HANDLE,
secondaryPosition.x,
- secondaryCursorInfo.lineOffset + offset.y,
+ secondaryCursorInfo.lineOffset + mScrollPosition.y,
secondaryCursorInfo.lineHeight );
// Cursor to be positioned at end of selection so if selection interrupted and edit mode restarted the cursor will be at end of selection
}
}
- switch( mLayoutEngine.GetVerticalAlignment() )
- {
- case LayoutEngine::VERTICAL_ALIGN_TOP:
- {
- cursorInfo.primaryPosition.y = 0.f;
- break;
- }
- case LayoutEngine::VERTICAL_ALIGN_CENTER:
- {
- cursorInfo.primaryPosition.y = floorf( 0.5f * ( mVisualModel->mControlSize.height - cursorInfo.lineHeight ) );
- break;
- }
- case LayoutEngine::VERTICAL_ALIGN_BOTTOM:
- {
- cursorInfo.primaryPosition.y = mVisualModel->mControlSize.height - cursorInfo.lineHeight;
- break;
- }
- }
-
// Nothing else to do.
return;
}
return;
}
- const Vector2 offset = mEventData->mScrollPosition + ( IsShowingRealText() ? mAlignmentOffset : Vector2::ZERO );
- const Vector2 cursorPosition = cursorInfo.primaryPosition + offset;
+ const Vector2 cursorPosition = cursorInfo.primaryPosition + mScrollPosition;
// Sets the cursor position.
mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
// Sets the grab handle position.
mEventData->mDecorator->SetPosition( GRAB_HANDLE,
cursorPosition.x,
- cursorInfo.lineOffset + offset.y,
+ cursorInfo.lineOffset + mScrollPosition.y,
cursorInfo.lineHeight );
if( cursorInfo.isSecondaryCursor )
{
mEventData->mDecorator->SetPosition( SECONDARY_CURSOR,
- cursorInfo.secondaryPosition.x + offset.x,
- cursorInfo.secondaryPosition.y + offset.y,
+ cursorInfo.secondaryPosition.x + mScrollPosition.x,
+ cursorInfo.secondaryPosition.y + mScrollPosition.y,
cursorInfo.secondaryCursorHeight,
cursorInfo.lineHeight );
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + offset.x, cursorInfo.secondaryPosition.y + offset.y );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + mScrollPosition.x, cursorInfo.secondaryPosition.y + mScrollPosition.y );
}
// Set which cursors are active according the state.
return;
}
- const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset;
- const Vector2 cursorPosition = cursorInfo.primaryPosition + offset;
+ const Vector2 cursorPosition = cursorInfo.primaryPosition + mScrollPosition;
// Sets the handle's position.
mEventData->mDecorator->SetPosition( handleType,
cursorPosition.x,
- cursorInfo.lineOffset + offset.y,
+ cursorInfo.lineOffset + mScrollPosition.y,
cursorInfo.lineHeight );
// If selection handle at start of the text and other at end of the text then all text is selected.
void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize )
{
- // Clamp between -space & 0 (and the text alignment).
+ // Clamp between -space & 0.
if( actualSize.width > mVisualModel->mControlSize.width )
{
- const float space = ( actualSize.width - mVisualModel->mControlSize.width ) + mAlignmentOffset.x;
- mEventData->mScrollPosition.x = ( mEventData->mScrollPosition.x < -space ) ? -space : mEventData->mScrollPosition.x;
- mEventData->mScrollPosition.x = ( mEventData->mScrollPosition.x > -mAlignmentOffset.x ) ? -mAlignmentOffset.x : mEventData->mScrollPosition.x;
+ const float space = ( actualSize.width - mVisualModel->mControlSize.width );
+ mScrollPosition.x = ( mScrollPosition.x < -space ) ? -space : mScrollPosition.x;
+ mScrollPosition.x = ( mScrollPosition.x > 0.f ) ? 0.f : mScrollPosition.x;
mEventData->mDecoratorUpdated = true;
}
else
{
- mEventData->mScrollPosition.x = 0.f;
+ mScrollPosition.x = 0.f;
}
}
void Controller::Impl::ClampVerticalScroll( const Vector2& actualSize )
{
- // Clamp between -space & 0 (and the text alignment).
+ // Clamp between -space & 0.
if( actualSize.height > mVisualModel->mControlSize.height )
{
- const float space = ( actualSize.height - mVisualModel->mControlSize.height ) + mAlignmentOffset.y;
- mEventData->mScrollPosition.y = ( mEventData->mScrollPosition.y < -space ) ? -space : mEventData->mScrollPosition.y;
- mEventData->mScrollPosition.y = ( mEventData->mScrollPosition.y > -mAlignmentOffset.y ) ? -mAlignmentOffset.y : mEventData->mScrollPosition.y;
+ const float space = ( actualSize.height - mVisualModel->mControlSize.height );
+ mScrollPosition.y = ( mScrollPosition.y < -space ) ? -space : mScrollPosition.y;
+ mScrollPosition.y = ( mScrollPosition.y > 0.f ) ? 0.f : mScrollPosition.y;
mEventData->mDecoratorUpdated = true;
}
else
{
- mEventData->mScrollPosition.y = 0.f;
+ mScrollPosition.y = 0.f;
}
}
const float positionEnd = position.x + cursorWidth;
// Transform the position to decorator coords.
- const float alignment = IsShowingRealText() ? mAlignmentOffset.x : 0.f;
- const float offset = mEventData->mScrollPosition.x + alignment;
- const float decoratorPositionBegin = position.x + offset;
- const float decoratorPositionEnd = positionEnd + offset;
+ const float decoratorPositionBegin = position.x + mScrollPosition.x;
+ const float decoratorPositionEnd = positionEnd + mScrollPosition.x;
if( decoratorPositionBegin < 0.f )
{
- mEventData->mScrollPosition.x = -position.x - alignment;
+ mScrollPosition.x = -position.x;
}
else if( decoratorPositionEnd > mVisualModel->mControlSize.width )
{
- mEventData->mScrollPosition.x = mVisualModel->mControlSize.width - positionEnd - alignment;
+ mScrollPosition.x = mVisualModel->mControlSize.width - positionEnd;
}
}
const Vector2& currentCursorPosition = mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
// Calculate the offset to match the cursor position before the character was deleted.
- mEventData->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x - mAlignmentOffset.x;
+ mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x;
ClampHorizontalScroll( mVisualModel->GetLayoutSize() );
InputStyle mInputStyle; ///< The style to be set to the new inputed text.
- /**
- * 0,0 means that the top-left corner of the layout matches the top-left corner of the UI control.
- * Typically this will have a negative value with scrolling occurs.
- */
- Vector2 mScrollPosition; ///< The text is offset by this position when scrolling.
-
State mState; ///< Selection mode, edit mode etc.
CharacterIndex mPrimaryCursorPosition; ///< Index into logical model for primary cursor.
mLayoutEngine(),
mModifyEvents(),
mTextColor( Color::BLACK ),
- mAlignmentOffset(),
mTextUpdateInfo(),
mOperationsPending( NO_OPERATION ),
mMaximumNumberOfCharacters( 50u ),
LayoutEngine mLayoutEngine; ///< The layout engine.
Vector<ModifyEvent> mModifyEvents; ///< Temporary stores the text set until the next relayout.
Vector4 mTextColor; ///< The regular text color
- Vector2 mAlignmentOffset; ///< Vertical and horizontal offset of the whole text inside the control due to alignment.
+ /**
+ * 0,0 means that the top-left corner of the layout matches the top-left corner of the UI control.
+ * Typically this will have a negative value with scrolling occurs.
+ */
+ Vector2 mScrollPosition; ///< The text is offset by this position when scrolling.
TextUpdateInfo mTextUpdateInfo; ///< Info of the characters updated.
OperationsMask mOperationsPending; ///< Operations pending to be done to layout the text.
Length mMaximumNumberOfCharacters; ///< Maximum number of characters that can be inserted.
return mImpl->mAutoScrollDirectionRTL;
}
+float Controller::GetAutoScrollLineAlignment() const
+{
+ float offset = 0.f;
+
+ if( mImpl->mVisualModel &&
+ ( 0u != mImpl->mVisualModel->mLines.Count() ) )
+ {
+ offset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset;
+ }
+
+ return offset;
+}
+
void Controller::SetText( const std::string& text )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText\n" );
const Vector2& Controller::GetScrollPosition() const
{
- if( NULL != mImpl->mEventData )
- {
- return mImpl->mEventData->mScrollPosition;
- }
-
- return Vector2::ZERO;
-}
-
-const Vector2& Controller::GetAlignmentOffset() const
-{
- return mImpl->mAlignmentOffset;
+ return mImpl->mScrollPosition;
}
Vector3 Controller::GetNaturalSize()
// Whether the text control is editable
const bool isEditable = NULL != mImpl->mEventData;
- // Keep the current offset and alignment as it will be used to update the decorator's positions (if the size changes).
+ // Keep the current offset as it will be used to update the decorator's positions (if the size changes).
Vector2 offset;
if( newSize && isEditable )
{
- offset = mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition;
+ offset = mImpl->mScrollPosition;
}
- // After doing the text layout, the alignment offset to place the actor in the desired position can be calculated.
- CalculateTextAlignment( size );
+ if( !isEditable || !IsMultiLineEnabled() )
+ {
+ // After doing the text layout, the vertical offset to place the actor in the desired position can be calculated.
+ CalculateVerticalOffset( size );
+ }
if( isEditable )
{
mImpl->ClampHorizontalScroll( layoutSize );
// Update the decorator's positions is needed if there is a new size.
- mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition - offset );
+ mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mScrollPosition - offset );
}
// Move the cursor, grab handle etc.
if( NULL != mImpl->mEventData )
{
// Reset the scroll position.
- mImpl->mEventData->mScrollPosition = Vector2::ZERO;
+ mImpl->mScrollPosition = Vector2::ZERO;
mImpl->mEventData->mScrollAfterUpdatePosition = true;
}
}
return mImpl->mLayoutEngine.GetVerticalAlignment();
}
-void Controller::CalculateTextAlignment( const Size& controlSize )
+void Controller::CalculateVerticalOffset( const Size& controlSize )
{
Size layoutSize = mImpl->mVisualModel->GetLayoutSize();
layoutSize.height = mImpl->GetDefaultFontLineHeight();
}
- if( LayoutEngine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() )
- {
- // Get the direction of the first character.
- const CharacterDirection firstParagraphDirection = mImpl->mLogicalModel->GetCharacterDirection( 0u );
-
- // If the first paragraph is right to left swap ALIGN_BEGIN and ALIGN_END;
- LayoutEngine::HorizontalAlignment horizontalAlignment = mImpl->mLayoutEngine.GetHorizontalAlignment();
- if( firstParagraphDirection )
- {
- switch( horizontalAlignment )
- {
- case LayoutEngine::HORIZONTAL_ALIGN_BEGIN:
- {
- horizontalAlignment = LayoutEngine::HORIZONTAL_ALIGN_END;
- break;
- }
- case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
- {
- // Nothing to do.
- break;
- }
- case LayoutEngine::HORIZONTAL_ALIGN_END:
- {
- horizontalAlignment = LayoutEngine::HORIZONTAL_ALIGN_BEGIN;
- break;
- }
- }
- }
-
- switch( horizontalAlignment )
- {
- case LayoutEngine::HORIZONTAL_ALIGN_BEGIN:
- {
- mImpl->mAlignmentOffset.x = 0.f;
- break;
- }
- case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
- {
- mImpl->mAlignmentOffset.x = floorf( 0.5f * ( controlSize.width - layoutSize.width ) ); // try to avoid pixel alignment.
- break;
- }
- case LayoutEngine::HORIZONTAL_ALIGN_END:
- {
- mImpl->mAlignmentOffset.x = controlSize.width - layoutSize.width;
- break;
- }
- }
- }
-
- const LayoutEngine::VerticalAlignment verticalAlignment = mImpl->mLayoutEngine.GetVerticalAlignment();
- switch( verticalAlignment )
+ switch( mImpl->mLayoutEngine.GetVerticalAlignment() )
{
case LayoutEngine::VERTICAL_ALIGN_TOP:
{
- mImpl->mAlignmentOffset.y = 0.f;
+ mImpl->mScrollPosition.y = 0.f;
break;
}
case LayoutEngine::VERTICAL_ALIGN_CENTER:
{
- mImpl->mAlignmentOffset.y = floorf( 0.5f * ( controlSize.height - layoutSize.height ) ); // try to avoid pixel alignment.
+ mImpl->mScrollPosition.y = floorf( 0.5f * ( controlSize.height - layoutSize.height ) ); // try to avoid pixel alignment.
break;
}
case LayoutEngine::VERTICAL_ALIGN_BOTTOM:
{
- mImpl->mAlignmentOffset.y = controlSize.height - layoutSize.height;
+ mImpl->mScrollPosition.y = controlSize.height - layoutSize.height;
break;
}
}
CharacterDirection GetAutoScrollDirection() const;
/**
+ * @brief Get the alignment offset of the first line of text.
+ *
+ * @return The alignment offset.
+ */
+ float GetAutoScrollLineAlignment() const;
+
+ /**
* @brief Replaces any text previously set.
*
* @note This will be converted into UTF-32 when stored in the text model.
const Vector2& GetScrollPosition() const;
/**
- * @brief Query the alignment offset.
- *
- * @return The alignmnet offset.
- */
- const Vector2& GetAlignmentOffset() const;
-
- /**
* @copydoc Control::GetNaturalSize()
*/
Vector3 GetNaturalSize();
LayoutEngine::VerticalAlignment GetVerticalAlignment() const;
/**
- * @brief Calulates the alignment of the whole text inside the bounding box.
+ * @brief Calulates the vertical offset to align the text inside the bounding box.
*
* @param[in] size The size of the bounding box.
*/
- void CalculateTextAlignment( const Size& size );
+ void CalculateVerticalOffset( const Size& size );
/**
* @brief Return the layout engine.
CleanUp();
}
-void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, const Vector2 alignmentOffset )
+void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset )
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f,%f]\n",
- controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset.x, alignmentOffset.y );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
+ controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset );
FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888, Dali::Image::UNUSED );
Renderer renderer;
// Reposition camera to match alignment of target, RTL text has direction=true
if ( direction )
{
- mOffscreenCameraActor.SetX( alignmentOffset.x + offScreenSize.width*0.5f );
+ mOffscreenCameraActor.SetX( alignmentOffset + offScreenSize.width*0.5f );
}
else
{
* @param[in] alignmentOffset alignment of source text
*
*/
- void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, const Vector2 alignmentOffset );
+ void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset );
/**
* @brief Set the gap distance to elapse before the text wraps around