X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Ftext-view%2Ftext-view-impl.cpp;h=4278d4bb3a4679e7aa2adcb26af3e4fde3b71114;hb=22e89375677d1fe737d5472e21ab681f2f3e4ca7;hp=add65d2a37fdaf52ece2e1b726047b8b8a8ed3b3;hpb=e2eda444afbe82e9591fe198eef339227f90a616;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git 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 add65d2..4278d4b 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,18 +45,36 @@ namespace Internal namespace { +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 ) + +DALI_SIGNAL_REGISTRATION( TextView, "scrolled", SIGNAL_TEXT_SCROLLED ) -SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal ); +DALI_TYPE_REGISTRATION_END() /** * Whether the text-view-processor operation sets, inserts, replaces, removes text. @@ -95,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) { } @@ -113,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; } @@ -123,7 +149,7 @@ void TextView::SetText( const std::string& text ) { // Creates a styled text with the markup or plain string. MarkupProcessor::StyledTextArray styledText; - MarkupProcessor::GetStyledTextArray( text, styledText ); + MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() ); // Calls SetText() with the styled text array. SetText( styledText ); @@ -159,88 +185,138 @@ void TextView::InsertTextAt( std::size_t position, const std::string& text ) { // Creates a styled text with the markup or plain string. MarkupProcessor::StyledTextArray styledText; - MarkupProcessor::GetStyledTextArray( text, styledText ); + MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() ); // Calls InsertTextAt() with the styled text array. 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; - MarkupProcessor::GetStyledTextArray( text, styledText ); + MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() ); // Calls ReplaceTextFromTo() with the styled text array. 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 @@ -257,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 ) { @@ -285,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 ); } } } @@ -296,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() ) { @@ -352,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 ); } } @@ -451,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 ); } } } @@ -479,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 ); } } } @@ -508,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 ); } } } @@ -523,19 +599,37 @@ void TextView::SetEllipsizeText( const std::string& ellipsizeText ) { // Creates a styled text with the markup or plain string. MarkupProcessor::StyledTextArray styledText; - MarkupProcessor::GetStyledTextArray( ellipsizeText, 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(); @@ -545,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() @@ -578,8 +666,8 @@ void TextView::GetTextLayoutInfo() if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) && ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) ) { - // Check if the text-view has text-actors. - const bool hasTextActors = !mRelayoutData.mTextActors.empty(); + // Check if the text-view has glyph-actors. + const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty(); RelayoutOperationMask mask = NO_RELAYOUT; if( relayoutSizeAndPositionNeeded ) @@ -595,23 +683,21 @@ void TextView::GetTextLayoutInfo() mask = static_cast( mask | RELAYOUT_VISIBILITY ); } - if( hasTextActors ) + if( hasGlyphActors ) { - // Remove text-actors from the text-view as some text-operation like CreateTextInfo() + // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo() // add them to the text-actor cache. - TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors ); - mRelayoutData.mTextActors.clear(); + TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors ); + mRelayoutData.mGlyphActors.clear(); } - // Relays-out but doesn't add text-actors to the text-view. + // Relays-out but doesn't add glyph-actors to the text-view. DoRelayOut( textViewSize.GetVectorXY(), mask ); - if( hasTextActors ) + if( hasGlyphActors ) { mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW ); - mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); } - } } } @@ -635,7 +721,7 @@ void TextView::SetSortModifier( float depthOffset ) { mVisualParameters.mSortModifier = depthOffset; - for( std::vector::iterator it = mRelayoutData.mTextActors.begin(), endIt = mRelayoutData.mTextActors.end(); + for( std::vector::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.end(); it != endIt; ++it ) { @@ -652,10 +738,10 @@ void TextView::SetSnapshotModeEnabled( bool enable ) { if( enable != mVisualParameters.mSnapshotModeEnabled ) { - // Remove first all text-actors - if( !mRelayoutData.mTextActors.empty() ) + // Remove first all glyph-actors + if( !mRelayoutData.mGlyphActors.empty() ) { - TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors ); + TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors ); } mVisualParameters.mSnapshotModeEnabled = enable; @@ -677,7 +763,7 @@ void TextView::SetSnapshotModeEnabled( bool enable ) mOffscreenRootActor.SetColorMode( USE_OWN_COLOR ); mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION ); - mOffscreenRootActor.SetInheritRotation( false ); + mOffscreenRootActor.SetInheritOrientation( false ); mOffscreenRootActor.SetInheritScale( false ); mOffscreenRootActor.SetDepthTestDisabled( true ); @@ -685,10 +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 ) ); } else { @@ -712,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(); } @@ -724,7 +812,17 @@ bool TextView::IsSnapshotModeEnabled() const return mVisualParameters.mSnapshotModeEnabled; } -void TextView::SetScrollEnabled( const bool enable ) +void TextView::SetMarkupProcessingEnabled( bool enable ) +{ + mMarkUpEnabled = enable; +} + +bool TextView::IsMarkupProcessingEnabled() const +{ + return mMarkUpEnabled; +} + +void TextView::SetScrollEnabled( bool enable ) { if( enable != mVisualParameters.mScrollEnabled ) { @@ -795,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 ) @@ -805,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 ); } @@ -822,34 +920,37 @@ 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 ) +{ +} + +TextView::LayoutParameters::~LayoutParameters() { - // Sets ellipsize text - MarkupProcessor::StyledTextArray styledEllipsize; - MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText ); } -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 ) +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 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft : @@ -861,21 +962,18 @@ TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::Multiline mHorizontalAlignment = horizontalAlignment; mVerticalAlignment = verticalAlignment; - - // Sets ellipsize text - MarkupProcessor::StyledTextArray styledEllipsize; - MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText ); } 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 ) { } @@ -888,7 +986,7 @@ TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextVie mVerticalAlignment = layoutParameters.mVerticalAlignment; mLineJustification = layoutParameters.mLineJustification; mLineHeightOffset = layoutParameters.mLineHeightOffset; - mEllipsizeText = layoutParameters.mEllipsizeText; + mMarkUpEnabled = layoutParameters.mMarkUpEnabled; return *this; } @@ -931,7 +1029,7 @@ TextView::RelayoutData::RelayoutData() mTextLayoutInfo(), mCharacterLogicalToVisualMap(), mCharacterVisualToLogicalMap(), - mTextActors(), + mGlyphActors(), mCharacterLayoutInfoTable(), mLines(), mTextSizeForRelayoutOption() @@ -944,7 +1042,7 @@ TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData mTextLayoutInfo( relayoutData.mTextLayoutInfo ), mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ), mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ), - mTextActors( relayoutData.mTextActors ), + mGlyphActors( relayoutData.mGlyphActors ), mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ), mLines( relayoutData.mLines ), mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption ) @@ -958,7 +1056,7 @@ TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::Relay mTextLayoutInfo = relayoutData.mTextLayoutInfo; mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap; mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap; - mTextActors = relayoutData.mTextActors; + mGlyphActors = relayoutData.mGlyphActors; mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable; mLines = relayoutData.mLines; mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption; @@ -967,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, @@ -976,7 +1074,7 @@ TextView::TextView() static_cast( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ), Toolkit::TextView::Left, PointSize( 0.f ), - std::string( "..." ) ), + false ), mVisualParameters(), mRelayoutData(), mRelayoutOperations( NO_RELAYOUT ), @@ -988,10 +1086,11 @@ TextView::TextView() mRenderTask(), mPanGestureDetector(), mLockPreviousSnapshotMode( false ), - mPreviousSnapshotModeEnabled( false ) + mPreviousSnapshotModeEnabled( false ), + mMarkUpEnabled( false ) { - TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText, - mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo ); + // Creates the ellipsis layout info. + CreateEllipsizeLayout(); } TextView::~TextView() @@ -1012,15 +1111,14 @@ Vector3 TextView::GetNaturalSize() { // There are SetText, Inserts or Removes to do. It means the current layout info is not updated. - if( !mRelayoutData.mTextActors.empty() ) + if( !mRelayoutData.mGlyphActors.empty() ) { - // Remove text-actors from the text-view as some text-operation like CreateTextInfo() + // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo() // add them to the text-actor cache. - TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors ); - mRelayoutData.mTextActors.clear(); + TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors ); + mRelayoutData.mGlyphActors.clear(); mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW ); - mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); } PerformTextViewProcessorOperations(); @@ -1046,26 +1144,26 @@ float TextView::GetHeightForWidth( float width ) // Check if the given width is different than the current one. const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 ); - // Check if the text-view has text-actors. - const bool hasTextActors = !mRelayoutData.mTextActors.empty(); + // Check if the text-view has glyph-actors. + const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty(); // Check which layout operations need to be done. const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth; if( relayoutSizeAndPositionNeeded ) { - if( hasTextActors ) + if( hasGlyphActors ) { - // Remove text-actors from the text-view as some text-operation like CreateTextInfo() + // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo() // add them to the text-actor cache. - TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors ); - mRelayoutData.mTextActors.clear(); + TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors ); + mRelayoutData.mGlyphActors.clear(); } // Use the given width. const Vector2 textViewSize( width, GetControlSize().height ); - // Relays-out but doesn't add text-actors to the text-view. + // Relays-out but doesn't add glyph-actors to the text-view. DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION ); } @@ -1078,13 +1176,12 @@ float TextView::GetHeightForWidth( float width ) mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_SIZE_POSITION ); } - if( hasTextActors ) + if( hasGlyphActors ) { mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW ); - mRelayoutOperations = static_cast( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST ); } - if( differentWidth || hasTextActors ) + if( differentWidth || hasGlyphActors ) { RelayoutRequest(); } @@ -1099,83 +1196,18 @@ 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( Dali::Toolkit::TextView::PROPERTY_TEXT, "", Property::READ_WRITE ); - - mPropertyMultilinePolicy = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_MULTILINE_POLICY, "SplitByNewLineChar", Property::READ_WRITE ); - - mPropertyWidthExceedPolicy = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY, "Original", Property::READ_WRITE ); - - mPropertyHeightExceedPolicy = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY, "Original", Property::READ_WRITE ); - - mPropertyLineJustification = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION, "Left", Property::READ_WRITE ); - - mPropertyFadeBoundaryLeft = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_LEFT, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyFadeBoundaryRight = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_RIGHT, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyFadeBoundaryTop = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_TOP, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyFadeBoundaryBottom = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_BOTTOM, static_cast< int >( 0 ), Property::READ_WRITE ); - - mPropertyLineHeightOffset = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET, 0.0f, Property::READ_WRITE ); - - mPropertyHorizontalAlignment = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT, "HorizontalCenter", Property::READ_WRITE ); - - mPropertyVerticalAlignment = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT, "VerticalCenter", Property::READ_WRITE ); - + // The actor handle needs to be inialised for this to work + Self().SetResizePolicy( USE_NATURAL_SIZE, ALL_DIMENSIONS ); } -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 ); } @@ -1192,7 +1224,7 @@ void TextView::OnControlSizeSet( const Vector3& size ) } } -void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container ) +void TextView::OnRelayout( const Vector2& size, RelayoutContainer& container ) { if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) ) { @@ -1202,7 +1234,7 @@ void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container ) if( size != mRelayoutData.mTextViewSize ) { - // if new size is different than the prevoius one, set positions and maybe sizes of all text-actor is needed. + // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed. if( RELAYOUT_ALL != mRelayoutOperations ) { mRelayoutOperations = static_cast( mRelayoutOperations | @@ -1211,21 +1243,31 @@ 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 ); } } - // Remove text-actors from text-view - if( !mRelayoutData.mTextActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) ) + if( ( Toolkit::TextView::Fade == mLayoutParameters.mWidthExceedPolicy ) || + ( Toolkit::TextView::Fade == mLayoutParameters.mHeightExceedPolicy ) ) { - TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors ); - mRelayoutData.mTextActors.clear(); + 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; + } + } + + // Remove glyph-actors from text-view + if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) ) + { + TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors ); + mRelayoutData.mGlyphActors.clear(); } if( NO_RELAYOUT != mRelayoutOperations ) { - // Relays-out and add text-actors to the text-view. + // Relays-out and add glyph-actors to the text-view. DoRelayOut( size, mRelayoutOperations ); ProcessSnapshot( size ); } @@ -1320,9 +1362,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 ) @@ -1357,9 +1399,9 @@ 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 text-actor data structures. + // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures. if( !mTextViewProcessorOperations.empty() ) { PerformTextViewProcessorOperations(); @@ -1454,13 +1496,11 @@ void TextView::ProcessSnapshot( const Size& textViewSize ) mOffscreenCameraActor = CameraActor::New(); mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER ); mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER ); + mOffscreenCameraActor.SetOrientation(Degree(180.f), Vector3::YAXIS); mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor. mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text - - // Images are expected to be from top to bottom, but OpenGL buffers are bottom to top - mOffscreenCameraActor.SetInvertYAxis( false ); } // Calculate camera parameters for current text size. @@ -1630,7 +1670,7 @@ void TextView::DestroyOffscreenRenderingResources() } } -void TextView::OnTextPan( Actor actor, PanGesture gesture ) +void TextView::OnTextPan( Actor actor, const PanGesture& gesture ) { if( 1u == gesture.numberOfTouches ) { @@ -1728,7 +1768,7 @@ void TextView::DoSetScrollPosition( const Vector2& position ) if( mOffscreenRootActor ) { - // If there is a render-task it needs to be refreshed. Therefore text-actors need to be + // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be // set to visible. mOffscreenRootActor.SetVisible( true ); } @@ -1748,7 +1788,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() @@ -1802,6 +1842,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" ); @@ -1902,6 +1947,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() ); @@ -1930,10 +2003,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); @@ -1963,10 +2032,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); @@ -2010,37 +2075,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") { @@ -2059,7 +2112,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" ) { @@ -2078,6 +2131,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