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 const char* const PROPERTY_TEXT = "text";
42 const char* const PROPERTY_MULTILINE_POLICY = "multiline-policy";
43 const char* const PROPERTY_WIDTH_EXCEED_POLICY = "width-exceed-policy";
44 const char* const PROPERTY_HEIGHT_EXCEED_POLICY = "height-exceed-policy";
45 const char* const PROPERTY_LINE_JUSTIFICATION = "line-justification";
46 const char* const PROPERTY_FADE_BOUNDARY_LEFT = "fade-boundary-left";
47 const char* const PROPERTY_FADE_BOUNDARY_RIGHT = "fade-boundary-right";
48 const char* const PROPERTY_FADE_BOUNDARY_TOP = "fade-boundary-top";
49 const char* const PROPERTY_FADE_BOUNDARY_BOTTOM = "fade-boundary-bottom";
50 const char* const PROPERTY_LINE_HEIGHT_OFFSET = "line-height-offset";
51 const char* const PROPERTY_HORIZONTAL_ALIGNMENT = "horizontal-alignment";
52 const char* const PROPERTY_VERTICAL_ALIGNMENT = "vertical-alignment";
54 // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
55 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
60 return Toolkit::TextView::New();
63 TypeRegistration typeRegistration( typeid(Toolkit::TextView), typeid(Toolkit::Control), Create );
65 SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal );
68 * Whether the text-view-processor operation sets, inserts, replaces, removes text.
70 * @param[in] metadata The text-view-processor operation.
72 * @return \e true if the given text-view-processor operation is modifying the text.
74 bool IsTextViewProcessorRelayoutOperation( const TextView::TextViewProcessorMetadata& metadata )
76 return ( ( metadata.mType == TextView::TextSet ) ||
77 ( metadata.mType == TextView::TextInserted ) ||
78 ( metadata.mType == TextView::TextReplaced ) ||
79 ( metadata.mType == TextView::TextRemoved ) ||
80 ( metadata.mType == TextView::NewStyle ));
84 * Whether the text-view-processor operation sets a new line height offset.
86 * @param[in] metadata The text-view-processor operation.
88 * @return \e true if the given text-view-processor operation sets a new line height offset.
90 bool IsTextViewProcessorLineHeightOffsetOperation( const TextView::TextViewProcessorMetadata& metadata )
92 return ( metadata.mType == TextView::NewLineHeight );
96 * Whether the text-view-processor operation sets a new style.
98 * @param[in] metadata The text-view-processor operation.
100 * @return \e true if the given text-view-processor operation sets a new style.
102 bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMetadata& metadata )
104 return ( metadata.mType == TextView::NewStyle );
109 TextView::TextViewProcessorMetadata::TextViewProcessorMetadata()
110 : mType( TextView::TextSet ),
112 mNumberOfCharacters( 0 ),
117 Toolkit::TextView TextView::New()
119 // Create the implementation, temporarily owned on stack
120 IntrusivePtr<TextView> textView = new TextView();
122 // Pass ownership to CustomActor
123 Toolkit::TextView handle( *textView );
125 // Second-phase init of the implementation
126 // This can only be done after the CustomActor connection has been made...
127 textView->Initialize();
129 // Enables by default the offscreen rendering.
130 textView->SetSnapshotModeEnabled( false ); /// @note Temporary disabled due to some issues with text quality and glyph loading.
135 void TextView::SetText( const std::string& text )
137 // Creates a styled text with the markup or plain string.
138 MarkupProcessor::StyledTextArray styledText;
139 MarkupProcessor::GetStyledTextArray( text, styledText );
141 // Calls SetText() with the styled text array.
142 SetText( styledText );
145 void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
147 // mTextViewProcessorOperations stores the InsertTextAt and RemoveTextFrom operations to transform the initial text to mCurrentStyledText.
148 // Once again, if a new text is set, any previous call to InsertTextAt or RemoveTextFrom can be discarted.
150 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorRelayoutOperation );
151 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
153 // Creates metadata with the Set operation.
154 TextViewProcessorMetadata metadata;
155 metadata.mType = TextView::TextSet;
156 metadata.mText = text;
159 mTextViewProcessorOperations.push_back( metadata );
161 // Updates current styled text.
162 mCurrentStyledText = text;
164 // Request to be relaid out
167 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
168 mRelayoutOperations = RELAYOUT_ALL;
171 void TextView::InsertTextAt( std::size_t position, const std::string& text )
173 // Creates a styled text with the markup or plain string.
174 MarkupProcessor::StyledTextArray styledText;
175 MarkupProcessor::GetStyledTextArray( text, styledText );
177 // Calls InsertTextAt() with the styled text array.
178 InsertTextAt( position, styledText );
181 void TextView::InsertTextAt( const std::size_t position, const MarkupProcessor::StyledTextArray& text )
183 // Creates metadata with the Insert operation.
184 TextViewProcessorMetadata metadata;
185 metadata.mType = TextView::TextInserted;
186 metadata.mPosition = position;
187 metadata.mText = text;
190 mTextViewProcessorOperations.push_back( metadata );
192 // Updates current styled text.
193 mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
195 // Request to be relaid out
198 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
199 mRelayoutOperations = RELAYOUT_ALL;
202 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const std::string& text )
204 // Creates a styled text with the markup or plain string.
205 MarkupProcessor::StyledTextArray styledText;
206 MarkupProcessor::GetStyledTextArray( text, styledText );
208 // Calls ReplaceTextFromTo() with the styled text array.
209 ReplaceTextFromTo( position, numberOfCharacters, styledText );
212 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
214 // Creates metadata with the Insert operation.
215 TextViewProcessorMetadata metadata;
216 metadata.mType = TextView::TextReplaced;
217 metadata.mPosition = position;
218 metadata.mNumberOfCharacters = numberOfCharacters;
219 metadata.mText = text;
222 mTextViewProcessorOperations.push_back( metadata );
224 // Updates current styled text.
225 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
226 mCurrentStyledText.erase( it, it + numberOfCharacters );
227 it = mCurrentStyledText.begin() + position;
228 mCurrentStyledText.insert( it, text.begin(), text.end() );
230 // Request to be relaid out
233 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
234 mRelayoutOperations = RELAYOUT_ALL;
237 void TextView::RemoveTextFrom( const std::size_t position, const std::size_t numberOfCharacters )
239 // Creates metadata with the Remove operation.
240 TextViewProcessorMetadata metadata;
241 metadata.mType = TextView::TextRemoved;
242 metadata.mPosition = position;
243 metadata.mNumberOfCharacters = numberOfCharacters;
246 mTextViewProcessorOperations.push_back( metadata );
248 // Updates current styled text.
249 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
250 mCurrentStyledText.erase( it, it + numberOfCharacters );
252 // Request to be relaid out
255 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
256 mRelayoutOperations = RELAYOUT_ALL;
259 std::string TextView::GetText() const
261 // Traverses the styled text array getting only the text.
262 // Note that for some languages a 'character' could be represented by more than one 'char'
265 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); it != endIt; ++it )
267 text.append( (*it).mText.GetText() );
273 void TextView::SetLineHeightOffset( const PointSize offset )
275 if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 )
277 // Removes any previous operation which modifies the line height offset.
278 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorLineHeightOffsetOperation );
279 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
281 // Creates metadata with the new line height operation.
282 TextViewProcessorMetadata metadata;
283 metadata.mType = TextView::NewLineHeight;
285 mTextViewProcessorOperations.push_back( metadata );
287 // Updates line height offset.
288 mLayoutParameters.mLineHeightOffset = offset;
292 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
293 if( RELAYOUT_ALL != mRelayoutOperations )
295 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
296 RELAYOUT_REMOVE_TEXT_ACTORS |
297 RELAYOUT_SIZE_POSITION |
299 RELAYOUT_VISIBILITY |
300 RELAYOUT_TEXT_ACTOR_UPDATE |
301 RELAYOUT_INSERT_TO_TEXT_VIEW |
302 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
307 PointSize TextView::GetLineHeightOffset() const
309 return PointSize( mLayoutParameters.mLineHeightOffset );
312 void TextView::SetStyleToCurrentText( const TextStyle& style, const TextStyle::Mask mask )
314 if( !mCurrentStyledText.empty() )
316 const bool checkFontName = mask & TextStyle::FONT;
317 const bool checkFontSize = mask & TextStyle::SIZE;
318 const bool checkFontStyle = mask & TextStyle::STYLE;
320 // Check first if metrics have changed.
321 bool metricsChanged = false;
322 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
324 const MarkupProcessor::StyledText& styledText( *it );
326 metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
327 ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
328 ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
333 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
335 // If metrics change, new text measurements are needed.
336 SetText( mCurrentStyledText );
340 // Deletes any previous operation which sets a new style.
341 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
342 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
344 // Creates metadata with the new style operation.
345 TextViewProcessorMetadata metadata;
346 metadata.mType = TextView::NewStyle;
348 MarkupProcessor::StyledText text;
350 metadata.mText.push_back( text );
351 metadata.mStyleMask = mask;
353 mTextViewProcessorOperations.push_back( metadata );
355 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
359 if( RELAYOUT_ALL != mRelayoutOperations )
361 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
362 RELAYOUT_TEXT_ACTOR_UPDATE );
367 // Sets the new style to the ellipsize text
368 if( !mLayoutParameters.mEllipsizeText.empty() )
370 for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
372 (*it).mStyle.Copy( style, mask );
375 SetEllipsizeText( mLayoutParameters.mEllipsizeText );
379 void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
381 if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
383 Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
384 ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
385 ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
386 Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
387 ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
388 ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
390 mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
391 mLayoutParameters.mVerticalAlignment = verticalAlignment;
395 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
396 if( RELAYOUT_ALL != mRelayoutOperations )
398 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
399 RELAYOUT_TEXT_ACTOR_UPDATE |
401 RELAYOUT_VISIBILITY );
406 Toolkit::Alignment::Type TextView::GetTextAlignment() const
408 return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
411 void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
413 if( policy != mLayoutParameters.mMultilinePolicy )
415 mLayoutParameters.mMultilinePolicy = policy;
417 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
418 mRelayoutOperations = RELAYOUT_ALL;
424 Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
426 return mLayoutParameters.mMultilinePolicy;
429 void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
431 // The layout info could be invalid depending on the current exceed policy and the new one.
432 // i.e. if the current policy is Split and the new one is ShrinkToFit then
433 // the layout info generated for each char is not needed.
434 if( policy != mLayoutParameters.mWidthExceedPolicy )
436 mLayoutParameters.mWidthExceedPolicy = policy;
438 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
439 mRelayoutOperations = RELAYOUT_ALL;
445 Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
447 return mLayoutParameters.mWidthExceedPolicy;
450 void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
452 if( policy != mLayoutParameters.mHeightExceedPolicy )
454 mLayoutParameters.mHeightExceedPolicy = policy;
458 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
459 if( RELAYOUT_ALL != mRelayoutOperations )
461 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
462 RELAYOUT_REMOVE_TEXT_ACTORS |
463 RELAYOUT_SIZE_POSITION |
465 RELAYOUT_VISIBILITY |
466 RELAYOUT_TEXT_ACTOR_UPDATE |
467 RELAYOUT_INSERT_TO_TEXT_VIEW |
468 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
473 Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
475 return mLayoutParameters.mHeightExceedPolicy;
478 void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
480 if( justification != mLayoutParameters.mLineJustification )
482 mLayoutParameters.mLineJustification = justification;
486 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
487 if( RELAYOUT_ALL != mRelayoutOperations )
489 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
490 RELAYOUT_REMOVE_TEXT_ACTORS |
491 RELAYOUT_SIZE_POSITION |
493 RELAYOUT_VISIBILITY |
494 RELAYOUT_TEXT_ACTOR_UPDATE |
495 RELAYOUT_INSERT_TO_TEXT_VIEW |
496 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
501 Toolkit::TextView::LineJustification TextView::GetLineJustification() const
503 return mLayoutParameters.mLineJustification;
506 void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
508 if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
509 ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
510 ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
511 ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
513 mVisualParameters.mFadeBoundary = fadeBoundary;
517 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
518 if( RELAYOUT_ALL != mRelayoutOperations )
520 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
521 RELAYOUT_REMOVE_TEXT_ACTORS |
522 RELAYOUT_VISIBILITY |
523 RELAYOUT_TEXT_ACTOR_UPDATE |
524 RELAYOUT_INSERT_TO_TEXT_VIEW |
525 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
530 const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
532 return mVisualParameters.mFadeBoundary;
535 void TextView::SetEllipsizeText( const std::string& ellipsizeText )
537 // Creates a styled text with the markup or plain string.
538 MarkupProcessor::StyledTextArray styledText;
539 MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText );
541 SetEllipsizeText( styledText );
544 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
546 mLayoutParameters.mEllipsizeText = ellipsizeText;
548 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
550 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
551 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
553 // Request to be relaid out
556 mRelayoutOperations = RELAYOUT_ALL;
559 std::string TextView::GetEllipsizeText() const
562 for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
564 text.append( (*it).mText.GetText() );
570 void TextView::GetTextLayoutInfo()
572 const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
573 const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
574 const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
576 if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
578 Vector3 textViewSize = GetControlSize();
580 if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
581 ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
582 ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
583 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
584 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
586 // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
587 // the text natural size can be used.
588 textViewSize = GetNaturalSize();
591 if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
592 ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
594 // Check if the text-view has text-actors.
595 const bool hasTextActors = !mRelayoutData.mTextActors.empty();
597 RelayoutOperationMask mask = NO_RELAYOUT;
598 if( relayoutSizeAndPositionNeeded )
600 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
602 if( relayoutAlignmentNeeded )
604 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
606 if( relayoutVisibilityNeeded )
608 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
613 // Remove text-actors from the text-view as some text-operation like CreateTextInfo()
614 // add them to the text-actor cache.
615 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
616 mRelayoutData.mTextActors.clear();
619 // Relays-out but doesn't add text-actors to the text-view.
620 DoRelayOut( textViewSize.GetVectorXY(), mask );
624 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
625 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
632 void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
636 textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
637 textLayoutInfo.mLines = mRelayoutData.mLines;
639 textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
640 textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
642 textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
644 textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
647 void TextView::SetSortModifier( float depthOffset )
649 mVisualParameters.mSortModifier = depthOffset;
651 for( std::vector<TextActor>::iterator it = mRelayoutData.mTextActors.begin(), endIt = mRelayoutData.mTextActors.end();
655 ( *it ).SetSortModifier( depthOffset );
658 if( mOffscreenImageActor )
660 mOffscreenImageActor.SetSortModifier( depthOffset );
664 void TextView::SetSnapshotModeEnabled( bool enable )
666 if( enable != mVisualParameters.mSnapshotModeEnabled )
668 // Remove first all text-actors
669 if( !mRelayoutData.mTextActors.empty() )
671 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
674 mVisualParameters.mSnapshotModeEnabled = enable;
675 if( !mLockPreviousSnapshotMode )
677 // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
678 // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
680 // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
681 // to smash the stored value.
682 mPreviousSnapshotModeEnabled = enable;
685 if( mVisualParameters.mSnapshotModeEnabled )
687 // Create a root actor and an image actor for offscreen rendering.
688 mOffscreenRootActor = Layer::New();
689 mOffscreenImageActor = ImageActor::New();
691 mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
692 mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
693 mOffscreenRootActor.SetInheritRotation( false );
694 mOffscreenRootActor.SetInheritScale( false );
695 mOffscreenRootActor.SetDepthTestDisabled( true );
697 mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
699 mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
700 mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
703 self.Add( mOffscreenRootActor );
704 self.Add( mOffscreenImageActor );
710 if( mOffscreenRootActor )
712 self.Remove( mOffscreenRootActor );
715 if( mOffscreenImageActor )
717 self.Remove( mOffscreenImageActor );
720 DestroyOffscreenRenderingResources();
723 if( RELAYOUT_ALL != mRelayoutOperations )
725 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
726 RELAYOUT_REMOVE_TEXT_ACTORS |
727 RELAYOUT_TEXT_ACTOR_UPDATE |
728 RELAYOUT_INSERT_TO_TEXT_VIEW |
729 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
735 bool TextView::IsSnapshotModeEnabled() const
737 return mVisualParameters.mSnapshotModeEnabled;
740 void TextView::SetScrollEnabled( const bool enable )
742 if( enable != mVisualParameters.mScrollEnabled )
744 mVisualParameters.mScrollEnabled = enable;
746 if( mVisualParameters.mScrollEnabled )
748 // Offscreen rendering is needed to enable text scroll.
750 // Stores previous value of the snapshot mode.
751 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
754 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
755 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
756 Lock lock( mLockPreviousSnapshotMode );
757 SetSnapshotModeEnabled( true );
760 // Creates the pan gesture detector and attach the text-view.
761 mPanGestureDetector = PanGestureDetector::New();
762 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
763 mPanGestureDetector.Attach( Self() );
767 // Removes the pan gesture detector.
768 if( mPanGestureDetector )
770 mPanGestureDetector.Detach( Self() );
771 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
772 mPanGestureDetector.Reset();
775 // Restores the previous state for snapshot mode.
776 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
781 bool TextView::IsScrollEnabled() const
783 return mVisualParameters.mScrollEnabled;
786 void TextView::SetScrollPosition( const Vector2& position )
788 if( position != mVisualParameters.mCameraScrollPosition )
790 // Guard against destruction during signal emission
791 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
792 Toolkit::TextView handle( GetOwner() );
794 DoSetScrollPosition( position );
796 // Check if the new scroll position has been trimmed.
797 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
801 const Vector2& TextView::GetScrollPosition() const
803 return mVisualParameters.mCameraScrollPosition;
806 bool TextView::IsScrollPositionTrimmed() const
808 return mVisualParameters.mScrollPositionTrimmed;
811 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
813 return mScrolledSignalV2;
816 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
818 Dali::BaseHandle handle( object );
820 bool connected( true );
821 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
823 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
825 textView.ScrolledSignal().Connect( tracker, functor );
829 // signalName does not match any signal
836 TextView::LayoutParameters::LayoutParameters()
837 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
838 mWidthExceedPolicy( Toolkit::TextView::Original ),
839 mHeightExceedPolicy( Toolkit::TextView::Original ),
840 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
841 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
842 mLineJustification( Toolkit::TextView::Left ),
843 mLineHeightOffset( 0.f ),
846 // Sets ellipsize text
847 MarkupProcessor::StyledTextArray styledEllipsize;
848 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText );
851 TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::MultilinePolicy multilinePolicy,
852 const Toolkit::TextView::ExceedPolicy widthExceedPolicy,
853 const Toolkit::TextView::ExceedPolicy heightExceedPolicy,
854 const Toolkit::Alignment::Type alignmentType,
855 const Toolkit::TextView::LineJustification lineJustification,
856 const float lineHeightOffset,
857 const std::string& ellipsizeText )
858 : mMultilinePolicy( multilinePolicy ),
859 mWidthExceedPolicy( widthExceedPolicy ),
860 mHeightExceedPolicy( heightExceedPolicy ),
861 mHorizontalAlignment(),
862 mVerticalAlignment(),
863 mLineJustification( lineJustification ),
864 mLineHeightOffset( lineHeightOffset ),
868 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
869 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
870 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
871 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
872 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
873 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
875 mHorizontalAlignment = horizontalAlignment;
876 mVerticalAlignment = verticalAlignment;
878 // Sets ellipsize text
879 MarkupProcessor::StyledTextArray styledEllipsize;
880 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText );
883 TextView::LayoutParameters::LayoutParameters( 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 )
895 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
897 mMultilinePolicy = layoutParameters.mMultilinePolicy;
898 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
899 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
900 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
901 mVerticalAlignment = layoutParameters.mVerticalAlignment;
902 mLineJustification = layoutParameters.mLineJustification;
903 mLineHeightOffset = layoutParameters.mLineHeightOffset;
904 mEllipsizeText = layoutParameters.mEllipsizeText;
909 TextView::VisualParameters::VisualParameters()
911 mSortModifier( 0.f ),
912 mCameraScrollPosition( 0.f, 0.f ),
913 mSnapshotModeEnabled( false ),
914 mScrollEnabled( false ),
915 mScrollPositionTrimmed( false )
919 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
920 : mFadeBoundary( visualParameters.mFadeBoundary ),
921 mSortModifier( visualParameters.mSortModifier ),
922 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
923 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
924 mScrollEnabled( visualParameters.mScrollEnabled ),
925 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
929 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
931 mFadeBoundary = visualParameters.mFadeBoundary;
932 mSortModifier = visualParameters.mSortModifier;
933 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
934 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
935 mScrollEnabled = visualParameters.mScrollEnabled;
936 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
941 TextView::RelayoutData::RelayoutData()
943 mShrinkFactor( 1.f ),
945 mCharacterLogicalToVisualMap(),
946 mCharacterVisualToLogicalMap(),
948 mCharacterLayoutInfoTable(),
950 mTextSizeForRelayoutOption()
954 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
955 : mTextViewSize( relayoutData.mTextViewSize ),
956 mShrinkFactor( relayoutData.mShrinkFactor ),
957 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
958 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
959 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
960 mTextActors( relayoutData.mTextActors ),
961 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
962 mLines( relayoutData.mLines ),
963 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
967 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
969 mTextViewSize = relayoutData.mTextViewSize;
970 mShrinkFactor = relayoutData.mShrinkFactor;
971 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
972 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
973 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
974 mTextActors = relayoutData.mTextActors;
975 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
976 mLines = relayoutData.mLines;
977 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
983 : ControlImpl( false ), // doesn't require touch events
984 mCurrentStyledText(),
985 mTextViewProcessorOperations(),
986 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
987 Toolkit::TextView::Original,
988 Toolkit::TextView::Original,
989 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
990 Toolkit::TextView::Left,
992 std::string( "..." ) ),
995 mRelayoutOperations( NO_RELAYOUT ),
996 mOffscreenRootActor(),
997 mOffscreenImageActor(),
998 mOffscreenCameraActor(),
999 mCurrentOffscreenSize(),
1000 mFrameBufferImage(),
1002 mPanGestureDetector(),
1003 mLockPreviousSnapshotMode( false ),
1004 mPreviousSnapshotModeEnabled( false )
1006 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1007 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1010 TextView::~TextView()
1012 // Destroys offscreen rendering resources.
1013 DestroyOffscreenRenderingResources();
1015 // Destroys scroll pan gesture detector.
1016 if( mPanGestureDetector )
1018 mPanGestureDetector.Reset();
1022 Vector3 TextView::GetNaturalSize()
1024 if( !mTextViewProcessorOperations.empty() )
1026 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1028 if( !mRelayoutData.mTextActors.empty() )
1030 // Remove text-actors from the text-view as some text-operation like CreateTextInfo()
1031 // add them to the text-actor cache.
1032 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
1033 mRelayoutData.mTextActors.clear();
1035 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1036 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1039 PerformTextViewProcessorOperations();
1042 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1045 float TextView::GetHeightForWidth( float width )
1049 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1050 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1051 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1053 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1054 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1055 height = GetNaturalSize().height;
1059 // Check if the given width is different than the current one.
1060 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1062 // Check if the text-view has text-actors.
1063 const bool hasTextActors = !mRelayoutData.mTextActors.empty();
1065 // Check which layout operations need to be done.
1066 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1068 if( relayoutSizeAndPositionNeeded )
1072 // Remove text-actors from the text-view as some text-operation like CreateTextInfo()
1073 // add them to the text-actor cache.
1074 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
1075 mRelayoutData.mTextActors.clear();
1078 // Use the given width.
1079 const Vector2 textViewSize( width, GetControlSize().height );
1081 // Relays-out but doesn't add text-actors to the text-view.
1082 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1085 // Retrieve the text height after relayout the text.
1086 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1088 if( differentWidth )
1090 // Revert the relayout operation mask
1091 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1096 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1097 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1100 if( differentWidth || hasTextActors )
1109 float TextView::GetWidthForHeight( float height )
1111 // TODO: Needs implementing properly, for now just return the natural width.
1112 return GetNaturalSize().width;
1115 void TextView::OnPropertySet( Property::Index index, Property::Value propertyValue )
1117 if( index == mPropertyText )
1119 SetText(propertyValue.Get<std::string>());
1121 else if( index == mPropertyMultilinePolicy )
1123 OnMultilinePolicyPropertySet(propertyValue);
1125 else if( index == mPropertyWidthExceedPolicy )
1127 OnWidthExceedPolicyPropertySet(propertyValue);
1129 else if( index == mPropertyHeightExceedPolicy )
1131 OnHeightExceedPolicyPropertySet(propertyValue);
1133 else if( index == mPropertyLineJustification )
1135 OnLineJustificationPropertySet(propertyValue);
1137 else if( ( index == mPropertyFadeBoundaryLeft ) ||
1138 ( index == mPropertyFadeBoundaryRight ) ||
1139 ( index == mPropertyFadeBoundaryTop ) ||
1140 ( index == mPropertyFadeBoundaryBottom ) )
1142 OnFadeBoundaryPropertySet( index, propertyValue );
1144 else if( index == mPropertyLineHeightOffset )
1146 Dali::PointSize pointSize( propertyValue.Get<float>() );
1147 SetLineHeightOffset(pointSize);
1149 else if ( ( index == mPropertyHorizontalAlignment ) ||
1150 ( index == mPropertyVerticalAlignment ) )
1152 OnAlignmentPropertySet( index, propertyValue );
1156 void TextView::OnInitialize()
1158 Actor self = Self();
1160 mPropertyText = self.RegisterProperty( PROPERTY_TEXT, "", Property::READ_WRITE );
1162 mPropertyMultilinePolicy = self.RegisterProperty( PROPERTY_MULTILINE_POLICY, "SplitByNewLineChar", Property::READ_WRITE );
1164 mPropertyWidthExceedPolicy = self.RegisterProperty( PROPERTY_WIDTH_EXCEED_POLICY, "Original", Property::READ_WRITE );
1166 mPropertyHeightExceedPolicy = self.RegisterProperty( PROPERTY_HEIGHT_EXCEED_POLICY, "Original", Property::READ_WRITE );
1168 mPropertyLineJustification = self.RegisterProperty( PROPERTY_LINE_JUSTIFICATION, "Left", Property::READ_WRITE );
1170 mPropertyFadeBoundaryLeft = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_LEFT, static_cast< int >( 0 ), Property::READ_WRITE );
1172 mPropertyFadeBoundaryRight = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_RIGHT, static_cast< int >( 0 ), Property::READ_WRITE );
1174 mPropertyFadeBoundaryTop = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_TOP, static_cast< int >( 0 ), Property::READ_WRITE );
1176 mPropertyFadeBoundaryBottom = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_BOTTOM, static_cast< int >( 0 ), Property::READ_WRITE );
1178 mPropertyLineHeightOffset = self.RegisterProperty( PROPERTY_LINE_HEIGHT_OFFSET, 0.0f, Property::READ_WRITE );
1180 mPropertyHorizontalAlignment = self.RegisterProperty( PROPERTY_HORIZONTAL_ALIGNMENT, "HorizontalCenter", Property::READ_WRITE );
1182 mPropertyVerticalAlignment = self.RegisterProperty( PROPERTY_VERTICAL_ALIGNMENT, "VerticalCenter", Property::READ_WRITE );
1187 void TextView::OnStyleChange( StyleChange change )
1189 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1190 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1191 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1193 SetText( mCurrentStyledText );
1196 void TextView::OnControlSizeSet( const Vector3& size )
1198 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1200 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1201 mRelayoutOperations = RELAYOUT_ALL;
1203 // Request to be relaid out
1208 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1210 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1212 // Not worth to relayout if width or height is equal to zero.
1216 if( size != mRelayoutData.mTextViewSize )
1218 // if new size is different than the prevoius one, set positions and maybe sizes of all text-actor is needed.
1219 if( RELAYOUT_ALL != mRelayoutOperations )
1221 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1222 RELAYOUT_REMOVE_TEXT_ACTORS |
1223 RELAYOUT_SIZE_POSITION |
1224 RELAYOUT_ALIGNMENT |
1225 RELAYOUT_VISIBILITY |
1226 RELAYOUT_TEXT_ACTOR_UPDATE |
1227 RELAYOUT_INSERT_TO_TEXT_VIEW |
1228 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1232 // Remove text-actors from text-view
1233 if( !mRelayoutData.mTextActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1235 TextViewRelayout::RemoveTextActors( GetRootActor(), mRelayoutData.mTextActors );
1236 mRelayoutData.mTextActors.clear();
1239 if( NO_RELAYOUT != mRelayoutOperations )
1241 // Relays-out and add text-actors to the text-view.
1242 DoRelayOut( size, mRelayoutOperations );
1243 ProcessSnapshot( size );
1246 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1247 mRelayoutData.mTextActorCache.ClearTexts();
1250 void TextView::PerformTextViewProcessorOperations()
1252 // Traverse the relayout operation vector ...
1254 // Optimizes some operations.
1255 OptimizeTextViewProcessorOperations();
1257 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1259 const TextViewProcessorMetadata& relayoutMetadata( *it );
1261 switch( relayoutMetadata.mType )
1263 case TextView::TextSet:
1265 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1270 case TextView::TextInserted:
1272 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1273 relayoutMetadata.mText,
1278 case TextView::TextReplaced:
1280 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1281 relayoutMetadata.mNumberOfCharacters,
1282 relayoutMetadata.mText,
1287 case TextView::TextRemoved:
1289 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1290 relayoutMetadata.mNumberOfCharacters,
1293 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1296 case TextView::NewLineHeight:
1298 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1299 mRelayoutData.mTextLayoutInfo );
1302 case TextView::NewStyle:
1304 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1305 relayoutMetadata.mStyleMask,
1312 // Clear all operations when they are done.
1313 mTextViewProcessorOperations.clear();
1316 void TextView::OptimizeTextViewProcessorOperations()
1318 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1320 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1321 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1322 // use the cache without clearing the text-actors.
1324 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1326 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1328 const TextViewProcessorMetadata& relayoutMetadata( *it );
1330 switch( relayoutMetadata.mType )
1332 case TextView::TextRemoved:
1334 bool optimizationDone = false;
1336 if( it + 1 != endIt )
1338 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1339 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1341 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1343 optimizationDone = true;
1344 TextViewProcessorMetadata newRelayoutMetadata;
1345 newRelayoutMetadata.mType = TextView::TextReplaced;
1346 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1347 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1348 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1349 textViewProcessorOperations.push_back( newRelayoutMetadata );
1351 // do not access the TextInserted operation in next iteration.
1357 if( !optimizationDone )
1359 textViewProcessorOperations.push_back( relayoutMetadata );
1365 textViewProcessorOperations.push_back( relayoutMetadata );
1370 mTextViewProcessorOperations = textViewProcessorOperations;
1373 void TextView::DoRelayOut( const Size& textViewSize, const RelayoutOperationMask relayoutOperationMask )
1375 // Traverse the relayout operation vector. It fills the natural size, layout and text-actor data structures.
1376 if( !mTextViewProcessorOperations.empty() )
1378 PerformTextViewProcessorOperations();
1381 CombineExceedPolicies();
1384 if( mVisualParameters.mSnapshotModeEnabled )
1386 rootActor = mOffscreenRootActor;
1393 mRelayoutData.mTextViewSize = textViewSize;
1394 switch( mLayoutParameters.mMultilinePolicy )
1396 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1398 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1400 } // SplitByNewLineChar
1402 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1404 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1408 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1410 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1413 } // switch( mMultilinePolicy )
1415 // Remove done operations from the mask.
1416 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1419 void TextView::ProcessSnapshot( const Size& textViewSize )
1421 if( mVisualParameters.mSnapshotModeEnabled )
1423 // If layout options change, it's needed generate a new image.
1425 if( mOffscreenRootActor )
1427 // Set the root actor visible.
1428 // The root actor is set to non visible after the render task is processed.
1429 mOffscreenRootActor.SetVisible( true );
1431 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1432 mOffscreenRootActor.SetSize( textViewSize );
1435 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1436 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1438 // Set the image actor visible.
1439 // The image actor is set to non visible if there is no text to render.
1440 mOffscreenImageActor.SetVisible( true );
1442 // Calculates the offscreen image's size. It takes into account different points:
1443 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1444 // * There is a maximum texture size the graphic subsystem can load on the memory.
1445 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1447 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1448 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1449 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1450 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1452 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1456 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1457 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1458 offscreenSize.height,
1461 // Stores current text-view size to avoid create new Dali resources if text changes.
1462 mCurrentOffscreenSize = offscreenSize;
1464 if( !mOffscreenCameraActor )
1466 // Creates a new camera actor.
1467 mOffscreenCameraActor = CameraActor::New();
1468 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1469 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1471 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1473 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1475 // Images are expected to be from top to bottom, but OpenGL buffers are bottom to top
1476 mOffscreenCameraActor.SetInvertYAxis( false );
1479 // Calculate camera parameters for current text size.
1480 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1483 if( mVisualParameters.mScrollEnabled )
1485 // Updates the offscreen camera position with the new scroll offset.
1486 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1487 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1491 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1492 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1497 // Creates a new render task.
1498 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1500 mRenderTask.SetSourceActor( mOffscreenRootActor );
1501 mRenderTask.SetInputEnabled( false );
1502 mRenderTask.SetClearColor( Color::TRANSPARENT );
1503 mRenderTask.SetClearEnabled( true );
1504 mRenderTask.SetExclusive( true );
1506 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1507 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1512 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1513 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1516 // Process the render task only once every time the text changes or the text-view's size canges.
1517 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1521 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1522 mOffscreenImageActor.SetVisible( false );
1527 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1529 float xPosition = 0.f;
1530 float yPosition = 0.f;
1531 Vector3 parentOrigin = ParentOrigin::CENTER;
1532 Vector3 anchorPoint = AnchorPoint::CENTER;
1534 switch( mLayoutParameters.mHorizontalAlignment )
1536 case Toolkit::Alignment::HorizontalLeft:
1538 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1539 parentOrigin.x = 0.f;
1540 anchorPoint.x = 0.f;
1543 case Toolkit::Alignment::HorizontalCenter:
1548 case Toolkit::Alignment::HorizontalRight:
1550 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1551 parentOrigin.x = 1.f;
1552 anchorPoint.x = 1.f;
1557 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1561 switch( mLayoutParameters.mVerticalAlignment )
1563 case Toolkit::Alignment::VerticalTop:
1565 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1566 parentOrigin.y = 0.f;
1567 anchorPoint.y = 0.f;
1570 case Toolkit::Alignment::VerticalCenter:
1575 case Toolkit::Alignment::VerticalBottom:
1577 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1578 parentOrigin.y = 1.f;
1579 anchorPoint.y = 1.f;
1584 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1588 mOffscreenCameraActor.SetX( xPosition );
1589 mOffscreenCameraActor.SetY( yPosition );
1591 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1592 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1595 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1597 // not to process the offscreen root actor by setting its visibility to false.
1598 mOffscreenRootActor.SetVisible( false );
1600 // Sets the new size and the new frame buffer to the image actor.
1601 // Image actor must have same size as text. Otherwise text can be truncated.
1602 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1603 mOffscreenImageActor.SetImage( mFrameBufferImage );
1606 void TextView::DestroyOffscreenRenderingResources()
1610 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1612 if( Stage::IsInstalled() )
1614 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1617 mRenderTask.Reset();
1620 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1621 if( mOffscreenCameraActor )
1623 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1625 mOffscreenCameraActor.Reset();
1628 if( mOffscreenRootActor )
1630 mOffscreenRootActor.Reset();
1633 if( mOffscreenImageActor )
1635 mOffscreenImageActor.Reset();
1638 mCurrentOffscreenSize = Size( 0.f, 0.f );
1640 if( mFrameBufferImage )
1642 mFrameBufferImage.Reset();
1646 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1648 if( 1u == gesture.numberOfTouches )
1650 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1654 void TextView::TrimScrollPosition()
1656 const Vector3& textViewSize = GetControlSize();
1658 // Before use the text's size, relayout the text is needed to get the actual text size.
1659 GetTextLayoutInfo();
1661 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1662 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1663 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1664 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1665 float minVerticalDisplacement = -maxVerticalDisplacement;
1667 // Updates the range if the text is aligned on the right or left.
1668 switch( mLayoutParameters.mHorizontalAlignment )
1670 case Toolkit::Alignment::HorizontalLeft:
1672 maxHorizontalDisplacement *= 2.f;
1673 minHorizontalDisplacement = 0.f;
1676 case Toolkit::Alignment::HorizontalCenter:
1681 case Toolkit::Alignment::HorizontalRight:
1683 maxHorizontalDisplacement = 0.f;
1684 minHorizontalDisplacement *= 2.f;
1689 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1693 // Updates the range if the text is aligned on the top or bottom.
1694 switch( mLayoutParameters.mVerticalAlignment )
1696 case Toolkit::Alignment::VerticalTop:
1698 maxVerticalDisplacement *= 2.f;
1699 minVerticalDisplacement = 0.f;
1702 case Toolkit::Alignment::VerticalCenter:
1707 case Toolkit::Alignment::VerticalBottom:
1709 maxVerticalDisplacement = 0.f;
1710 minVerticalDisplacement *= 2.f;
1715 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1719 // Trims the scroll position to be within the range.
1720 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1721 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1723 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1724 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1727 void TextView::DoSetScrollPosition( const Vector2& position )
1729 // Stores old scroll position.
1730 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1732 // Updates the scroll position
1733 mVisualParameters.mCameraScrollPosition = position;
1735 // Ensures the text-view is covered with text.
1736 TrimScrollPosition();
1738 // Calculate the difference with the previous scroll position
1739 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1740 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1742 if( mOffscreenRootActor )
1744 // If there is a render-task it needs to be refreshed. Therefore text-actors need to be
1746 mOffscreenRootActor.SetVisible( true );
1749 if( mOffscreenCameraActor )
1751 // Update the offscreen camera with the new scroll position.
1752 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1753 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1758 // Refresh the render-task.
1759 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1763 Toolkit::TextView handle( GetOwner() );
1764 mScrolledSignalV2.Emit( handle, delta );
1767 void TextView::CombineExceedPolicies()
1769 // Calculates the combination of exceed policies.
1771 switch( mLayoutParameters.mWidthExceedPolicy )
1773 case Toolkit::TextView::Original:
1775 switch( mLayoutParameters.mHeightExceedPolicy )
1777 case Toolkit::TextView::Original:
1779 mLayoutParameters.mExceedPolicy = Original;
1782 case Toolkit::TextView::Fade:
1784 mLayoutParameters.mExceedPolicy = OriginalFade;
1787 case Toolkit::TextView::ShrinkToFit:
1789 mLayoutParameters.mExceedPolicy = OriginalShrink;
1794 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1799 case Toolkit::TextView::Split:
1801 switch( mLayoutParameters.mHeightExceedPolicy )
1803 case Toolkit::TextView::Original:
1805 mLayoutParameters.mExceedPolicy = SplitOriginal;
1808 case Toolkit::TextView::Fade:
1810 mLayoutParameters.mExceedPolicy = SplitFade;
1813 case Toolkit::TextView::ShrinkToFit:
1815 mLayoutParameters.mExceedPolicy = SplitShrink;
1820 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1825 case Toolkit::TextView::Fade:
1827 switch( mLayoutParameters.mHeightExceedPolicy )
1829 case Toolkit::TextView::Original:
1831 mLayoutParameters.mExceedPolicy = FadeOriginal;
1834 case Toolkit::TextView::Fade:
1836 mLayoutParameters.mExceedPolicy = Fade;
1841 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1846 case Toolkit::TextView::ShrinkToFit:
1848 switch( mLayoutParameters.mHeightExceedPolicy )
1850 case Toolkit::TextView::Original:
1852 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1855 case Toolkit::TextView::Fade:
1857 mLayoutParameters.mExceedPolicy = ShrinkFade;
1860 case Toolkit::TextView::ShrinkToFit:
1862 mLayoutParameters.mExceedPolicy = Shrink;
1867 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1872 case Toolkit::TextView::EllipsizeEnd:
1874 switch( mLayoutParameters.mHeightExceedPolicy )
1876 case Toolkit::TextView::Original:
1878 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1881 case Toolkit::TextView::EllipsizeEnd:
1883 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1888 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1895 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1900 Actor TextView::GetRootActor() const
1902 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1906 if( mVisualParameters.mSnapshotModeEnabled )
1908 rootActor = mOffscreenRootActor;
1918 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1920 std::string policyName( propertyValue.Get<std::string>() );
1921 if(policyName == "SplitByNewLineChar")
1923 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1925 else if(policyName == "SplitByWord")
1927 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1929 else if(policyName == "SplitByChar")
1931 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1935 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1939 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1941 std::string policyName( propertyValue.Get<std::string>() );
1942 if(policyName == "Original")
1944 SetWidthExceedPolicy(Toolkit::TextView::Original);
1946 else if(policyName == "Truncate")
1948 SetWidthExceedPolicy(Toolkit::TextView::Truncate);
1950 else if(policyName == "Fade")
1952 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1954 else if(policyName == "Split")
1956 SetWidthExceedPolicy(Toolkit::TextView::Split);
1958 else if(policyName == "ShrinkToFit")
1960 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1962 else if(policyName == "EllipsizeEnd")
1964 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1968 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1972 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1974 std::string policyName( propertyValue.Get<std::string>() );
1975 if(policyName == "Original")
1977 SetHeightExceedPolicy(Toolkit::TextView::Original);
1979 else if(policyName == "Truncate")
1981 SetHeightExceedPolicy(Toolkit::TextView::Truncate);
1983 else if(policyName == "Fade")
1985 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1987 else if(policyName == "Split")
1989 SetHeightExceedPolicy(Toolkit::TextView::Split);
1991 else if(policyName == "ShrinkToFit")
1993 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1997 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
2001 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
2003 std::string policyName( propertyValue.Get<std::string>() );
2004 if(policyName == "Left")
2006 SetLineJustification(Toolkit::TextView::Left);
2008 else if(policyName == "Center")
2010 SetLineJustification(Toolkit::TextView::Center);
2012 else if(policyName == "Right")
2014 SetLineJustification(Toolkit::TextView::Right);
2016 else if(policyName == "Justified")
2018 SetLineJustification(Toolkit::TextView::Justified);
2022 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2026 void TextView::OnFadeBoundaryPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2028 PixelSize boundary( propertyValue.Get<unsigned int>() );
2030 if ( propertyIndex == mPropertyFadeBoundaryLeft )
2032 mVisualParameters.mFadeBoundary.mLeft = boundary;
2034 else if ( propertyIndex == mPropertyFadeBoundaryRight )
2036 mVisualParameters.mFadeBoundary.mRight = boundary;
2038 else if ( propertyIndex == mPropertyFadeBoundaryTop )
2040 mVisualParameters.mFadeBoundary.mTop = boundary;
2042 else if ( propertyIndex == mPropertyFadeBoundaryBottom )
2044 mVisualParameters.mFadeBoundary.mBottom = boundary;
2048 DALI_ASSERT_ALWAYS( !"TextView::OnFadeBoundaryPropertySet(). Invalid Property value." );
2052 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2054 std::string value( propertyValue.Get<std::string>() );
2056 if( propertyIndex == mPropertyHorizontalAlignment )
2058 if(value == "HorizontalLeft")
2060 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2062 else if( value == "HorizontalCenter")
2064 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2066 else if( value == "HorizontalRight")
2068 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2072 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2075 else if( propertyIndex == mPropertyVerticalAlignment )
2077 if( value == "VerticalTop" )
2079 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2081 else if( value == "VerticalCenter")
2083 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2085 else if( value == "VerticalBottom")
2087 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2091 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2096 } // namespace Internal
2098 } // namespace Toolkit