2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include "text-view-impl.h"
21 #include "split-by-new-line-char-policies.h"
22 #include "split-by-word-policies.h"
23 #include "split-by-char-policies.h"
24 #include "text-view-processor.h"
25 #include "text-view-word-processor.h"
26 #include "relayout-utilities.h"
27 #include "text-view-processor-dbg.h"
41 // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
42 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
47 return Toolkit::TextView::New();
50 TypeRegistration typeRegistration( typeid(Toolkit::TextView), typeid(Toolkit::Control), Create );
52 SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal );
55 * Whether the text-view-processor operation sets, inserts, replaces, removes text.
57 * @param[in] metadata The text-view-processor operation.
59 * @return \e true if the given text-view-processor operation is modifying the text.
61 bool IsTextViewProcessorRelayoutOperation( const TextView::TextViewProcessorMetadata& metadata )
63 return ( ( metadata.mType == TextView::TextSet ) ||
64 ( metadata.mType == TextView::TextInserted ) ||
65 ( metadata.mType == TextView::TextReplaced ) ||
66 ( metadata.mType == TextView::TextRemoved ) ||
67 ( metadata.mType == TextView::NewStyle ));
71 * Whether the text-view-processor operation sets a new line height offset.
73 * @param[in] metadata The text-view-processor operation.
75 * @return \e true if the given text-view-processor operation sets a new line height offset.
77 bool IsTextViewProcessorLineHeightOffsetOperation( const TextView::TextViewProcessorMetadata& metadata )
79 return ( metadata.mType == TextView::NewLineHeight );
83 * Whether the text-view-processor operation sets a new style.
85 * @param[in] metadata The text-view-processor operation.
87 * @return \e true if the given text-view-processor operation sets a new style.
89 bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMetadata& metadata )
91 return ( metadata.mType == TextView::NewStyle );
96 TextView::TextViewProcessorMetadata::TextViewProcessorMetadata()
97 : mType( TextView::TextSet ),
99 mNumberOfCharacters( 0 ),
104 Toolkit::TextView TextView::New()
106 // Create the implementation, temporarily owned on stack
107 IntrusivePtr<TextView> textView = new TextView();
109 // Pass ownership to CustomActor
110 Toolkit::TextView handle( *textView );
112 // Second-phase init of the implementation
113 // This can only be done after the CustomActor connection has been made...
114 textView->Initialize();
116 // Enables by default the offscreen rendering.
117 textView->SetSnapshotModeEnabled( false ); /// @note Temporary disabled due to some issues with text quality and glyph loading.
122 void TextView::SetText( const std::string& text )
124 // Creates a styled text with the markup or plain string.
125 MarkupProcessor::StyledTextArray styledText;
126 MarkupProcessor::GetStyledTextArray( text, styledText );
128 // Calls SetText() with the styled text array.
129 SetText( styledText );
132 void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
134 // mTextViewProcessorOperations stores the InsertTextAt and RemoveTextFrom operations to transform the initial text to mCurrentStyledText.
135 // Once again, if a new text is set, any previous call to InsertTextAt or RemoveTextFrom can be discarted.
137 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorRelayoutOperation );
138 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
140 // Creates metadata with the Set operation.
141 TextViewProcessorMetadata metadata;
142 metadata.mType = TextView::TextSet;
143 metadata.mText = text;
146 mTextViewProcessorOperations.push_back( metadata );
148 // Updates current styled text.
149 mCurrentStyledText = text;
151 // Request to be relaid out
154 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
155 mRelayoutOperations = RELAYOUT_ALL;
158 void TextView::InsertTextAt( std::size_t position, const std::string& text )
160 // Creates a styled text with the markup or plain string.
161 MarkupProcessor::StyledTextArray styledText;
162 MarkupProcessor::GetStyledTextArray( text, styledText );
164 // Calls InsertTextAt() with the styled text array.
165 InsertTextAt( position, styledText );
168 void TextView::InsertTextAt( const std::size_t position, const MarkupProcessor::StyledTextArray& text )
170 // Creates metadata with the Insert operation.
171 TextViewProcessorMetadata metadata;
172 metadata.mType = TextView::TextInserted;
173 metadata.mPosition = position;
174 metadata.mText = text;
177 mTextViewProcessorOperations.push_back( metadata );
179 // Updates current styled text.
180 mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
182 // Request to be relaid out
185 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
186 mRelayoutOperations = RELAYOUT_ALL;
189 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const std::string& text )
191 // Creates a styled text with the markup or plain string.
192 MarkupProcessor::StyledTextArray styledText;
193 MarkupProcessor::GetStyledTextArray( text, styledText );
195 // Calls ReplaceTextFromTo() with the styled text array.
196 ReplaceTextFromTo( position, numberOfCharacters, styledText );
199 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
201 // Creates metadata with the Insert operation.
202 TextViewProcessorMetadata metadata;
203 metadata.mType = TextView::TextReplaced;
204 metadata.mPosition = position;
205 metadata.mNumberOfCharacters = numberOfCharacters;
206 metadata.mText = text;
209 mTextViewProcessorOperations.push_back( metadata );
211 // Updates current styled text.
212 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
213 mCurrentStyledText.erase( it, it + numberOfCharacters );
214 it = mCurrentStyledText.begin() + position;
215 mCurrentStyledText.insert( it, text.begin(), text.end() );
217 // Request to be relaid out
220 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
221 mRelayoutOperations = RELAYOUT_ALL;
224 void TextView::RemoveTextFrom( const std::size_t position, const std::size_t numberOfCharacters )
226 // Creates metadata with the Remove operation.
227 TextViewProcessorMetadata metadata;
228 metadata.mType = TextView::TextRemoved;
229 metadata.mPosition = position;
230 metadata.mNumberOfCharacters = numberOfCharacters;
233 mTextViewProcessorOperations.push_back( metadata );
235 // Updates current styled text.
236 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
237 mCurrentStyledText.erase( it, it + numberOfCharacters );
239 // Request to be relaid out
242 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
243 mRelayoutOperations = RELAYOUT_ALL;
246 std::string TextView::GetText() const
248 // Traverses the styled text array getting only the text.
249 // Note that for some languages a 'character' could be represented by more than one 'char'
252 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); it != endIt; ++it )
254 text.append( (*it).mText.GetText() );
260 void TextView::SetLineHeightOffset( const PointSize offset )
262 if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 )
264 // Removes any previous operation which modifies the line height offset.
265 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorLineHeightOffsetOperation );
266 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
268 // Creates metadata with the new line height operation.
269 TextViewProcessorMetadata metadata;
270 metadata.mType = TextView::NewLineHeight;
272 mTextViewProcessorOperations.push_back( metadata );
274 // Updates line height offset.
275 mLayoutParameters.mLineHeightOffset = offset;
279 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
280 if( RELAYOUT_ALL != mRelayoutOperations )
282 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
283 RELAYOUT_REMOVE_TEXT_ACTORS |
284 RELAYOUT_SIZE_POSITION |
286 RELAYOUT_VISIBILITY |
287 RELAYOUT_TEXT_ACTOR_UPDATE |
288 RELAYOUT_INSERT_TO_TEXT_VIEW |
289 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
294 PointSize TextView::GetLineHeightOffset() const
296 return PointSize( mLayoutParameters.mLineHeightOffset );
299 void TextView::SetStyleToCurrentText( const TextStyle& style, const TextStyle::Mask mask )
301 if( !mCurrentStyledText.empty() )
303 const bool checkFontName = mask & TextStyle::FONT;
304 const bool checkFontSize = mask & TextStyle::SIZE;
305 const bool checkFontStyle = mask & TextStyle::STYLE;
307 // Check first if metrics have changed.
308 bool metricsChanged = false;
309 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
311 const MarkupProcessor::StyledText& styledText( *it );
313 metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
314 ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
315 ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
320 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
322 // If metrics change, new text measurements are needed.
323 SetText( mCurrentStyledText );
327 // Deletes any previous operation which sets a new style.
328 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
329 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
331 // Creates metadata with the new style operation.
332 TextViewProcessorMetadata metadata;
333 metadata.mType = TextView::NewStyle;
335 MarkupProcessor::StyledText text;
337 metadata.mText.push_back( text );
338 metadata.mStyleMask = mask;
340 mTextViewProcessorOperations.push_back( metadata );
342 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
346 if( RELAYOUT_ALL != mRelayoutOperations )
348 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
349 RELAYOUT_TEXT_ACTOR_UPDATE );
354 // Sets the new style to the ellipsize text
355 if( !mLayoutParameters.mEllipsizeText.empty() )
357 for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
359 (*it).mStyle.Copy( style, mask );
362 SetEllipsizeText( mLayoutParameters.mEllipsizeText );
366 void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
368 if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
370 Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
371 ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
372 ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
373 Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
374 ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
375 ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
377 mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
378 mLayoutParameters.mVerticalAlignment = verticalAlignment;
382 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
383 if( RELAYOUT_ALL != mRelayoutOperations )
385 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
386 RELAYOUT_TEXT_ACTOR_UPDATE |
388 RELAYOUT_VISIBILITY );
393 Toolkit::Alignment::Type TextView::GetTextAlignment() const
395 return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
398 void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
400 if( policy != mLayoutParameters.mMultilinePolicy )
402 mLayoutParameters.mMultilinePolicy = policy;
404 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
405 mRelayoutOperations = RELAYOUT_ALL;
411 Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
413 return mLayoutParameters.mMultilinePolicy;
416 void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
418 // The layout info could be invalid depending on the current exceed policy and the new one.
419 // i.e. if the current policy is Split and the new one is ShrinkToFit then
420 // the layout info generated for each char is not needed.
421 if( policy != mLayoutParameters.mWidthExceedPolicy )
423 mLayoutParameters.mWidthExceedPolicy = policy;
425 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
426 mRelayoutOperations = RELAYOUT_ALL;
432 Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
434 return mLayoutParameters.mWidthExceedPolicy;
437 void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
439 if( policy != mLayoutParameters.mHeightExceedPolicy )
441 mLayoutParameters.mHeightExceedPolicy = policy;
445 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
446 if( RELAYOUT_ALL != mRelayoutOperations )
448 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
449 RELAYOUT_REMOVE_TEXT_ACTORS |
450 RELAYOUT_SIZE_POSITION |
452 RELAYOUT_VISIBILITY |
453 RELAYOUT_TEXT_ACTOR_UPDATE |
454 RELAYOUT_INSERT_TO_TEXT_VIEW |
455 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
460 Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
462 return mLayoutParameters.mHeightExceedPolicy;
465 void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
467 if( justification != mLayoutParameters.mLineJustification )
469 mLayoutParameters.mLineJustification = justification;
473 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
474 if( RELAYOUT_ALL != mRelayoutOperations )
476 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
477 RELAYOUT_REMOVE_TEXT_ACTORS |
478 RELAYOUT_SIZE_POSITION |
480 RELAYOUT_VISIBILITY |
481 RELAYOUT_TEXT_ACTOR_UPDATE |
482 RELAYOUT_INSERT_TO_TEXT_VIEW |
483 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
488 Toolkit::TextView::LineJustification TextView::GetLineJustification() const
490 return mLayoutParameters.mLineJustification;
493 void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
495 if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
496 ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
497 ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
498 ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
500 mVisualParameters.mFadeBoundary = fadeBoundary;
504 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
505 if( RELAYOUT_ALL != mRelayoutOperations )
507 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
508 RELAYOUT_REMOVE_TEXT_ACTORS |
509 RELAYOUT_VISIBILITY |
510 RELAYOUT_TEXT_ACTOR_UPDATE |
511 RELAYOUT_INSERT_TO_TEXT_VIEW |
512 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
517 const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
519 return mVisualParameters.mFadeBoundary;
522 void TextView::SetEllipsizeText( const std::string& ellipsizeText )
524 // Creates a styled text with the markup or plain string.
525 MarkupProcessor::StyledTextArray styledText;
526 MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText );
528 SetEllipsizeText( styledText );
531 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
533 mLayoutParameters.mEllipsizeText = ellipsizeText;
535 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
537 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
538 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
540 // Request to be relaid out
543 mRelayoutOperations = RELAYOUT_ALL;
546 std::string TextView::GetEllipsizeText() const
549 for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
551 text.append( (*it).mText.GetText() );
557 void TextView::GetTextLayoutInfo()
559 const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
560 const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
561 const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
563 if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
565 Vector3 textViewSize = GetControlSize();
567 if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
568 ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
569 ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
570 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
571 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
573 // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
574 // the text natural size can be used.
575 textViewSize = GetNaturalSize();
578 if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
579 ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
581 // Check if the text-view has text-actors.
582 const bool hasTextActors = !mRelayoutData.mTextActors.empty();
584 RelayoutOperationMask mask = NO_RELAYOUT;
585 if( relayoutSizeAndPositionNeeded )
587 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
589 if( relayoutAlignmentNeeded )
591 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
593 if( relayoutVisibilityNeeded )
595 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
600 // Remove text-actors from the text-view as some text-operation like CreateTextInfo()
601 // add them to the text-actor cache.
602 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
603 mRelayoutData.mTextActors.clear();
606 // Relays-out but doesn't add text-actors to the text-view.
607 DoRelayOut( textViewSize.GetVectorXY(), mask );
611 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
612 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
619 void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
623 textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
624 textLayoutInfo.mLines = mRelayoutData.mLines;
626 textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
627 textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
629 textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
631 textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
634 void TextView::SetSortModifier( float depthOffset )
636 mVisualParameters.mSortModifier = depthOffset;
638 for( std::vector<TextActor>::iterator it = mRelayoutData.mTextActors.begin(), endIt = mRelayoutData.mTextActors.end();
642 ( *it ).SetSortModifier( depthOffset );
645 if( mOffscreenImageActor )
647 mOffscreenImageActor.SetSortModifier( depthOffset );
651 void TextView::SetSnapshotModeEnabled( bool enable )
653 if( enable != mVisualParameters.mSnapshotModeEnabled )
655 // Remove first all text-actors
656 if( !mRelayoutData.mTextActors.empty() )
658 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
661 mVisualParameters.mSnapshotModeEnabled = enable;
662 if( !mLockPreviousSnapshotMode )
664 // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
665 // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
667 // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
668 // to smash the stored value.
669 mPreviousSnapshotModeEnabled = enable;
672 if( mVisualParameters.mSnapshotModeEnabled )
674 // Create a root actor and an image actor for offscreen rendering.
675 mOffscreenRootActor = Layer::New();
676 mOffscreenImageActor = ImageActor::New();
678 mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
679 mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
680 mOffscreenRootActor.SetInheritRotation( false );
681 mOffscreenRootActor.SetInheritScale( false );
682 mOffscreenRootActor.SetDepthTestDisabled( true );
684 mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
686 mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
687 mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
690 self.Add( mOffscreenRootActor );
691 self.Add( mOffscreenImageActor );
697 if( mOffscreenRootActor )
699 self.Remove( mOffscreenRootActor );
702 if( mOffscreenImageActor )
704 self.Remove( mOffscreenImageActor );
707 DestroyOffscreenRenderingResources();
710 if( RELAYOUT_ALL != mRelayoutOperations )
712 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
713 RELAYOUT_REMOVE_TEXT_ACTORS |
714 RELAYOUT_TEXT_ACTOR_UPDATE |
715 RELAYOUT_INSERT_TO_TEXT_VIEW |
716 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
722 bool TextView::IsSnapshotModeEnabled() const
724 return mVisualParameters.mSnapshotModeEnabled;
727 void TextView::SetScrollEnabled( const bool enable )
729 if( enable != mVisualParameters.mScrollEnabled )
731 mVisualParameters.mScrollEnabled = enable;
733 if( mVisualParameters.mScrollEnabled )
735 // Offscreen rendering is needed to enable text scroll.
737 // Stores previous value of the snapshot mode.
738 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
741 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
742 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
743 Lock lock( mLockPreviousSnapshotMode );
744 SetSnapshotModeEnabled( true );
747 // Creates the pan gesture detector and attach the text-view.
748 mPanGestureDetector = PanGestureDetector::New();
749 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
750 mPanGestureDetector.Attach( Self() );
754 // Removes the pan gesture detector.
755 if( mPanGestureDetector )
757 mPanGestureDetector.Detach( Self() );
758 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
759 mPanGestureDetector.Reset();
762 // Restores the previous state for snapshot mode.
763 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
768 bool TextView::IsScrollEnabled() const
770 return mVisualParameters.mScrollEnabled;
773 void TextView::SetScrollPosition( const Vector2& position )
775 if( position != mVisualParameters.mCameraScrollPosition )
777 // Guard against destruction during signal emission
778 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
779 Toolkit::TextView handle( GetOwner() );
781 DoSetScrollPosition( position );
783 // Check if the new scroll position has been trimmed.
784 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
788 const Vector2& TextView::GetScrollPosition() const
790 return mVisualParameters.mCameraScrollPosition;
793 bool TextView::IsScrollPositionTrimmed() const
795 return mVisualParameters.mScrollPositionTrimmed;
798 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
800 return mScrolledSignalV2;
803 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
805 Dali::BaseHandle handle( object );
807 bool connected( true );
808 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
810 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
812 textView.ScrolledSignal().Connect( tracker, functor );
816 // signalName does not match any signal
823 TextView::LayoutParameters::LayoutParameters()
824 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
825 mWidthExceedPolicy( Toolkit::TextView::Original ),
826 mHeightExceedPolicy( Toolkit::TextView::Original ),
827 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
828 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
829 mLineJustification( Toolkit::TextView::Left ),
830 mLineHeightOffset( 0.f ),
833 // Sets ellipsize text
834 MarkupProcessor::StyledTextArray styledEllipsize;
835 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText );
838 TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::MultilinePolicy multilinePolicy,
839 const Toolkit::TextView::ExceedPolicy widthExceedPolicy,
840 const Toolkit::TextView::ExceedPolicy heightExceedPolicy,
841 const Toolkit::Alignment::Type alignmentType,
842 const Toolkit::TextView::LineJustification lineJustification,
843 const float lineHeightOffset,
844 const std::string& ellipsizeText )
845 : mMultilinePolicy( multilinePolicy ),
846 mWidthExceedPolicy( widthExceedPolicy ),
847 mHeightExceedPolicy( heightExceedPolicy ),
848 mHorizontalAlignment(),
849 mVerticalAlignment(),
850 mLineJustification( lineJustification ),
851 mLineHeightOffset( lineHeightOffset ),
855 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
856 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
857 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
858 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
859 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
860 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
862 mHorizontalAlignment = horizontalAlignment;
863 mVerticalAlignment = verticalAlignment;
865 // Sets ellipsize text
866 MarkupProcessor::StyledTextArray styledEllipsize;
867 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText );
870 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
871 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
872 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
873 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
874 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
875 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
876 mLineJustification( layoutParameters.mLineJustification ),
877 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
878 mEllipsizeText( layoutParameters.mEllipsizeText )
882 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
884 mMultilinePolicy = layoutParameters.mMultilinePolicy;
885 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
886 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
887 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
888 mVerticalAlignment = layoutParameters.mVerticalAlignment;
889 mLineJustification = layoutParameters.mLineJustification;
890 mLineHeightOffset = layoutParameters.mLineHeightOffset;
891 mEllipsizeText = layoutParameters.mEllipsizeText;
896 TextView::VisualParameters::VisualParameters()
898 mSortModifier( 0.f ),
899 mCameraScrollPosition( 0.f, 0.f ),
900 mSnapshotModeEnabled( false ),
901 mScrollEnabled( false ),
902 mScrollPositionTrimmed( false )
906 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
907 : mFadeBoundary( visualParameters.mFadeBoundary ),
908 mSortModifier( visualParameters.mSortModifier ),
909 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
910 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
911 mScrollEnabled( visualParameters.mScrollEnabled ),
912 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
916 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
918 mFadeBoundary = visualParameters.mFadeBoundary;
919 mSortModifier = visualParameters.mSortModifier;
920 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
921 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
922 mScrollEnabled = visualParameters.mScrollEnabled;
923 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
928 TextView::RelayoutData::RelayoutData()
930 mShrinkFactor( 1.f ),
932 mCharacterLogicalToVisualMap(),
933 mCharacterVisualToLogicalMap(),
935 mCharacterLayoutInfoTable(),
937 mTextSizeForRelayoutOption()
941 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
942 : mTextViewSize( relayoutData.mTextViewSize ),
943 mShrinkFactor( relayoutData.mShrinkFactor ),
944 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
945 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
946 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
947 mTextActors( relayoutData.mTextActors ),
948 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
949 mLines( relayoutData.mLines ),
950 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
954 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
956 mTextViewSize = relayoutData.mTextViewSize;
957 mShrinkFactor = relayoutData.mShrinkFactor;
958 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
959 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
960 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
961 mTextActors = relayoutData.mTextActors;
962 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
963 mLines = relayoutData.mLines;
964 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
970 : ControlImpl( false ), // doesn't require touch events
971 mCurrentStyledText(),
972 mTextViewProcessorOperations(),
973 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
974 Toolkit::TextView::Original,
975 Toolkit::TextView::Original,
976 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
977 Toolkit::TextView::Left,
979 std::string( "..." ) ),
982 mRelayoutOperations( NO_RELAYOUT ),
983 mOffscreenRootActor(),
984 mOffscreenImageActor(),
985 mOffscreenCameraActor(),
986 mCurrentOffscreenSize(),
989 mPanGestureDetector(),
990 mLockPreviousSnapshotMode( false ),
991 mPreviousSnapshotModeEnabled( false )
993 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
994 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
997 TextView::~TextView()
999 // Destroys offscreen rendering resources.
1000 DestroyOffscreenRenderingResources();
1002 // Destroys scroll pan gesture detector.
1003 if( mPanGestureDetector )
1005 mPanGestureDetector.Reset();
1009 Vector3 TextView::GetNaturalSize()
1011 if( !mTextViewProcessorOperations.empty() )
1013 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1015 if( !mRelayoutData.mTextActors.empty() )
1017 // Remove text-actors from the text-view as some text-operation like CreateTextInfo()
1018 // add them to the text-actor cache.
1019 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
1020 mRelayoutData.mTextActors.clear();
1022 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1023 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1026 PerformTextViewProcessorOperations();
1029 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1032 float TextView::GetHeightForWidth( float width )
1036 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1037 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1038 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1040 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1041 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1042 height = GetNaturalSize().height;
1046 // Check if the given width is different than the current one.
1047 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1049 // Check if the text-view has text-actors.
1050 const bool hasTextActors = !mRelayoutData.mTextActors.empty();
1052 // Check which layout operations need to be done.
1053 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1055 if( relayoutSizeAndPositionNeeded )
1059 // Remove text-actors from the text-view as some text-operation like CreateTextInfo()
1060 // add them to the text-actor cache.
1061 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
1062 mRelayoutData.mTextActors.clear();
1065 // Use the given width.
1066 const Vector2 textViewSize( width, GetControlSize().height );
1068 // Relays-out but doesn't add text-actors to the text-view.
1069 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1072 // Retrieve the text height after relayout the text.
1073 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1075 if( differentWidth )
1077 // Revert the relayout operation mask
1078 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1083 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1084 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1087 if( differentWidth || hasTextActors )
1096 float TextView::GetWidthForHeight( float height )
1098 // TODO: Needs implementing properly, for now just return the natural width.
1099 return GetNaturalSize().width;
1102 void TextView::OnPropertySet( Property::Index index, Property::Value propertyValue )
1104 if( index == mPropertyText )
1106 SetText(propertyValue.Get<std::string>());
1108 else if( index == mPropertyMultilinePolicy )
1110 OnMultilinePolicyPropertySet(propertyValue);
1112 else if( index == mPropertyWidthExceedPolicy )
1114 OnWidthExceedPolicyPropertySet(propertyValue);
1116 else if( index == mPropertyHeightExceedPolicy )
1118 OnHeightExceedPolicyPropertySet(propertyValue);
1120 else if( index == mPropertyLineJustification )
1122 OnLineJustificationPropertySet(propertyValue);
1124 else if( ( index == mPropertyFadeBoundaryLeft ) ||
1125 ( index == mPropertyFadeBoundaryRight ) ||
1126 ( index == mPropertyFadeBoundaryTop ) ||
1127 ( index == mPropertyFadeBoundaryBottom ) )
1129 OnFadeBoundaryPropertySet( index, propertyValue );
1131 else if( index == mPropertyLineHeightOffset )
1133 Dali::PointSize pointSize( propertyValue.Get<float>() );
1134 SetLineHeightOffset(pointSize);
1136 else if ( ( index == mPropertyHorizontalAlignment ) ||
1137 ( index == mPropertyVerticalAlignment ) )
1139 OnAlignmentPropertySet( index, propertyValue );
1143 void TextView::OnInitialize()
1145 Actor self = Self();
1147 mPropertyText = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_TEXT, "", Property::READ_WRITE );
1149 mPropertyMultilinePolicy = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_MULTILINE_POLICY, "SplitByNewLineChar", Property::READ_WRITE );
1151 mPropertyWidthExceedPolicy = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY, "Original", Property::READ_WRITE );
1153 mPropertyHeightExceedPolicy = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY, "Original", Property::READ_WRITE );
1155 mPropertyLineJustification = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION, "Left", Property::READ_WRITE );
1157 mPropertyFadeBoundaryLeft = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_LEFT, static_cast< int >( 0 ), Property::READ_WRITE );
1159 mPropertyFadeBoundaryRight = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_RIGHT, static_cast< int >( 0 ), Property::READ_WRITE );
1161 mPropertyFadeBoundaryTop = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_TOP, static_cast< int >( 0 ), Property::READ_WRITE );
1163 mPropertyFadeBoundaryBottom = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_FADE_BOUNDARY_BOTTOM, static_cast< int >( 0 ), Property::READ_WRITE );
1165 mPropertyLineHeightOffset = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET, 0.0f, Property::READ_WRITE );
1167 mPropertyHorizontalAlignment = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT, "HorizontalCenter", Property::READ_WRITE );
1169 mPropertyVerticalAlignment = self.RegisterProperty( Dali::Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT, "VerticalCenter", Property::READ_WRITE );
1174 void TextView::OnStyleChange( StyleChange change )
1176 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1177 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1178 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1180 SetText( mCurrentStyledText );
1183 void TextView::OnControlSizeSet( const Vector3& size )
1185 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1187 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1188 mRelayoutOperations = RELAYOUT_ALL;
1190 // Request to be relaid out
1195 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1197 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1199 // Not worth to relayout if width or height is equal to zero.
1203 if( size != mRelayoutData.mTextViewSize )
1205 // if new size is different than the prevoius one, set positions and maybe sizes of all text-actor is needed.
1206 if( RELAYOUT_ALL != mRelayoutOperations )
1208 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1209 RELAYOUT_REMOVE_TEXT_ACTORS |
1210 RELAYOUT_SIZE_POSITION |
1211 RELAYOUT_ALIGNMENT |
1212 RELAYOUT_VISIBILITY |
1213 RELAYOUT_TEXT_ACTOR_UPDATE |
1214 RELAYOUT_INSERT_TO_TEXT_VIEW |
1215 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1219 // Remove text-actors from text-view
1220 if( !mRelayoutData.mTextActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1222 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
1223 mRelayoutData.mTextActors.clear();
1226 if( NO_RELAYOUT != mRelayoutOperations )
1228 // Relays-out and add text-actors to the text-view.
1229 DoRelayOut( size, mRelayoutOperations );
1230 ProcessSnapshot( size );
1233 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1234 mRelayoutData.mTextActorCache.ClearTexts();
1237 void TextView::PerformTextViewProcessorOperations()
1239 // Traverse the relayout operation vector ...
1241 // Optimizes some operations.
1242 OptimizeTextViewProcessorOperations();
1244 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1246 const TextViewProcessorMetadata& relayoutMetadata( *it );
1248 switch( relayoutMetadata.mType )
1250 case TextView::TextSet:
1252 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1257 case TextView::TextInserted:
1259 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1260 relayoutMetadata.mText,
1265 case TextView::TextReplaced:
1267 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1268 relayoutMetadata.mNumberOfCharacters,
1269 relayoutMetadata.mText,
1274 case TextView::TextRemoved:
1276 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1277 relayoutMetadata.mNumberOfCharacters,
1280 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1283 case TextView::NewLineHeight:
1285 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1286 mRelayoutData.mTextLayoutInfo );
1289 case TextView::NewStyle:
1291 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1292 relayoutMetadata.mStyleMask,
1299 // Clear all operations when they are done.
1300 mTextViewProcessorOperations.clear();
1303 void TextView::OptimizeTextViewProcessorOperations()
1305 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1307 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1308 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1309 // use the cache without clearing the text-actors.
1311 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1313 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1315 const TextViewProcessorMetadata& relayoutMetadata( *it );
1317 switch( relayoutMetadata.mType )
1319 case TextView::TextRemoved:
1321 bool optimizationDone = false;
1323 if( it + 1 != endIt )
1325 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1326 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1328 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1330 optimizationDone = true;
1331 TextViewProcessorMetadata newRelayoutMetadata;
1332 newRelayoutMetadata.mType = TextView::TextReplaced;
1333 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1334 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1335 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1336 textViewProcessorOperations.push_back( newRelayoutMetadata );
1338 // do not access the TextInserted operation in next iteration.
1344 if( !optimizationDone )
1346 textViewProcessorOperations.push_back( relayoutMetadata );
1352 textViewProcessorOperations.push_back( relayoutMetadata );
1357 mTextViewProcessorOperations = textViewProcessorOperations;
1360 void TextView::DoRelayOut( const Size& textViewSize, const RelayoutOperationMask relayoutOperationMask )
1362 // Traverse the relayout operation vector. It fills the natural size, layout and text-actor data structures.
1363 if( !mTextViewProcessorOperations.empty() )
1365 PerformTextViewProcessorOperations();
1368 CombineExceedPolicies();
1371 if( mVisualParameters.mSnapshotModeEnabled )
1373 rootActor = mOffscreenRootActor;
1380 mRelayoutData.mTextViewSize = textViewSize;
1381 switch( mLayoutParameters.mMultilinePolicy )
1383 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1385 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1387 } // SplitByNewLineChar
1389 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1391 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1395 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1397 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1400 } // switch( mMultilinePolicy )
1402 // Remove done operations from the mask.
1403 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1406 void TextView::ProcessSnapshot( const Size& textViewSize )
1408 if( mVisualParameters.mSnapshotModeEnabled )
1410 // If layout options change, it's needed generate a new image.
1412 if( mOffscreenRootActor )
1414 // Set the root actor visible.
1415 // The root actor is set to non visible after the render task is processed.
1416 mOffscreenRootActor.SetVisible( true );
1418 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1419 mOffscreenRootActor.SetSize( textViewSize );
1422 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1423 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1425 // Set the image actor visible.
1426 // The image actor is set to non visible if there is no text to render.
1427 mOffscreenImageActor.SetVisible( true );
1429 // Calculates the offscreen image's size. It takes into account different points:
1430 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1431 // * There is a maximum texture size the graphic subsystem can load on the memory.
1432 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1434 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1435 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1436 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1437 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1439 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1443 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1444 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1445 offscreenSize.height,
1448 // Stores current text-view size to avoid create new Dali resources if text changes.
1449 mCurrentOffscreenSize = offscreenSize;
1451 if( !mOffscreenCameraActor )
1453 // Creates a new camera actor.
1454 mOffscreenCameraActor = CameraActor::New();
1455 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1456 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1458 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1460 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1462 // Images are expected to be from top to bottom, but OpenGL buffers are bottom to top
1463 mOffscreenCameraActor.SetInvertYAxis( false );
1466 // Calculate camera parameters for current text size.
1467 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1470 if( mVisualParameters.mScrollEnabled )
1472 // Updates the offscreen camera position with the new scroll offset.
1473 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1474 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1478 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1479 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1484 // Creates a new render task.
1485 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1487 mRenderTask.SetSourceActor( mOffscreenRootActor );
1488 mRenderTask.SetInputEnabled( false );
1489 mRenderTask.SetClearColor( Color::TRANSPARENT );
1490 mRenderTask.SetClearEnabled( true );
1491 mRenderTask.SetExclusive( true );
1493 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1494 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1499 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1500 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1503 // Process the render task only once every time the text changes or the text-view's size canges.
1504 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1508 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1509 mOffscreenImageActor.SetVisible( false );
1514 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1516 float xPosition = 0.f;
1517 float yPosition = 0.f;
1518 Vector3 parentOrigin = ParentOrigin::CENTER;
1519 Vector3 anchorPoint = AnchorPoint::CENTER;
1521 switch( mLayoutParameters.mHorizontalAlignment )
1523 case Toolkit::Alignment::HorizontalLeft:
1525 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1526 parentOrigin.x = 0.f;
1527 anchorPoint.x = 0.f;
1530 case Toolkit::Alignment::HorizontalCenter:
1535 case Toolkit::Alignment::HorizontalRight:
1537 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1538 parentOrigin.x = 1.f;
1539 anchorPoint.x = 1.f;
1544 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1548 switch( mLayoutParameters.mVerticalAlignment )
1550 case Toolkit::Alignment::VerticalTop:
1552 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1553 parentOrigin.y = 0.f;
1554 anchorPoint.y = 0.f;
1557 case Toolkit::Alignment::VerticalCenter:
1562 case Toolkit::Alignment::VerticalBottom:
1564 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1565 parentOrigin.y = 1.f;
1566 anchorPoint.y = 1.f;
1571 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1575 mOffscreenCameraActor.SetX( xPosition );
1576 mOffscreenCameraActor.SetY( yPosition );
1578 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1579 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1582 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1584 // not to process the offscreen root actor by setting its visibility to false.
1585 mOffscreenRootActor.SetVisible( false );
1587 // Sets the new size and the new frame buffer to the image actor.
1588 // Image actor must have same size as text. Otherwise text can be truncated.
1589 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1590 mOffscreenImageActor.SetImage( mFrameBufferImage );
1593 void TextView::DestroyOffscreenRenderingResources()
1597 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1599 if( Stage::IsInstalled() )
1601 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1604 mRenderTask.Reset();
1607 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1608 if( mOffscreenCameraActor )
1610 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1612 mOffscreenCameraActor.Reset();
1615 if( mOffscreenRootActor )
1617 mOffscreenRootActor.Reset();
1620 if( mOffscreenImageActor )
1622 mOffscreenImageActor.Reset();
1625 mCurrentOffscreenSize = Size( 0.f, 0.f );
1627 if( mFrameBufferImage )
1629 mFrameBufferImage.Reset();
1633 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1635 if( 1u == gesture.numberOfTouches )
1637 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1641 void TextView::TrimScrollPosition()
1643 const Vector3& textViewSize = GetControlSize();
1645 // Before use the text's size, relayout the text is needed to get the actual text size.
1646 GetTextLayoutInfo();
1648 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1649 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1650 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1651 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1652 float minVerticalDisplacement = -maxVerticalDisplacement;
1654 // Updates the range if the text is aligned on the right or left.
1655 switch( mLayoutParameters.mHorizontalAlignment )
1657 case Toolkit::Alignment::HorizontalLeft:
1659 maxHorizontalDisplacement *= 2.f;
1660 minHorizontalDisplacement = 0.f;
1663 case Toolkit::Alignment::HorizontalCenter:
1668 case Toolkit::Alignment::HorizontalRight:
1670 maxHorizontalDisplacement = 0.f;
1671 minHorizontalDisplacement *= 2.f;
1676 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1680 // Updates the range if the text is aligned on the top or bottom.
1681 switch( mLayoutParameters.mVerticalAlignment )
1683 case Toolkit::Alignment::VerticalTop:
1685 maxVerticalDisplacement *= 2.f;
1686 minVerticalDisplacement = 0.f;
1689 case Toolkit::Alignment::VerticalCenter:
1694 case Toolkit::Alignment::VerticalBottom:
1696 maxVerticalDisplacement = 0.f;
1697 minVerticalDisplacement *= 2.f;
1702 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1706 // Trims the scroll position to be within the range.
1707 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1708 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1710 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1711 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1714 void TextView::DoSetScrollPosition( const Vector2& position )
1716 // Stores old scroll position.
1717 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1719 // Updates the scroll position
1720 mVisualParameters.mCameraScrollPosition = position;
1722 // Ensures the text-view is covered with text.
1723 TrimScrollPosition();
1725 // Calculate the difference with the previous scroll position
1726 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1727 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1729 if( mOffscreenRootActor )
1731 // If there is a render-task it needs to be refreshed. Therefore text-actors need to be
1733 mOffscreenRootActor.SetVisible( true );
1736 if( mOffscreenCameraActor )
1738 // Update the offscreen camera with the new scroll position.
1739 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1740 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1745 // Refresh the render-task.
1746 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1750 Toolkit::TextView handle( GetOwner() );
1751 mScrolledSignalV2.Emit( handle, delta );
1754 void TextView::CombineExceedPolicies()
1756 // Calculates the combination of exceed policies.
1758 switch( mLayoutParameters.mWidthExceedPolicy )
1760 case Toolkit::TextView::Original:
1762 switch( mLayoutParameters.mHeightExceedPolicy )
1764 case Toolkit::TextView::Original:
1766 mLayoutParameters.mExceedPolicy = Original;
1769 case Toolkit::TextView::Fade:
1771 mLayoutParameters.mExceedPolicy = OriginalFade;
1774 case Toolkit::TextView::ShrinkToFit:
1776 mLayoutParameters.mExceedPolicy = OriginalShrink;
1781 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1786 case Toolkit::TextView::Split:
1788 switch( mLayoutParameters.mHeightExceedPolicy )
1790 case Toolkit::TextView::Original:
1792 mLayoutParameters.mExceedPolicy = SplitOriginal;
1795 case Toolkit::TextView::Fade:
1797 mLayoutParameters.mExceedPolicy = SplitFade;
1800 case Toolkit::TextView::ShrinkToFit:
1802 mLayoutParameters.mExceedPolicy = SplitShrink;
1807 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1812 case Toolkit::TextView::Fade:
1814 switch( mLayoutParameters.mHeightExceedPolicy )
1816 case Toolkit::TextView::Original:
1818 mLayoutParameters.mExceedPolicy = FadeOriginal;
1821 case Toolkit::TextView::Fade:
1823 mLayoutParameters.mExceedPolicy = Fade;
1828 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1833 case Toolkit::TextView::ShrinkToFit:
1835 switch( mLayoutParameters.mHeightExceedPolicy )
1837 case Toolkit::TextView::Original:
1839 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1842 case Toolkit::TextView::Fade:
1844 mLayoutParameters.mExceedPolicy = ShrinkFade;
1847 case Toolkit::TextView::ShrinkToFit:
1849 mLayoutParameters.mExceedPolicy = Shrink;
1854 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1859 case Toolkit::TextView::EllipsizeEnd:
1861 switch( mLayoutParameters.mHeightExceedPolicy )
1863 case Toolkit::TextView::Original:
1865 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1868 case Toolkit::TextView::EllipsizeEnd:
1870 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1875 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1882 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1887 Actor TextView::GetRootActor() const
1889 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1893 if( mVisualParameters.mSnapshotModeEnabled )
1895 rootActor = mOffscreenRootActor;
1905 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1907 std::string policyName( propertyValue.Get<std::string>() );
1908 if(policyName == "SplitByNewLineChar")
1910 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1912 else if(policyName == "SplitByWord")
1914 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1916 else if(policyName == "SplitByChar")
1918 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1922 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1926 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1928 std::string policyName( propertyValue.Get<std::string>() );
1929 if(policyName == "Original")
1931 SetWidthExceedPolicy(Toolkit::TextView::Original);
1933 else if(policyName == "Truncate")
1935 SetWidthExceedPolicy(Toolkit::TextView::Truncate);
1937 else if(policyName == "Fade")
1939 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1941 else if(policyName == "Split")
1943 SetWidthExceedPolicy(Toolkit::TextView::Split);
1945 else if(policyName == "ShrinkToFit")
1947 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1949 else if(policyName == "EllipsizeEnd")
1951 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1955 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1959 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1961 std::string policyName( propertyValue.Get<std::string>() );
1962 if(policyName == "Original")
1964 SetHeightExceedPolicy(Toolkit::TextView::Original);
1966 else if(policyName == "Truncate")
1968 SetHeightExceedPolicy(Toolkit::TextView::Truncate);
1970 else if(policyName == "Fade")
1972 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1974 else if(policyName == "Split")
1976 SetHeightExceedPolicy(Toolkit::TextView::Split);
1978 else if(policyName == "ShrinkToFit")
1980 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1984 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1988 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1990 std::string policyName( propertyValue.Get<std::string>() );
1991 if(policyName == "Left")
1993 SetLineJustification(Toolkit::TextView::Left);
1995 else if(policyName == "Center")
1997 SetLineJustification(Toolkit::TextView::Center);
1999 else if(policyName == "Right")
2001 SetLineJustification(Toolkit::TextView::Right);
2003 else if(policyName == "Justified")
2005 SetLineJustification(Toolkit::TextView::Justified);
2009 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2013 void TextView::OnFadeBoundaryPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2015 PixelSize boundary( propertyValue.Get<unsigned int>() );
2017 if ( propertyIndex == mPropertyFadeBoundaryLeft )
2019 mVisualParameters.mFadeBoundary.mLeft = boundary;
2021 else if ( propertyIndex == mPropertyFadeBoundaryRight )
2023 mVisualParameters.mFadeBoundary.mRight = boundary;
2025 else if ( propertyIndex == mPropertyFadeBoundaryTop )
2027 mVisualParameters.mFadeBoundary.mTop = boundary;
2029 else if ( propertyIndex == mPropertyFadeBoundaryBottom )
2031 mVisualParameters.mFadeBoundary.mBottom = boundary;
2035 DALI_ASSERT_ALWAYS( !"TextView::OnFadeBoundaryPropertySet(). Invalid Property value." );
2039 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2041 std::string value( propertyValue.Get<std::string>() );
2043 if( propertyIndex == mPropertyHorizontalAlignment )
2045 if(value == "HorizontalLeft")
2047 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2049 else if( value == "HorizontalCenter")
2051 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2053 else if( value == "HorizontalRight")
2055 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2059 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2062 else if( propertyIndex == mPropertyVerticalAlignment )
2064 if( value == "VerticalTop" )
2066 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2068 else if( value == "VerticalCenter")
2070 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2072 else if( value == "VerticalBottom")
2074 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2078 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2083 } // namespace Internal
2085 } // namespace Toolkit