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 glyph-actors.
595 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.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 glyph-actors from the text-view as some text-operation like CreateTextInfo()
614 // add them to the text-actor cache.
615 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
616 mRelayoutData.mGlyphActors.clear();
619 // Relays-out but doesn't add glyph-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<RenderableActor>::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.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 glyph-actors
669 if( !mRelayoutData.mGlyphActors.empty() )
671 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
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 );
705 mOffscreenImageActor.SetScale(Vector3(1.f, -1.f, 1.f));
711 if( mOffscreenRootActor )
713 self.Remove( mOffscreenRootActor );
716 if( mOffscreenImageActor )
718 self.Remove( mOffscreenImageActor );
721 DestroyOffscreenRenderingResources();
724 if( RELAYOUT_ALL != mRelayoutOperations )
726 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
727 RELAYOUT_REMOVE_TEXT_ACTORS |
728 RELAYOUT_TEXT_ACTOR_UPDATE |
729 RELAYOUT_INSERT_TO_TEXT_VIEW |
730 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
736 bool TextView::IsSnapshotModeEnabled() const
738 return mVisualParameters.mSnapshotModeEnabled;
741 void TextView::SetScrollEnabled( const bool enable )
743 if( enable != mVisualParameters.mScrollEnabled )
745 mVisualParameters.mScrollEnabled = enable;
747 if( mVisualParameters.mScrollEnabled )
749 // Offscreen rendering is needed to enable text scroll.
751 // Stores previous value of the snapshot mode.
752 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
755 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
756 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
757 Lock lock( mLockPreviousSnapshotMode );
758 SetSnapshotModeEnabled( true );
761 // Creates the pan gesture detector and attach the text-view.
762 mPanGestureDetector = PanGestureDetector::New();
763 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
764 mPanGestureDetector.Attach( Self() );
768 // Removes the pan gesture detector.
769 if( mPanGestureDetector )
771 mPanGestureDetector.Detach( Self() );
772 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
773 mPanGestureDetector.Reset();
776 // Restores the previous state for snapshot mode.
777 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
782 bool TextView::IsScrollEnabled() const
784 return mVisualParameters.mScrollEnabled;
787 void TextView::SetScrollPosition( const Vector2& position )
789 if( position != mVisualParameters.mCameraScrollPosition )
791 // Guard against destruction during signal emission
792 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
793 Toolkit::TextView handle( GetOwner() );
795 DoSetScrollPosition( position );
797 // Check if the new scroll position has been trimmed.
798 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
802 const Vector2& TextView::GetScrollPosition() const
804 return mVisualParameters.mCameraScrollPosition;
807 bool TextView::IsScrollPositionTrimmed() const
809 return mVisualParameters.mScrollPositionTrimmed;
812 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
814 return mScrolledSignalV2;
817 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
819 Dali::BaseHandle handle( object );
821 bool connected( true );
822 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
824 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
826 textView.ScrolledSignal().Connect( tracker, functor );
830 // signalName does not match any signal
837 TextView::LayoutParameters::LayoutParameters()
838 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
839 mWidthExceedPolicy( Toolkit::TextView::Original ),
840 mHeightExceedPolicy( Toolkit::TextView::Original ),
841 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
842 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
843 mLineJustification( Toolkit::TextView::Left ),
844 mLineHeightOffset( 0.f ),
847 // Sets ellipsize text
848 MarkupProcessor::StyledTextArray styledEllipsize;
849 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText );
852 TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::MultilinePolicy multilinePolicy,
853 const Toolkit::TextView::ExceedPolicy widthExceedPolicy,
854 const Toolkit::TextView::ExceedPolicy heightExceedPolicy,
855 const Toolkit::Alignment::Type alignmentType,
856 const Toolkit::TextView::LineJustification lineJustification,
857 const float lineHeightOffset,
858 const std::string& ellipsizeText )
859 : mMultilinePolicy( multilinePolicy ),
860 mWidthExceedPolicy( widthExceedPolicy ),
861 mHeightExceedPolicy( heightExceedPolicy ),
862 mHorizontalAlignment(),
863 mVerticalAlignment(),
864 mLineJustification( lineJustification ),
865 mLineHeightOffset( lineHeightOffset ),
869 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
870 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
871 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
872 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
873 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
874 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
876 mHorizontalAlignment = horizontalAlignment;
877 mVerticalAlignment = verticalAlignment;
879 // Sets ellipsize text
880 MarkupProcessor::StyledTextArray styledEllipsize;
881 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText );
884 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
885 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
886 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
887 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
888 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
889 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
890 mLineJustification( layoutParameters.mLineJustification ),
891 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
892 mEllipsizeText( layoutParameters.mEllipsizeText )
896 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
898 mMultilinePolicy = layoutParameters.mMultilinePolicy;
899 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
900 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
901 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
902 mVerticalAlignment = layoutParameters.mVerticalAlignment;
903 mLineJustification = layoutParameters.mLineJustification;
904 mLineHeightOffset = layoutParameters.mLineHeightOffset;
905 mEllipsizeText = layoutParameters.mEllipsizeText;
910 TextView::VisualParameters::VisualParameters()
912 mSortModifier( 0.f ),
913 mCameraScrollPosition( 0.f, 0.f ),
914 mSnapshotModeEnabled( false ),
915 mScrollEnabled( false ),
916 mScrollPositionTrimmed( false )
920 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
921 : mFadeBoundary( visualParameters.mFadeBoundary ),
922 mSortModifier( visualParameters.mSortModifier ),
923 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
924 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
925 mScrollEnabled( visualParameters.mScrollEnabled ),
926 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
930 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
932 mFadeBoundary = visualParameters.mFadeBoundary;
933 mSortModifier = visualParameters.mSortModifier;
934 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
935 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
936 mScrollEnabled = visualParameters.mScrollEnabled;
937 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
942 TextView::RelayoutData::RelayoutData()
944 mShrinkFactor( 1.f ),
946 mCharacterLogicalToVisualMap(),
947 mCharacterVisualToLogicalMap(),
949 mCharacterLayoutInfoTable(),
951 mTextSizeForRelayoutOption()
955 TextView::RelayoutData::RelayoutData( 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 mGlyphActors( relayoutData.mGlyphActors ),
962 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
963 mLines( relayoutData.mLines ),
964 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
968 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
970 mTextViewSize = relayoutData.mTextViewSize;
971 mShrinkFactor = relayoutData.mShrinkFactor;
972 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
973 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
974 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
975 mGlyphActors = relayoutData.mGlyphActors;
976 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
977 mLines = relayoutData.mLines;
978 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
984 : ControlImpl( false ), // doesn't require touch events
985 mCurrentStyledText(),
986 mTextViewProcessorOperations(),
987 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
988 Toolkit::TextView::Original,
989 Toolkit::TextView::Original,
990 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
991 Toolkit::TextView::Left,
993 std::string( "..." ) ),
996 mRelayoutOperations( NO_RELAYOUT ),
997 mOffscreenRootActor(),
998 mOffscreenImageActor(),
999 mOffscreenCameraActor(),
1000 mCurrentOffscreenSize(),
1001 mFrameBufferImage(),
1003 mPanGestureDetector(),
1004 mLockPreviousSnapshotMode( false ),
1005 mPreviousSnapshotModeEnabled( false )
1007 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1008 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1011 TextView::~TextView()
1013 // Destroys offscreen rendering resources.
1014 DestroyOffscreenRenderingResources();
1016 // Destroys scroll pan gesture detector.
1017 if( mPanGestureDetector )
1019 mPanGestureDetector.Reset();
1023 Vector3 TextView::GetNaturalSize()
1025 if( !mTextViewProcessorOperations.empty() )
1027 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1029 if( !mRelayoutData.mGlyphActors.empty() )
1031 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1032 // add them to the text-actor cache.
1033 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1034 mRelayoutData.mGlyphActors.clear();
1036 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1037 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1040 PerformTextViewProcessorOperations();
1043 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1046 float TextView::GetHeightForWidth( float width )
1050 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1051 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1052 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1054 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1055 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1056 height = GetNaturalSize().height;
1060 // Check if the given width is different than the current one.
1061 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1063 // Check if the text-view has glyph-actors.
1064 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1066 // Check which layout operations need to be done.
1067 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1069 if( relayoutSizeAndPositionNeeded )
1071 if( hasGlyphActors )
1073 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1074 // add them to the text-actor cache.
1075 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1076 mRelayoutData.mGlyphActors.clear();
1079 // Use the given width.
1080 const Vector2 textViewSize( width, GetControlSize().height );
1082 // Relays-out but doesn't add glyph-actors to the text-view.
1083 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1086 // Retrieve the text height after relayout the text.
1087 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1089 if( differentWidth )
1091 // Revert the relayout operation mask
1092 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1095 if( hasGlyphActors )
1097 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1098 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1101 if( differentWidth || hasGlyphActors )
1110 float TextView::GetWidthForHeight( float height )
1112 // TODO: Needs implementing properly, for now just return the natural width.
1113 return GetNaturalSize().width;
1116 void TextView::OnPropertySet( Property::Index index, Property::Value propertyValue )
1118 if( index == mPropertyText )
1120 SetText(propertyValue.Get<std::string>());
1122 else if( index == mPropertyMultilinePolicy )
1124 OnMultilinePolicyPropertySet(propertyValue);
1126 else if( index == mPropertyWidthExceedPolicy )
1128 OnWidthExceedPolicyPropertySet(propertyValue);
1130 else if( index == mPropertyHeightExceedPolicy )
1132 OnHeightExceedPolicyPropertySet(propertyValue);
1134 else if( index == mPropertyLineJustification )
1136 OnLineJustificationPropertySet(propertyValue);
1138 else if( ( index == mPropertyFadeBoundaryLeft ) ||
1139 ( index == mPropertyFadeBoundaryRight ) ||
1140 ( index == mPropertyFadeBoundaryTop ) ||
1141 ( index == mPropertyFadeBoundaryBottom ) )
1143 OnFadeBoundaryPropertySet( index, propertyValue );
1145 else if( index == mPropertyLineHeightOffset )
1147 Dali::PointSize pointSize( propertyValue.Get<float>() );
1148 SetLineHeightOffset(pointSize);
1150 else if ( ( index == mPropertyHorizontalAlignment ) ||
1151 ( index == mPropertyVerticalAlignment ) )
1153 OnAlignmentPropertySet( index, propertyValue );
1157 void TextView::OnInitialize()
1159 Actor self = Self();
1161 mPropertyText = self.RegisterProperty( PROPERTY_TEXT, "", Property::READ_WRITE );
1163 mPropertyMultilinePolicy = self.RegisterProperty( PROPERTY_MULTILINE_POLICY, "SplitByNewLineChar", Property::READ_WRITE );
1165 mPropertyWidthExceedPolicy = self.RegisterProperty( PROPERTY_WIDTH_EXCEED_POLICY, "Original", Property::READ_WRITE );
1167 mPropertyHeightExceedPolicy = self.RegisterProperty( PROPERTY_HEIGHT_EXCEED_POLICY, "Original", Property::READ_WRITE );
1169 mPropertyLineJustification = self.RegisterProperty( PROPERTY_LINE_JUSTIFICATION, "Left", Property::READ_WRITE );
1171 mPropertyFadeBoundaryLeft = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_LEFT, static_cast< int >( 0 ), Property::READ_WRITE );
1173 mPropertyFadeBoundaryRight = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_RIGHT, static_cast< int >( 0 ), Property::READ_WRITE );
1175 mPropertyFadeBoundaryTop = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_TOP, static_cast< int >( 0 ), Property::READ_WRITE );
1177 mPropertyFadeBoundaryBottom = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_BOTTOM, static_cast< int >( 0 ), Property::READ_WRITE );
1179 mPropertyLineHeightOffset = self.RegisterProperty( PROPERTY_LINE_HEIGHT_OFFSET, 0.0f, Property::READ_WRITE );
1181 mPropertyHorizontalAlignment = self.RegisterProperty( PROPERTY_HORIZONTAL_ALIGNMENT, "HorizontalCenter", Property::READ_WRITE );
1183 mPropertyVerticalAlignment = self.RegisterProperty( PROPERTY_VERTICAL_ALIGNMENT, "VerticalCenter", Property::READ_WRITE );
1188 void TextView::OnStyleChange( StyleChange change )
1190 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1191 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1192 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1194 SetText( mCurrentStyledText );
1197 void TextView::OnControlSizeSet( const Vector3& size )
1199 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1201 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1202 mRelayoutOperations = RELAYOUT_ALL;
1204 // Request to be relaid out
1209 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1211 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1213 // Not worth to relayout if width or height is equal to zero.
1217 if( size != mRelayoutData.mTextViewSize )
1219 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1220 if( RELAYOUT_ALL != mRelayoutOperations )
1222 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1223 RELAYOUT_REMOVE_TEXT_ACTORS |
1224 RELAYOUT_SIZE_POSITION |
1225 RELAYOUT_ALIGNMENT |
1226 RELAYOUT_VISIBILITY |
1227 RELAYOUT_TEXT_ACTOR_UPDATE |
1228 RELAYOUT_INSERT_TO_TEXT_VIEW |
1229 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1233 // Remove glyph-actors from text-view
1234 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1236 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1237 mRelayoutData.mGlyphActors.clear();
1240 if( NO_RELAYOUT != mRelayoutOperations )
1242 // Relays-out and add glyph-actors to the text-view.
1243 DoRelayOut( size, mRelayoutOperations );
1244 ProcessSnapshot( size );
1247 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1248 mRelayoutData.mTextActorCache.ClearTexts();
1251 void TextView::PerformTextViewProcessorOperations()
1253 // Traverse the relayout operation vector ...
1255 // Optimizes some operations.
1256 OptimizeTextViewProcessorOperations();
1258 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1260 const TextViewProcessorMetadata& relayoutMetadata( *it );
1262 switch( relayoutMetadata.mType )
1264 case TextView::TextSet:
1266 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1271 case TextView::TextInserted:
1273 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1274 relayoutMetadata.mText,
1279 case TextView::TextReplaced:
1281 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1282 relayoutMetadata.mNumberOfCharacters,
1283 relayoutMetadata.mText,
1288 case TextView::TextRemoved:
1290 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1291 relayoutMetadata.mNumberOfCharacters,
1294 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1297 case TextView::NewLineHeight:
1299 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1300 mRelayoutData.mTextLayoutInfo );
1303 case TextView::NewStyle:
1305 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1306 relayoutMetadata.mStyleMask,
1313 // Clear all operations when they are done.
1314 mTextViewProcessorOperations.clear();
1317 void TextView::OptimizeTextViewProcessorOperations()
1319 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1321 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1322 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1323 // use the cache without clearing the text-actors.
1325 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1327 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1329 const TextViewProcessorMetadata& relayoutMetadata( *it );
1331 switch( relayoutMetadata.mType )
1333 case TextView::TextRemoved:
1335 bool optimizationDone = false;
1337 if( it + 1 != endIt )
1339 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1340 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1342 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1344 optimizationDone = true;
1345 TextViewProcessorMetadata newRelayoutMetadata;
1346 newRelayoutMetadata.mType = TextView::TextReplaced;
1347 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1348 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1349 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1350 textViewProcessorOperations.push_back( newRelayoutMetadata );
1352 // do not access the TextInserted operation in next iteration.
1358 if( !optimizationDone )
1360 textViewProcessorOperations.push_back( relayoutMetadata );
1366 textViewProcessorOperations.push_back( relayoutMetadata );
1371 mTextViewProcessorOperations = textViewProcessorOperations;
1374 void TextView::DoRelayOut( const Size& textViewSize, const RelayoutOperationMask relayoutOperationMask )
1376 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1377 if( !mTextViewProcessorOperations.empty() )
1379 PerformTextViewProcessorOperations();
1382 CombineExceedPolicies();
1385 if( mVisualParameters.mSnapshotModeEnabled )
1387 rootActor = mOffscreenRootActor;
1394 mRelayoutData.mTextViewSize = textViewSize;
1395 switch( mLayoutParameters.mMultilinePolicy )
1397 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1399 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1401 } // SplitByNewLineChar
1403 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1405 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1409 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1411 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1414 } // switch( mMultilinePolicy )
1416 // Remove done operations from the mask.
1417 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1420 void TextView::ProcessSnapshot( const Size& textViewSize )
1422 if( mVisualParameters.mSnapshotModeEnabled )
1424 // If layout options change, it's needed generate a new image.
1426 if( mOffscreenRootActor )
1428 // Set the root actor visible.
1429 // The root actor is set to non visible after the render task is processed.
1430 mOffscreenRootActor.SetVisible( true );
1432 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1433 mOffscreenRootActor.SetSize( textViewSize );
1436 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1437 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1439 // Set the image actor visible.
1440 // The image actor is set to non visible if there is no text to render.
1441 mOffscreenImageActor.SetVisible( true );
1443 // Calculates the offscreen image's size. It takes into account different points:
1444 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1445 // * There is a maximum texture size the graphic subsystem can load on the memory.
1446 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1448 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1449 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1450 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1451 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1453 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1457 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1458 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1459 offscreenSize.height,
1462 // Stores current text-view size to avoid create new Dali resources if text changes.
1463 mCurrentOffscreenSize = offscreenSize;
1465 if( !mOffscreenCameraActor )
1467 // Creates a new camera actor.
1468 mOffscreenCameraActor = CameraActor::New();
1469 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1470 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1471 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1473 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1475 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1478 // Calculate camera parameters for current text size.
1479 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1482 if( mVisualParameters.mScrollEnabled )
1484 // Updates the offscreen camera position with the new scroll offset.
1485 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1486 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1490 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1491 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1496 // Creates a new render task.
1497 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1499 mRenderTask.SetSourceActor( mOffscreenRootActor );
1500 mRenderTask.SetInputEnabled( false );
1501 mRenderTask.SetClearColor( Color::TRANSPARENT );
1502 mRenderTask.SetClearEnabled( true );
1503 mRenderTask.SetExclusive( true );
1505 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1506 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1511 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1512 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1515 // Process the render task only once every time the text changes or the text-view's size canges.
1516 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1520 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1521 mOffscreenImageActor.SetVisible( false );
1526 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1528 float xPosition = 0.f;
1529 float yPosition = 0.f;
1530 Vector3 parentOrigin = ParentOrigin::CENTER;
1531 Vector3 anchorPoint = AnchorPoint::CENTER;
1533 switch( mLayoutParameters.mHorizontalAlignment )
1535 case Toolkit::Alignment::HorizontalLeft:
1537 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1538 parentOrigin.x = 0.f;
1539 anchorPoint.x = 0.f;
1542 case Toolkit::Alignment::HorizontalCenter:
1547 case Toolkit::Alignment::HorizontalRight:
1549 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1550 parentOrigin.x = 1.f;
1551 anchorPoint.x = 1.f;
1556 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1560 switch( mLayoutParameters.mVerticalAlignment )
1562 case Toolkit::Alignment::VerticalTop:
1564 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1565 parentOrigin.y = 0.f;
1566 anchorPoint.y = 0.f;
1569 case Toolkit::Alignment::VerticalCenter:
1574 case Toolkit::Alignment::VerticalBottom:
1576 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1577 parentOrigin.y = 1.f;
1578 anchorPoint.y = 1.f;
1583 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1587 mOffscreenCameraActor.SetX( xPosition );
1588 mOffscreenCameraActor.SetY( yPosition );
1590 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1591 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1594 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1596 // not to process the offscreen root actor by setting its visibility to false.
1597 mOffscreenRootActor.SetVisible( false );
1599 // Sets the new size and the new frame buffer to the image actor.
1600 // Image actor must have same size as text. Otherwise text can be truncated.
1601 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1602 mOffscreenImageActor.SetImage( mFrameBufferImage );
1605 void TextView::DestroyOffscreenRenderingResources()
1609 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1611 if( Stage::IsInstalled() )
1613 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1616 mRenderTask.Reset();
1619 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1620 if( mOffscreenCameraActor )
1622 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1624 mOffscreenCameraActor.Reset();
1627 if( mOffscreenRootActor )
1629 mOffscreenRootActor.Reset();
1632 if( mOffscreenImageActor )
1634 mOffscreenImageActor.Reset();
1637 mCurrentOffscreenSize = Size( 0.f, 0.f );
1639 if( mFrameBufferImage )
1641 mFrameBufferImage.Reset();
1645 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1647 if( 1u == gesture.numberOfTouches )
1649 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1653 void TextView::TrimScrollPosition()
1655 const Vector3& textViewSize = GetControlSize();
1657 // Before use the text's size, relayout the text is needed to get the actual text size.
1658 GetTextLayoutInfo();
1660 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1661 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1662 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1663 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1664 float minVerticalDisplacement = -maxVerticalDisplacement;
1666 // Updates the range if the text is aligned on the right or left.
1667 switch( mLayoutParameters.mHorizontalAlignment )
1669 case Toolkit::Alignment::HorizontalLeft:
1671 maxHorizontalDisplacement *= 2.f;
1672 minHorizontalDisplacement = 0.f;
1675 case Toolkit::Alignment::HorizontalCenter:
1680 case Toolkit::Alignment::HorizontalRight:
1682 maxHorizontalDisplacement = 0.f;
1683 minHorizontalDisplacement *= 2.f;
1688 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1692 // Updates the range if the text is aligned on the top or bottom.
1693 switch( mLayoutParameters.mVerticalAlignment )
1695 case Toolkit::Alignment::VerticalTop:
1697 maxVerticalDisplacement *= 2.f;
1698 minVerticalDisplacement = 0.f;
1701 case Toolkit::Alignment::VerticalCenter:
1706 case Toolkit::Alignment::VerticalBottom:
1708 maxVerticalDisplacement = 0.f;
1709 minVerticalDisplacement *= 2.f;
1714 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1718 // Trims the scroll position to be within the range.
1719 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1720 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1722 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1723 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1726 void TextView::DoSetScrollPosition( const Vector2& position )
1728 // Stores old scroll position.
1729 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1731 // Updates the scroll position
1732 mVisualParameters.mCameraScrollPosition = position;
1734 // Ensures the text-view is covered with text.
1735 TrimScrollPosition();
1737 // Calculate the difference with the previous scroll position
1738 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1739 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1741 if( mOffscreenRootActor )
1743 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1745 mOffscreenRootActor.SetVisible( true );
1748 if( mOffscreenCameraActor )
1750 // Update the offscreen camera with the new scroll position.
1751 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1752 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1757 // Refresh the render-task.
1758 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1762 Toolkit::TextView handle( GetOwner() );
1763 mScrolledSignalV2.Emit( handle, delta );
1766 void TextView::CombineExceedPolicies()
1768 // Calculates the combination of exceed policies.
1770 switch( mLayoutParameters.mWidthExceedPolicy )
1772 case Toolkit::TextView::Original:
1774 switch( mLayoutParameters.mHeightExceedPolicy )
1776 case Toolkit::TextView::Original:
1778 mLayoutParameters.mExceedPolicy = Original;
1781 case Toolkit::TextView::Fade:
1783 mLayoutParameters.mExceedPolicy = OriginalFade;
1786 case Toolkit::TextView::ShrinkToFit:
1788 mLayoutParameters.mExceedPolicy = OriginalShrink;
1793 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1798 case Toolkit::TextView::Split:
1800 switch( mLayoutParameters.mHeightExceedPolicy )
1802 case Toolkit::TextView::Original:
1804 mLayoutParameters.mExceedPolicy = SplitOriginal;
1807 case Toolkit::TextView::Fade:
1809 mLayoutParameters.mExceedPolicy = SplitFade;
1812 case Toolkit::TextView::ShrinkToFit:
1814 mLayoutParameters.mExceedPolicy = SplitShrink;
1819 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1824 case Toolkit::TextView::Fade:
1826 switch( mLayoutParameters.mHeightExceedPolicy )
1828 case Toolkit::TextView::Original:
1830 mLayoutParameters.mExceedPolicy = FadeOriginal;
1833 case Toolkit::TextView::Fade:
1835 mLayoutParameters.mExceedPolicy = Fade;
1840 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1845 case Toolkit::TextView::ShrinkToFit:
1847 switch( mLayoutParameters.mHeightExceedPolicy )
1849 case Toolkit::TextView::Original:
1851 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1854 case Toolkit::TextView::Fade:
1856 mLayoutParameters.mExceedPolicy = ShrinkFade;
1859 case Toolkit::TextView::ShrinkToFit:
1861 mLayoutParameters.mExceedPolicy = Shrink;
1866 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1871 case Toolkit::TextView::EllipsizeEnd:
1873 switch( mLayoutParameters.mHeightExceedPolicy )
1875 case Toolkit::TextView::Original:
1877 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1880 case Toolkit::TextView::EllipsizeEnd:
1882 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1887 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1894 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1899 Actor TextView::GetRootActor() const
1901 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1905 if( mVisualParameters.mSnapshotModeEnabled )
1907 rootActor = mOffscreenRootActor;
1917 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1919 std::string policyName( propertyValue.Get<std::string>() );
1920 if(policyName == "SplitByNewLineChar")
1922 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1924 else if(policyName == "SplitByWord")
1926 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1928 else if(policyName == "SplitByChar")
1930 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1934 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1938 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1940 std::string policyName( propertyValue.Get<std::string>() );
1941 if(policyName == "Original")
1943 SetWidthExceedPolicy(Toolkit::TextView::Original);
1945 else if(policyName == "Truncate")
1947 SetWidthExceedPolicy(Toolkit::TextView::Truncate);
1949 else if(policyName == "Fade")
1951 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1953 else if(policyName == "Split")
1955 SetWidthExceedPolicy(Toolkit::TextView::Split);
1957 else if(policyName == "ShrinkToFit")
1959 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1961 else if(policyName == "EllipsizeEnd")
1963 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1967 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1971 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1973 std::string policyName( propertyValue.Get<std::string>() );
1974 if(policyName == "Original")
1976 SetHeightExceedPolicy(Toolkit::TextView::Original);
1978 else if(policyName == "Truncate")
1980 SetHeightExceedPolicy(Toolkit::TextView::Truncate);
1982 else if(policyName == "Fade")
1984 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1986 else if(policyName == "Split")
1988 SetHeightExceedPolicy(Toolkit::TextView::Split);
1990 else if(policyName == "ShrinkToFit")
1992 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1996 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
2000 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
2002 std::string policyName( propertyValue.Get<std::string>() );
2003 if(policyName == "Left")
2005 SetLineJustification(Toolkit::TextView::Left);
2007 else if(policyName == "Center")
2009 SetLineJustification(Toolkit::TextView::Center);
2011 else if(policyName == "Right")
2013 SetLineJustification(Toolkit::TextView::Right);
2015 else if(policyName == "Justified")
2017 SetLineJustification(Toolkit::TextView::Justified);
2021 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2025 void TextView::OnFadeBoundaryPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2027 PixelSize boundary( propertyValue.Get<unsigned int>() );
2029 if ( propertyIndex == mPropertyFadeBoundaryLeft )
2031 mVisualParameters.mFadeBoundary.mLeft = boundary;
2033 else if ( propertyIndex == mPropertyFadeBoundaryRight )
2035 mVisualParameters.mFadeBoundary.mRight = boundary;
2037 else if ( propertyIndex == mPropertyFadeBoundaryTop )
2039 mVisualParameters.mFadeBoundary.mTop = boundary;
2041 else if ( propertyIndex == mPropertyFadeBoundaryBottom )
2043 mVisualParameters.mFadeBoundary.mBottom = boundary;
2047 DALI_ASSERT_ALWAYS( !"TextView::OnFadeBoundaryPropertySet(). Invalid Property value." );
2051 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2053 std::string value( propertyValue.Get<std::string>() );
2055 if( propertyIndex == mPropertyHorizontalAlignment )
2057 if(value == "HorizontalLeft")
2059 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2061 else if( value == "HorizontalCenter")
2063 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2065 else if( value == "HorizontalRight")
2067 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2071 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2074 else if( propertyIndex == mPropertyVerticalAlignment )
2076 if( value == "VerticalTop" )
2078 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2080 else if( value == "VerticalCenter")
2082 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2084 else if( value == "VerticalBottom")
2086 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2090 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2095 } // namespace Internal
2097 } // namespace Toolkit