X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Ftext-view%2Ftext-view-impl.cpp;h=241bcaaa5af7839b15f453ba46bf7b2de3e7ba15;hp=8082ce8efa716e83222b042d2b50fce5436fe2a4;hb=c32e712ddb572650fe0766d7f10a9707db5b5c6b;hpb=e2e777d22421d671e2bc7bf81148f7b89a44e807 diff --git a/dali-toolkit/internal/controls/text-view/text-view-impl.cpp b/dali-toolkit/internal/controls/text-view/text-view-impl.cpp index 8082ce8..241bcaa 100644 --- a/dali-toolkit/internal/controls/text-view/text-view-impl.cpp +++ b/dali-toolkit/internal/controls/text-view/text-view-impl.cpp @@ -1,30 +1,37 @@ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ // CLASS HEADER -#include "text-view-impl.h" +#include + +// EXTERNAL INCLUDES +#include +#include +#include +#include // INTERNAL INCLUDES -#include "split-by-new-line-char-policies.h" -#include "split-by-word-policies.h" -#include "split-by-char-policies.h" -#include "text-view-processor.h" -#include "text-view-word-processor.h" -#include "relayout-utilities.h" -#include "text-view-processor-dbg.h" +#include +#include +#include +#include +#include +#include +#include namespace Dali { @@ -38,31 +45,36 @@ namespace Internal namespace { -const char* const PROPERTY_TEXT = "text"; -const char* const PROPERTY_MULTILINE_POLICY = "multiline-policy"; -const char* const PROPERTY_WIDTH_EXCEED_POLICY = "width-exceed-policy"; -const char* const PROPERTY_HEIGHT_EXCEED_POLICY = "height-exceed-policy"; -const char* const PROPERTY_LINE_JUSTIFICATION = "line-justification"; -const char* const PROPERTY_FADE_BOUNDARY_LEFT = "fade-boundary-left"; -const char* const PROPERTY_FADE_BOUNDARY_RIGHT = "fade-boundary-right"; -const char* const PROPERTY_FADE_BOUNDARY_TOP = "fade-boundary-top"; -const char* const PROPERTY_FADE_BOUNDARY_BOTTOM = "fade-boundary-bottom"; -const char* const PROPERTY_LINE_HEIGHT_OFFSET = "line-height-offset"; -const char* const PROPERTY_HORIZONTAL_ALIGNMENT = "horizontal-alignment"; -const char* const PROPERTY_VERTICAL_ALIGNMENT = "vertical-alignment"; +const char* MULTILINE_POLICY_NAME[] = {"SplitByNewLineChar", "SplitByWord", "SplitByChar"}; +const char* EXCEED_POLICY_NAME[] = {"Original", "Truncate", "Fade", "Split","ShrinkToFit","EllipsizeEnd"}; +const char* LINE_JUSTIFICATION_NAME[] = {"Left","Center","Right","Justified"}; // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k. const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f; -//Type Registration +// Type Registration BaseHandle Create() { return Toolkit::TextView::New(); } -TypeRegistration typeRegistration( typeid(Toolkit::TextView), typeid(Toolkit::Control), Create ); +// Setup properties, signals and actions using the type-registry. +DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextView, Toolkit::Control, Create ); + +DALI_PROPERTY_REGISTRATION( TextView, "markup-enabled", BOOLEAN, MARKUP_ENABLED ) +DALI_PROPERTY_REGISTRATION( TextView, "text", STRING, TEXT ) +DALI_PROPERTY_REGISTRATION( TextView, "multiline-policy", STRING, MULTILINE_POLICY ) +DALI_PROPERTY_REGISTRATION( TextView, "width-exceed-policy", STRING, WIDTH_EXCEED_POLICY ) +DALI_PROPERTY_REGISTRATION( TextView, "height-exceed-policy", STRING, HEIGHT_EXCEED_POLICY ) +DALI_PROPERTY_REGISTRATION( TextView, "line-justification", STRING, LINE_JUSTIFICATION ) +DALI_PROPERTY_REGISTRATION( TextView, "fade-boundary", VECTOR4, FADE_BOUNDARY ) +DALI_PROPERTY_REGISTRATION( TextView, "line-height-offset", FLOAT, LINE_HEIGHT_OFFSET ) +DALI_PROPERTY_REGISTRATION( TextView, "horizontal-alignment", STRING, HORIZONTAL_ALIGNMENT ) +DALI_PROPERTY_REGISTRATION( TextView, "vertical-alignment", STRING, VERTICAL_ALIGNMENT ) -SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal ); +DALI_SIGNAL_REGISTRATION( TextView, "scrolled", SIGNAL_TEXT_SCROLLED ) + +DALI_TYPE_REGISTRATION_END() /** * Whether the text-view-processor operation sets, inserts, replaces, removes text. @@ -108,9 +120,10 @@ bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMeta TextView::TextViewProcessorMetadata::TextViewProcessorMetadata() : mType( TextView::TextSet ), - mPosition( 0 ), - mNumberOfCharacters( 0 ), - mText() + mPosition( 0u ), + mNumberOfCharacters( 0u ), + mText(), + mStyleMask(TextStyle::NONE) { } @@ -126,8 +139,8 @@ Toolkit::TextView TextView::New() // This can only be done after the CustomActor connection has been made... textView->Initialize(); - // Enables by default the offscreen rendering. - textView->SetSnapshotModeEnabled( false ); /// @note Temporary disabled due to some issues with text quality and glyph loading. + // Disables by default the offscreen rendering. + textView->SetSnapshotModeEnabled( false ); return handle; } @@ -178,28 +191,43 @@ void TextView::InsertTextAt( std::size_t position, const std::string& text ) InsertTextAt( position, styledText ); } -void TextView::InsertTextAt( const std::size_t position, const MarkupProcessor::StyledTextArray& text ) +void TextView::InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text ) { - // Creates metadata with the Insert operation. - TextViewProcessorMetadata metadata; - metadata.mType = TextView::TextInserted; - metadata.mPosition = position; - metadata.mText = text; + std::string textStr; + MarkupProcessor::GetPlainString( text, textStr ); - // Store metadata. - mTextViewProcessorOperations.push_back( metadata ); + if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) || + TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) ) + { + // Temporary fix. Creates the whole layout if there is rtl text. - // Updates current styled text. - mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() ); + MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText; + textToSet.insert( textToSet.begin() + position, text.begin(), text.end() ); + SetText( textToSet ); + } + else + { + // Creates metadata with the Insert operation. + TextViewProcessorMetadata metadata; + metadata.mType = TextView::TextInserted; + metadata.mPosition = position; + metadata.mText = text; - // Request to be relaid out - RelayoutRequest(); + // Store metadata. + mTextViewProcessorOperations.push_back( metadata ); - // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. - mRelayoutOperations = RELAYOUT_ALL; + // Updates current styled text. + mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() ); + + // Request to be relaid out + RelayoutRequest(); + + // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. + mRelayoutOperations = RELAYOUT_ALL; + } } -void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const std::string& text ) +void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text ) { // Creates a styled text with the markup or plain string. MarkupProcessor::StyledTextArray styledText; @@ -209,51 +237,86 @@ void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t ReplaceTextFromTo( position, numberOfCharacters, styledText ); } -void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text ) +void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text ) { - // Creates metadata with the Insert operation. - TextViewProcessorMetadata metadata; - metadata.mType = TextView::TextReplaced; - metadata.mPosition = position; - metadata.mNumberOfCharacters = numberOfCharacters; - metadata.mText = text; + std::string textStr; + MarkupProcessor::GetPlainString( text, textStr ); - // Store metadata. - mTextViewProcessorOperations.push_back( metadata ); + if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) || + TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) ) + { + // Temporary fix. Creates the whole layout if there is rtl text. - // Updates current styled text. - MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; - mCurrentStyledText.erase( it, it + numberOfCharacters ); - it = mCurrentStyledText.begin() + position; - mCurrentStyledText.insert( it, text.begin(), text.end() ); + // Updates current styled text. + MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText; - // Request to be relaid out - RelayoutRequest(); + MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position; + textToSet.erase( it, it + numberOfCharacters ); + it = textToSet.begin() + position; + textToSet.insert( it, text.begin(), text.end() ); - // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. - mRelayoutOperations = RELAYOUT_ALL; + SetText( textToSet ); + } + else + { + // Creates metadata with the Insert operation. + TextViewProcessorMetadata metadata; + metadata.mType = TextView::TextReplaced; + metadata.mPosition = position; + metadata.mNumberOfCharacters = numberOfCharacters; + metadata.mText = text; + + // Store metadata. + mTextViewProcessorOperations.push_back( metadata ); + + // Updates current styled text. + MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; + mCurrentStyledText.erase( it, it + numberOfCharacters ); + it = mCurrentStyledText.begin() + position; + mCurrentStyledText.insert( it, text.begin(), text.end() ); + + // Request to be relaid out + RelayoutRequest(); + + // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. + mRelayoutOperations = RELAYOUT_ALL; + } } -void TextView::RemoveTextFrom( const std::size_t position, const std::size_t numberOfCharacters ) +void TextView::RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters ) { - // Creates metadata with the Remove operation. - TextViewProcessorMetadata metadata; - metadata.mType = TextView::TextRemoved; - metadata.mPosition = position; - metadata.mNumberOfCharacters = numberOfCharacters; + if( TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) ) + { + // Temporary fix. Creates the whole layout if there is rtl text. - // Store metadata. - mTextViewProcessorOperations.push_back( metadata ); + // Updates current styled text. + MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText; + MarkupProcessor::StyledTextArray::iterator it = textToSet.begin() + position; + textToSet.erase( it, it + numberOfCharacters ); - // Updates current styled text. - MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; - mCurrentStyledText.erase( it, it + numberOfCharacters ); + SetText( textToSet ); + } + else + { + // Creates metadata with the Remove operation. + TextViewProcessorMetadata metadata; + metadata.mType = TextView::TextRemoved; + metadata.mPosition = position; + metadata.mNumberOfCharacters = numberOfCharacters; - // Request to be relaid out - RelayoutRequest(); + // Store metadata. + mTextViewProcessorOperations.push_back( metadata ); - // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. - mRelayoutOperations = RELAYOUT_ALL; + // Updates current styled text. + MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position; + mCurrentStyledText.erase( it, it + numberOfCharacters ); + + // Request to be relaid out + RelayoutRequest(); + + // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values. + mRelayoutOperations = RELAYOUT_ALL; + } } std::string TextView::GetText() const @@ -270,7 +333,7 @@ std::string TextView::GetText() const return text; } -void TextView::SetLineHeightOffset( const PointSize offset ) +void TextView::SetLineHeightOffset( PointSize offset ) { if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 ) { @@ -298,8 +361,7 @@ void TextView::SetLineHeightOffset( const PointSize offset ) RELAYOUT_ALIGNMENT | RELAYOUT_VISIBILITY | RELAYOUT_TEXT_ACTOR_UPDATE | - RELAYOUT_INSERT_TO_TEXT_VIEW | - RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); + RELAYOUT_INSERT_TO_TEXT_VIEW ); } } } @@ -309,7 +371,7 @@ PointSize TextView::GetLineHeightOffset() const return PointSize( mLayoutParameters.mLineHeightOffset ); } -void TextView::SetStyleToCurrentText( const TextStyle& style, const TextStyle::Mask mask ) +void TextView::SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask ) { if( !mCurrentStyledText.empty() ) { @@ -365,14 +427,18 @@ void TextView::SetStyleToCurrentText( const TextStyle& style, const TextStyle::M } // Sets the new style to the ellipsize text - if( !mLayoutParameters.mEllipsizeText.empty() ) + // TODO: fix this as a call to SetEllipsizeText will trigger the creation of new text actors. + if( 0u < mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Count() ) { - for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it ) + for( Vector::Iterator it = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Begin(), + endIt = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.End(); + it != endIt; + ++it ) { - (*it).mStyle.Copy( style, mask ); + (*it)->Copy( style, mask ); } - SetEllipsizeText( mLayoutParameters.mEllipsizeText ); + SetEllipsizeText( mRelayoutData.mTextLayoutInfo.mEllipsisText, mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles ); } } @@ -464,8 +530,7 @@ void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy ) RELAYOUT_ALIGNMENT | RELAYOUT_VISIBILITY | RELAYOUT_TEXT_ACTOR_UPDATE | - RELAYOUT_INSERT_TO_TEXT_VIEW | - RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); + RELAYOUT_INSERT_TO_TEXT_VIEW ); } } } @@ -492,8 +557,7 @@ void TextView::SetLineJustification( Toolkit::TextView::LineJustification justif RELAYOUT_ALIGNMENT | RELAYOUT_VISIBILITY | RELAYOUT_TEXT_ACTOR_UPDATE | - RELAYOUT_INSERT_TO_TEXT_VIEW | - RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); + RELAYOUT_INSERT_TO_TEXT_VIEW ); } } } @@ -521,8 +585,7 @@ void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBound RELAYOUT_REMOVE_TEXT_ACTORS | RELAYOUT_VISIBILITY | RELAYOUT_TEXT_ACTOR_UPDATE | - RELAYOUT_INSERT_TO_TEXT_VIEW | - RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); + RELAYOUT_INSERT_TO_TEXT_VIEW ); } } } @@ -538,17 +601,35 @@ void TextView::SetEllipsizeText( const std::string& ellipsizeText ) MarkupProcessor::StyledTextArray styledText; MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() ); + // Creates the ellipsis layout info and sets the text and styles. SetEllipsizeText( styledText ); } void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText ) { - mLayoutParameters.mEllipsizeText = ellipsizeText; + // Converts the styled text array into a Text and a vector of TextStyles. + Text text; + Vector styles; + for( MarkupProcessor::StyledTextArray::const_iterator it = ellipsizeText.begin(), endIt = ellipsizeText.end(); it != endIt; ++it ) + { + const MarkupProcessor::StyledText& styledText( *it ); - mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo(); + text.Append( styledText.mText ); + styles.PushBack( new TextStyle( styledText.mStyle ) ); + } - TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText, - mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo ); + // Creates the ellipsis layout info and sets the text and styles. + SetEllipsizeText( text, styles ); +} + +void TextView::SetEllipsizeText( const Text& ellipsizeText, const Vector& ellipsizeStyles ) +{ + // Sets the text and styles for the ellipsis text. + mRelayoutData.mTextLayoutInfo.mEllipsisText = ellipsizeText; + mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles = ellipsizeStyles; + + // Creates the ellipsis layout info. + CreateEllipsizeLayout(); // Request to be relaid out RelayoutRequest(); @@ -558,13 +639,7 @@ void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsi std::string TextView::GetEllipsizeText() const { - std::string text; - for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it ) - { - text.append( (*it).mText.GetText() ); - } - - return text; + return mRelayoutData.mTextLayoutInfo.mEllipsisText.GetText(); } void TextView::GetTextLayoutInfo() @@ -622,9 +697,7 @@ void TextView::GetTextLayoutInfo() if( hasGlyphActors ) { mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW ); - mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); } - } } } @@ -698,11 +771,13 @@ void TextView::SetSnapshotModeEnabled( bool enable ) mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER ); mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER ); + mOffscreenImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA, + BlendingFactor::ONE, BlendingFactor::ONE ); Actor self = Self(); self.Add( mOffscreenRootActor ); self.Add( mOffscreenImageActor ); - mOffscreenImageActor.SetScale(Vector3(1.f, -1.f, 1.f)); + mOffscreenImageActor.SetScale( Vector3( 1.f, -1.f, 1.f ) ); } else { @@ -726,8 +801,7 @@ void TextView::SetSnapshotModeEnabled( bool enable ) mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_REMOVE_TEXT_ACTORS | RELAYOUT_TEXT_ACTOR_UPDATE | - RELAYOUT_INSERT_TO_TEXT_VIEW | - RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); + RELAYOUT_INSERT_TO_TEXT_VIEW ); } RelayoutRequest(); } @@ -748,7 +822,7 @@ bool TextView::IsMarkupProcessingEnabled() const return mMarkUpEnabled; } -void TextView::SetScrollEnabled( const bool enable ) +void TextView::SetScrollEnabled( bool enable ) { if( enable != mVisualParameters.mScrollEnabled ) { @@ -819,9 +893,9 @@ bool TextView::IsScrollPositionTrimmed() const return mVisualParameters.mScrollPositionTrimmed; } -Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal() +Toolkit::TextView::ScrolledSignalType& TextView::ScrolledSignal() { - return mScrolledSignalV2; + return mScrolledSignal; } bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) @@ -829,9 +903,9 @@ bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* Dali::BaseHandle handle( object ); bool connected( true ); - Toolkit::TextView textView = Toolkit::TextView::DownCast(handle); + Toolkit::TextView textView = Toolkit::TextView::DownCast( handle ); - if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName ) + if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_SCROLLED ) ) { textView.ScrolledSignal().Connect( tracker, functor ); } @@ -846,36 +920,36 @@ bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* TextView::LayoutParameters::LayoutParameters() : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ), + mExceedPolicy( TextView::Original ), mWidthExceedPolicy( Toolkit::TextView::Original ), mHeightExceedPolicy( Toolkit::TextView::Original ), mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ), mVerticalAlignment( Toolkit::Alignment::VerticalCenter ), mLineJustification( Toolkit::TextView::Left ), mLineHeightOffset( 0.f ), - mEllipsizeText(), mMarkUpEnabled( false ) { - // Sets ellipsize text - MarkupProcessor::StyledTextArray styledEllipsize; - MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false ); } -TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::MultilinePolicy multilinePolicy, - const Toolkit::TextView::ExceedPolicy widthExceedPolicy, - const Toolkit::TextView::ExceedPolicy heightExceedPolicy, - const Toolkit::Alignment::Type alignmentType, - const Toolkit::TextView::LineJustification lineJustification, - const float lineHeightOffset, - const std::string& ellipsizeText, - const bool markUpEnabled ) +TextView::LayoutParameters::~LayoutParameters() +{ +} + +TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy, + Toolkit::TextView::ExceedPolicy widthExceedPolicy, + Toolkit::TextView::ExceedPolicy heightExceedPolicy, + Toolkit::Alignment::Type alignmentType, + Toolkit::TextView::LineJustification lineJustification, + float lineHeightOffset, + bool markUpEnabled ) : mMultilinePolicy( multilinePolicy ), + mExceedPolicy( TextView::Original ), mWidthExceedPolicy( widthExceedPolicy ), mHeightExceedPolicy( heightExceedPolicy ), mHorizontalAlignment(), mVerticalAlignment(), mLineJustification( lineJustification ), mLineHeightOffset( lineHeightOffset ), - mEllipsizeText(), mMarkUpEnabled( markUpEnabled ) { // Sets alignment @@ -888,21 +962,17 @@ TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::Multiline mHorizontalAlignment = horizontalAlignment; mVerticalAlignment = verticalAlignment; - - // Sets ellipsize text - MarkupProcessor::StyledTextArray styledEllipsize; - MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled ); } TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters ) : mMultilinePolicy( layoutParameters.mMultilinePolicy ), + mExceedPolicy( TextView::Original ), mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ), mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ), mHorizontalAlignment( layoutParameters.mHorizontalAlignment ), mVerticalAlignment( layoutParameters.mVerticalAlignment ), mLineJustification( layoutParameters.mLineJustification ), mLineHeightOffset( layoutParameters.mLineHeightOffset ), - mEllipsizeText( layoutParameters.mEllipsizeText ), mMarkUpEnabled( layoutParameters.mMarkUpEnabled ) { } @@ -916,7 +986,6 @@ TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextVie mVerticalAlignment = layoutParameters.mVerticalAlignment; mLineJustification = layoutParameters.mLineJustification; mLineHeightOffset = layoutParameters.mLineHeightOffset; - mEllipsizeText = layoutParameters.mEllipsizeText; mMarkUpEnabled = layoutParameters.mMarkUpEnabled; return *this; @@ -996,7 +1065,7 @@ TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::Relay } TextView::TextView() -: ControlImpl( false ), // doesn't require touch events +: Control( REQUIRES_STYLE_CHANGE_SIGNALS ), mCurrentStyledText(), mTextViewProcessorOperations(), mLayoutParameters( Toolkit::TextView::SplitByNewLineChar, @@ -1005,7 +1074,6 @@ TextView::TextView() static_cast( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ), Toolkit::TextView::Left, PointSize( 0.f ), - std::string( "..." ), false ), mVisualParameters(), mRelayoutData(), @@ -1021,8 +1089,8 @@ TextView::TextView() mPreviousSnapshotModeEnabled( false ), mMarkUpEnabled( false ) { - TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText, - mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo ); + // Creates the ellipsis layout info. + CreateEllipsizeLayout(); } TextView::~TextView() @@ -1051,7 +1119,6 @@ Vector3 TextView::GetNaturalSize() mRelayoutData.mGlyphActors.clear(); mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW ); - mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); } PerformTextViewProcessorOperations(); @@ -1112,7 +1179,6 @@ float TextView::GetHeightForWidth( float width ) if( hasGlyphActors ) { mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW ); - mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); } if( differentWidth || hasGlyphActors ) @@ -1130,83 +1196,16 @@ float TextView::GetWidthForHeight( float height ) return GetNaturalSize().width; } -void TextView::OnPropertySet( Property::Index index, Property::Value propertyValue ) -{ - if( index == mPropertyText ) - { - SetText(propertyValue.Get()); - } - else if( index == mPropertyMultilinePolicy ) - { - OnMultilinePolicyPropertySet(propertyValue); - } - else if( index == mPropertyWidthExceedPolicy ) - { - OnWidthExceedPolicyPropertySet(propertyValue); - } - else if( index == mPropertyHeightExceedPolicy ) - { - OnHeightExceedPolicyPropertySet(propertyValue); - } - else if( index == mPropertyLineJustification ) - { - OnLineJustificationPropertySet(propertyValue); - } - else if( ( index == mPropertyFadeBoundaryLeft ) || - ( index == mPropertyFadeBoundaryRight ) || - ( index == mPropertyFadeBoundaryTop ) || - ( index == mPropertyFadeBoundaryBottom ) ) - { - OnFadeBoundaryPropertySet( index, propertyValue ); - } - else if( index == mPropertyLineHeightOffset ) - { - Dali::PointSize pointSize( propertyValue.Get() ); - SetLineHeightOffset(pointSize); - } - else if ( ( index == mPropertyHorizontalAlignment ) || - ( index == mPropertyVerticalAlignment ) ) - { - OnAlignmentPropertySet( index, propertyValue ); - } -} void TextView::OnInitialize() { - Actor self = Self(); - - mPropertyText = self.RegisterProperty( PROPERTY_TEXT, "", Property::READ_WRITE ); - - mPropertyMultilinePolicy = self.RegisterProperty( PROPERTY_MULTILINE_POLICY, "SplitByNewLineChar", Property::READ_WRITE ); - - mPropertyWidthExceedPolicy = self.RegisterProperty( PROPERTY_WIDTH_EXCEED_POLICY, "Original", Property::READ_WRITE ); - - mPropertyHeightExceedPolicy = self.RegisterProperty( PROPERTY_HEIGHT_EXCEED_POLICY, "Original", Property::READ_WRITE ); - - mPropertyLineJustification = self.RegisterProperty( PROPERTY_LINE_JUSTIFICATION, "Left", Property::READ_WRITE ); - - mPropertyFadeBoundaryLeft = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_LEFT, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyFadeBoundaryRight = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_RIGHT, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyFadeBoundaryTop = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_TOP, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyFadeBoundaryBottom = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_BOTTOM, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyLineHeightOffset = self.RegisterProperty( PROPERTY_LINE_HEIGHT_OFFSET, 0.0f, Property::READ_WRITE ); - - mPropertyHorizontalAlignment = self.RegisterProperty( PROPERTY_HORIZONTAL_ALIGNMENT, "HorizontalCenter", Property::READ_WRITE ); - - mPropertyVerticalAlignment = self.RegisterProperty( PROPERTY_VERTICAL_ALIGNMENT, "VerticalCenter", Property::READ_WRITE ); - } -void TextView::OnStyleChange( StyleChange change ) +void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange ) { - mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo(); - TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText, - mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo ); + // Creates the ellipsis layout info. + CreateEllipsizeLayout(); SetText( mCurrentStyledText ); } @@ -1223,7 +1222,7 @@ void TextView::OnControlSizeSet( const Vector3& size ) } } -void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container ) +void TextView::OnRelayout( const Vector2& size, ActorSizeContainer& container ) { if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) ) { @@ -1242,8 +1241,18 @@ void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container ) RELAYOUT_ALIGNMENT | RELAYOUT_VISIBILITY | RELAYOUT_TEXT_ACTOR_UPDATE | - RELAYOUT_INSERT_TO_TEXT_VIEW | - RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); + RELAYOUT_INSERT_TO_TEXT_VIEW ); + } + } + + if( ( Toolkit::TextView::Fade == mLayoutParameters.mWidthExceedPolicy ) || + ( Toolkit::TextView::Fade == mLayoutParameters.mHeightExceedPolicy ) ) + { + if( mRelayoutOperations & RELAYOUT_ALIGNMENT ) + { + // If the text of the alignment changes and a fade exceed policy is set, + // some characters may need new TextActor. + mRelayoutOperations = RELAYOUT_ALL; } } @@ -1351,9 +1360,9 @@ void TextView::OptimizeTextViewProcessorOperations() { bool optimizationDone = false; - if( it + 1 != endIt ) + if( it + 1u != endIt ) { - const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) ); + const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1u ) ); if( TextView::TextInserted == nextRelayoutMetadata.mType ) { if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition ) @@ -1388,7 +1397,7 @@ void TextView::OptimizeTextViewProcessorOperations() mTextViewProcessorOperations = textViewProcessorOperations; } -void TextView::DoRelayOut( const Size& textViewSize, const RelayoutOperationMask relayoutOperationMask ) +void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask ) { // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures. if( !mTextViewProcessorOperations.empty() ) @@ -1659,7 +1668,7 @@ void TextView::DestroyOffscreenRenderingResources() } } -void TextView::OnTextPan( Actor actor, PanGesture gesture ) +void TextView::OnTextPan( Actor actor, const PanGesture& gesture ) { if( 1u == gesture.numberOfTouches ) { @@ -1777,7 +1786,7 @@ void TextView::DoSetScrollPosition( const Vector2& position ) // Emit the signal. Toolkit::TextView handle( GetOwner() ); - mScrolledSignalV2.Emit( handle, delta ); + mScrolledSignal.Emit( handle, delta ); } void TextView::CombineExceedPolicies() @@ -1831,6 +1840,11 @@ void TextView::CombineExceedPolicies() mLayoutParameters.mExceedPolicy = SplitShrink; break; } + case Toolkit::TextView::EllipsizeEnd: + { + mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd; + break; + } default: { DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" ); @@ -1931,6 +1945,34 @@ Actor TextView::GetRootActor() const return rootActor; } +void TextView::CreateEllipsizeLayout() +{ + // Creates the ellipsis layout info for the ellipsis text and styles. + mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo(); + mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.resize( mRelayoutData.mTextLayoutInfo.mEllipsisText.GetLength(), TextViewProcessor::CharacterLayoutInfo() ); + TextViewProcessor::CreateWordTextInfo( mRelayoutData.mTextLayoutInfo.mEllipsisText, + mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles, + mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo ); +} + +void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue ) +{ + bool newValue( propertyValue.Get() ); + if( newValue != IsMarkupProcessingEnabled() ) + { + SetMarkupProcessingEnabled( newValue ); + if( newValue ) + { + // If markup processing has been enabled, Ensure current text is reprocessed. + const std::string& currentText( GetText() ); + if( ! currentText.empty() ) + { + SetText( currentText ); + } + } + } +} + void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue ) { std::string policyName( propertyValue.Get() ); @@ -1959,10 +2001,6 @@ void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue ) { SetWidthExceedPolicy(Toolkit::TextView::Original); } - else if(policyName == "Truncate") - { - SetWidthExceedPolicy(Toolkit::TextView::Truncate); - } else if(policyName == "Fade") { SetWidthExceedPolicy(Toolkit::TextView::Fade); @@ -1992,10 +2030,6 @@ void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue ) { SetHeightExceedPolicy(Toolkit::TextView::Original); } - else if(policyName == "Truncate") - { - SetHeightExceedPolicy(Toolkit::TextView::Truncate); - } else if(policyName == "Fade") { SetHeightExceedPolicy(Toolkit::TextView::Fade); @@ -2039,37 +2073,25 @@ void TextView::OnLineJustificationPropertySet( Property::Value propertyValue ) } } -void TextView::OnFadeBoundaryPropertySet( Property::Index propertyIndex, Property::Value propertyValue ) +void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue ) { - PixelSize boundary( propertyValue.Get() ); + Vector4 value( propertyValue.Get() ); + DALI_ASSERT_ALWAYS( ( value.x >= 0.f ) && ( value.y >= 0.f ) && ( value.z >= 0.f ) && ( value.w >= 0.f ) + && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " ); - if ( propertyIndex == mPropertyFadeBoundaryLeft ) - { - mVisualParameters.mFadeBoundary.mLeft = boundary; - } - else if ( propertyIndex == mPropertyFadeBoundaryRight ) - { - mVisualParameters.mFadeBoundary.mRight = boundary; - } - else if ( propertyIndex == mPropertyFadeBoundaryTop ) - { - mVisualParameters.mFadeBoundary.mTop = boundary; - } - else if ( propertyIndex == mPropertyFadeBoundaryBottom ) - { - mVisualParameters.mFadeBoundary.mBottom = boundary; - } - else - { - DALI_ASSERT_ALWAYS( !"TextView::OnFadeBoundaryPropertySet(). Invalid Property value." ); - } + Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast( value.x ) ), + PixelSize( static_cast( value.y ) ), + PixelSize( static_cast( value.z ) ), + PixelSize( static_cast( value.w ) ) ); + + SetFadeBoundary( fadeBoundary ); } void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue ) { std::string value( propertyValue.Get() ); - if( propertyIndex == mPropertyHorizontalAlignment ) + if( propertyIndex == Toolkit::TextView::Property::HORIZONTAL_ALIGNMENT ) { if(value == "HorizontalLeft") { @@ -2088,7 +2110,7 @@ void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property:: DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." ); } } - else if( propertyIndex == mPropertyVerticalAlignment ) + else if( propertyIndex == Toolkit::TextView::Property::VERTICAL_ALIGNMENT ) { if( value == "VerticalTop" ) { @@ -2107,6 +2129,187 @@ void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property:: DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." ); } } + + RelayoutRequest(); + + // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values. + if( RELAYOUT_ALL != mRelayoutOperations ) + { + mRelayoutOperations = static_cast( mRelayoutOperations | + RELAYOUT_TEXT_ACTOR_UPDATE | + RELAYOUT_ALIGNMENT | + RELAYOUT_VISIBILITY ); + } +} + +std::string TextView::OnHorizontalAlignmentPropertyGet() +{ + if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft ) + { + return "HorizontalLeft"; + } + else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter ) + { + return "HorizontalCenter"; + } + else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight ) + { + return "HorizontalRight"; + } + else + { + DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." ); + } +} + +std::string TextView::OnVerticalAlignmentPropertyGet() +{ + if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop ) + { + return "VerticalTop"; + } + else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter ) + { + return "VerticalCenter"; + } + else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom ) + { + return "VerticalBottom"; + } + else + { + DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." ); + } +} + +void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +{ + Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) ); + + if( textView ) + { + TextView& textViewImpl( GetImpl( textView ) ); + switch( index ) + { + case Toolkit::TextView::Property::MARKUP_ENABLED: + { + textViewImpl.OnMarkupEnabledPeopertySet( value ); + break; + } + case Toolkit::TextView::Property::TEXT: + { + textViewImpl.SetText( value.Get() ); + break; + } + case Toolkit::TextView::Property::MULTILINE_POLICY: + { + textViewImpl.OnMultilinePolicyPropertySet( value ); + break; + } + case Toolkit::TextView::Property::WIDTH_EXCEED_POLICY: + { + textViewImpl.OnWidthExceedPolicyPropertySet( value ); + break; + } + case Toolkit::TextView::Property::HEIGHT_EXCEED_POLICY: + { + textViewImpl.OnHeightExceedPolicyPropertySet( value ); + break; + } + case Toolkit::TextView::Property::LINE_JUSTIFICATION: + { + textViewImpl.OnLineJustificationPropertySet( value ); + break; + } + case Toolkit::TextView::Property::FADE_BOUNDARY: + { + textViewImpl.OnFadeBoundaryPropertySet( value ); + break; + } + case Toolkit::TextView::Property::LINE_HEIGHT_OFFSET: + { + Dali::PointSize pointSize( value.Get() ); + textViewImpl.SetLineHeightOffset(pointSize); + break; + } + case Toolkit::TextView::Property::HORIZONTAL_ALIGNMENT: + case Toolkit::TextView::Property::VERTICAL_ALIGNMENT: + { + textViewImpl.OnAlignmentPropertySet( index, value ); + break; + } + } + } +} + +Property::Value TextView::GetProperty( BaseObject* object, Property::Index index ) +{ + Property::Value value; + + Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) ); + + if( textView ) + { + TextView& textViewImpl( GetImpl( textView ) ); + switch( index ) + { + case Toolkit::TextView::Property::MARKUP_ENABLED: + { + value = textViewImpl.IsMarkupProcessingEnabled(); + break; + } + case Toolkit::TextView::Property::TEXT: + { + value = textViewImpl.GetText(); + break; + } + case Toolkit::TextView::Property::MULTILINE_POLICY: + { + value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ]; + break; + } + case Toolkit::TextView::Property::WIDTH_EXCEED_POLICY: + { + value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ]; + break; + } + case Toolkit::TextView::Property::HEIGHT_EXCEED_POLICY: + { + value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ]; + break; + } + case Toolkit::TextView::Property::LINE_JUSTIFICATION: + { + value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ]; + break; + } + case Toolkit::TextView::Property::FADE_BOUNDARY: + { + Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary(); + value = Vector4( static_cast( boundary.mLeft.value ), + static_cast( boundary.mRight.value ), + static_cast( boundary.mTop.value ), + static_cast( boundary.mBottom.value ) ); + break; + } + case Toolkit::TextView::Property::LINE_HEIGHT_OFFSET: + { + value = textViewImpl.GetLineHeightOffset().value; + break; + } + case Toolkit::TextView::Property::HORIZONTAL_ALIGNMENT: + { + value = textViewImpl.OnHorizontalAlignmentPropertyGet(); + break; + } + case Toolkit::TextView::Property::VERTICAL_ALIGNMENT: + { + value = textViewImpl.OnVerticalAlignmentPropertyGet(); + break; + } + } + } + return value; } } // namespace Internal