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, IsMarkupProcessingEnabled() );
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, IsMarkupProcessingEnabled() );
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, IsMarkupProcessingEnabled() );
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, IsMarkupProcessingEnabled() );
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::SetMarkupProcessingEnabled( bool enable )
743 mMarkUpEnabled = enable;
746 bool TextView::IsMarkupProcessingEnabled() const
748 return mMarkUpEnabled;
751 void TextView::SetScrollEnabled( const bool enable )
753 if( enable != mVisualParameters.mScrollEnabled )
755 mVisualParameters.mScrollEnabled = enable;
757 if( mVisualParameters.mScrollEnabled )
759 // Offscreen rendering is needed to enable text scroll.
761 // Stores previous value of the snapshot mode.
762 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
765 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
766 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
767 Lock lock( mLockPreviousSnapshotMode );
768 SetSnapshotModeEnabled( true );
771 // Creates the pan gesture detector and attach the text-view.
772 mPanGestureDetector = PanGestureDetector::New();
773 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
774 mPanGestureDetector.Attach( Self() );
778 // Removes the pan gesture detector.
779 if( mPanGestureDetector )
781 mPanGestureDetector.Detach( Self() );
782 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
783 mPanGestureDetector.Reset();
786 // Restores the previous state for snapshot mode.
787 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
792 bool TextView::IsScrollEnabled() const
794 return mVisualParameters.mScrollEnabled;
797 void TextView::SetScrollPosition( const Vector2& position )
799 if( position != mVisualParameters.mCameraScrollPosition )
801 // Guard against destruction during signal emission
802 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
803 Toolkit::TextView handle( GetOwner() );
805 DoSetScrollPosition( position );
807 // Check if the new scroll position has been trimmed.
808 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
812 const Vector2& TextView::GetScrollPosition() const
814 return mVisualParameters.mCameraScrollPosition;
817 bool TextView::IsScrollPositionTrimmed() const
819 return mVisualParameters.mScrollPositionTrimmed;
822 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
824 return mScrolledSignalV2;
827 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
829 Dali::BaseHandle handle( object );
831 bool connected( true );
832 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
834 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
836 textView.ScrolledSignal().Connect( tracker, functor );
840 // signalName does not match any signal
847 TextView::LayoutParameters::LayoutParameters()
848 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
849 mWidthExceedPolicy( Toolkit::TextView::Original ),
850 mHeightExceedPolicy( Toolkit::TextView::Original ),
851 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
852 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
853 mLineJustification( Toolkit::TextView::Left ),
854 mLineHeightOffset( 0.f ),
856 mMarkUpEnabled( false )
858 // Sets ellipsize text
859 MarkupProcessor::StyledTextArray styledEllipsize;
860 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
863 TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::MultilinePolicy multilinePolicy,
864 const Toolkit::TextView::ExceedPolicy widthExceedPolicy,
865 const Toolkit::TextView::ExceedPolicy heightExceedPolicy,
866 const Toolkit::Alignment::Type alignmentType,
867 const Toolkit::TextView::LineJustification lineJustification,
868 const float lineHeightOffset,
869 const std::string& ellipsizeText,
870 const bool markUpEnabled )
871 : mMultilinePolicy( multilinePolicy ),
872 mWidthExceedPolicy( widthExceedPolicy ),
873 mHeightExceedPolicy( heightExceedPolicy ),
874 mHorizontalAlignment(),
875 mVerticalAlignment(),
876 mLineJustification( lineJustification ),
877 mLineHeightOffset( lineHeightOffset ),
879 mMarkUpEnabled( markUpEnabled )
882 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
883 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
884 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
885 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
886 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
887 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
889 mHorizontalAlignment = horizontalAlignment;
890 mVerticalAlignment = verticalAlignment;
892 // Sets ellipsize text
893 MarkupProcessor::StyledTextArray styledEllipsize;
894 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
897 TextView::LayoutParameters::LayoutParameters( 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 ),
906 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
910 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
912 mMultilinePolicy = layoutParameters.mMultilinePolicy;
913 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
914 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
915 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
916 mVerticalAlignment = layoutParameters.mVerticalAlignment;
917 mLineJustification = layoutParameters.mLineJustification;
918 mLineHeightOffset = layoutParameters.mLineHeightOffset;
919 mEllipsizeText = layoutParameters.mEllipsizeText;
920 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
925 TextView::VisualParameters::VisualParameters()
927 mSortModifier( 0.f ),
928 mCameraScrollPosition( 0.f, 0.f ),
929 mSnapshotModeEnabled( false ),
930 mScrollEnabled( false ),
931 mScrollPositionTrimmed( false )
935 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
936 : mFadeBoundary( visualParameters.mFadeBoundary ),
937 mSortModifier( visualParameters.mSortModifier ),
938 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
939 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
940 mScrollEnabled( visualParameters.mScrollEnabled ),
941 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
945 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
947 mFadeBoundary = visualParameters.mFadeBoundary;
948 mSortModifier = visualParameters.mSortModifier;
949 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
950 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
951 mScrollEnabled = visualParameters.mScrollEnabled;
952 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
957 TextView::RelayoutData::RelayoutData()
959 mShrinkFactor( 1.f ),
961 mCharacterLogicalToVisualMap(),
962 mCharacterVisualToLogicalMap(),
964 mCharacterLayoutInfoTable(),
966 mTextSizeForRelayoutOption()
970 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
971 : mTextViewSize( relayoutData.mTextViewSize ),
972 mShrinkFactor( relayoutData.mShrinkFactor ),
973 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
974 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
975 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
976 mGlyphActors( relayoutData.mGlyphActors ),
977 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
978 mLines( relayoutData.mLines ),
979 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
983 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
985 mTextViewSize = relayoutData.mTextViewSize;
986 mShrinkFactor = relayoutData.mShrinkFactor;
987 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
988 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
989 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
990 mGlyphActors = relayoutData.mGlyphActors;
991 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
992 mLines = relayoutData.mLines;
993 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
999 : ControlImpl( false ), // doesn't require touch events
1000 mCurrentStyledText(),
1001 mTextViewProcessorOperations(),
1002 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1003 Toolkit::TextView::Original,
1004 Toolkit::TextView::Original,
1005 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1006 Toolkit::TextView::Left,
1008 std::string( "..." ),
1010 mVisualParameters(),
1012 mRelayoutOperations( NO_RELAYOUT ),
1013 mOffscreenRootActor(),
1014 mOffscreenImageActor(),
1015 mOffscreenCameraActor(),
1016 mCurrentOffscreenSize(),
1017 mFrameBufferImage(),
1019 mPanGestureDetector(),
1020 mLockPreviousSnapshotMode( false ),
1021 mPreviousSnapshotModeEnabled( false ),
1022 mMarkUpEnabled( false )
1024 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1025 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1028 TextView::~TextView()
1030 // Destroys offscreen rendering resources.
1031 DestroyOffscreenRenderingResources();
1033 // Destroys scroll pan gesture detector.
1034 if( mPanGestureDetector )
1036 mPanGestureDetector.Reset();
1040 Vector3 TextView::GetNaturalSize()
1042 if( !mTextViewProcessorOperations.empty() )
1044 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1046 if( !mRelayoutData.mGlyphActors.empty() )
1048 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1049 // add them to the text-actor cache.
1050 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1051 mRelayoutData.mGlyphActors.clear();
1053 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1054 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1057 PerformTextViewProcessorOperations();
1060 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1063 float TextView::GetHeightForWidth( float width )
1067 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1068 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1069 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1071 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1072 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1073 height = GetNaturalSize().height;
1077 // Check if the given width is different than the current one.
1078 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1080 // Check if the text-view has glyph-actors.
1081 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1083 // Check which layout operations need to be done.
1084 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1086 if( relayoutSizeAndPositionNeeded )
1088 if( hasGlyphActors )
1090 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1091 // add them to the text-actor cache.
1092 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1093 mRelayoutData.mGlyphActors.clear();
1096 // Use the given width.
1097 const Vector2 textViewSize( width, GetControlSize().height );
1099 // Relays-out but doesn't add glyph-actors to the text-view.
1100 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1103 // Retrieve the text height after relayout the text.
1104 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1106 if( differentWidth )
1108 // Revert the relayout operation mask
1109 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1112 if( hasGlyphActors )
1114 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1115 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1118 if( differentWidth || hasGlyphActors )
1127 float TextView::GetWidthForHeight( float height )
1129 // TODO: Needs implementing properly, for now just return the natural width.
1130 return GetNaturalSize().width;
1133 void TextView::OnPropertySet( Property::Index index, Property::Value propertyValue )
1135 if( index == mPropertyText )
1137 SetText(propertyValue.Get<std::string>());
1139 else if( index == mPropertyMultilinePolicy )
1141 OnMultilinePolicyPropertySet(propertyValue);
1143 else if( index == mPropertyWidthExceedPolicy )
1145 OnWidthExceedPolicyPropertySet(propertyValue);
1147 else if( index == mPropertyHeightExceedPolicy )
1149 OnHeightExceedPolicyPropertySet(propertyValue);
1151 else if( index == mPropertyLineJustification )
1153 OnLineJustificationPropertySet(propertyValue);
1155 else if( ( index == mPropertyFadeBoundaryLeft ) ||
1156 ( index == mPropertyFadeBoundaryRight ) ||
1157 ( index == mPropertyFadeBoundaryTop ) ||
1158 ( index == mPropertyFadeBoundaryBottom ) )
1160 OnFadeBoundaryPropertySet( index, propertyValue );
1162 else if( index == mPropertyLineHeightOffset )
1164 Dali::PointSize pointSize( propertyValue.Get<float>() );
1165 SetLineHeightOffset(pointSize);
1167 else if ( ( index == mPropertyHorizontalAlignment ) ||
1168 ( index == mPropertyVerticalAlignment ) )
1170 OnAlignmentPropertySet( index, propertyValue );
1174 void TextView::OnInitialize()
1176 Actor self = Self();
1178 mPropertyText = self.RegisterProperty( PROPERTY_TEXT, "", Property::READ_WRITE );
1180 mPropertyMultilinePolicy = self.RegisterProperty( PROPERTY_MULTILINE_POLICY, "SplitByNewLineChar", Property::READ_WRITE );
1182 mPropertyWidthExceedPolicy = self.RegisterProperty( PROPERTY_WIDTH_EXCEED_POLICY, "Original", Property::READ_WRITE );
1184 mPropertyHeightExceedPolicy = self.RegisterProperty( PROPERTY_HEIGHT_EXCEED_POLICY, "Original", Property::READ_WRITE );
1186 mPropertyLineJustification = self.RegisterProperty( PROPERTY_LINE_JUSTIFICATION, "Left", Property::READ_WRITE );
1188 mPropertyFadeBoundaryLeft = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_LEFT, static_cast< int >( 0 ), Property::READ_WRITE );
1190 mPropertyFadeBoundaryRight = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_RIGHT, static_cast< int >( 0 ), Property::READ_WRITE );
1192 mPropertyFadeBoundaryTop = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_TOP, static_cast< int >( 0 ), Property::READ_WRITE );
1194 mPropertyFadeBoundaryBottom = self.RegisterProperty( PROPERTY_FADE_BOUNDARY_BOTTOM, static_cast< int >( 0 ), Property::READ_WRITE );
1196 mPropertyLineHeightOffset = self.RegisterProperty( PROPERTY_LINE_HEIGHT_OFFSET, 0.0f, Property::READ_WRITE );
1198 mPropertyHorizontalAlignment = self.RegisterProperty( PROPERTY_HORIZONTAL_ALIGNMENT, "HorizontalCenter", Property::READ_WRITE );
1200 mPropertyVerticalAlignment = self.RegisterProperty( PROPERTY_VERTICAL_ALIGNMENT, "VerticalCenter", Property::READ_WRITE );
1205 void TextView::OnStyleChange( StyleChange change )
1207 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1208 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1209 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1211 SetText( mCurrentStyledText );
1214 void TextView::OnControlSizeSet( const Vector3& size )
1216 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1218 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1219 mRelayoutOperations = RELAYOUT_ALL;
1221 // Request to be relaid out
1226 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1228 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1230 // Not worth to relayout if width or height is equal to zero.
1234 if( size != mRelayoutData.mTextViewSize )
1236 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1237 if( RELAYOUT_ALL != mRelayoutOperations )
1239 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1240 RELAYOUT_REMOVE_TEXT_ACTORS |
1241 RELAYOUT_SIZE_POSITION |
1242 RELAYOUT_ALIGNMENT |
1243 RELAYOUT_VISIBILITY |
1244 RELAYOUT_TEXT_ACTOR_UPDATE |
1245 RELAYOUT_INSERT_TO_TEXT_VIEW |
1246 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1250 // Remove glyph-actors from text-view
1251 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1253 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1254 mRelayoutData.mGlyphActors.clear();
1257 if( NO_RELAYOUT != mRelayoutOperations )
1259 // Relays-out and add glyph-actors to the text-view.
1260 DoRelayOut( size, mRelayoutOperations );
1261 ProcessSnapshot( size );
1264 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1265 mRelayoutData.mTextActorCache.ClearTexts();
1268 void TextView::PerformTextViewProcessorOperations()
1270 // Traverse the relayout operation vector ...
1272 // Optimizes some operations.
1273 OptimizeTextViewProcessorOperations();
1275 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1277 const TextViewProcessorMetadata& relayoutMetadata( *it );
1279 switch( relayoutMetadata.mType )
1281 case TextView::TextSet:
1283 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1288 case TextView::TextInserted:
1290 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1291 relayoutMetadata.mText,
1296 case TextView::TextReplaced:
1298 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1299 relayoutMetadata.mNumberOfCharacters,
1300 relayoutMetadata.mText,
1305 case TextView::TextRemoved:
1307 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1308 relayoutMetadata.mNumberOfCharacters,
1311 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1314 case TextView::NewLineHeight:
1316 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1317 mRelayoutData.mTextLayoutInfo );
1320 case TextView::NewStyle:
1322 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1323 relayoutMetadata.mStyleMask,
1330 // Clear all operations when they are done.
1331 mTextViewProcessorOperations.clear();
1334 void TextView::OptimizeTextViewProcessorOperations()
1336 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1338 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1339 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1340 // use the cache without clearing the text-actors.
1342 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1344 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1346 const TextViewProcessorMetadata& relayoutMetadata( *it );
1348 switch( relayoutMetadata.mType )
1350 case TextView::TextRemoved:
1352 bool optimizationDone = false;
1354 if( it + 1 != endIt )
1356 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1357 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1359 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1361 optimizationDone = true;
1362 TextViewProcessorMetadata newRelayoutMetadata;
1363 newRelayoutMetadata.mType = TextView::TextReplaced;
1364 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1365 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1366 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1367 textViewProcessorOperations.push_back( newRelayoutMetadata );
1369 // do not access the TextInserted operation in next iteration.
1375 if( !optimizationDone )
1377 textViewProcessorOperations.push_back( relayoutMetadata );
1383 textViewProcessorOperations.push_back( relayoutMetadata );
1388 mTextViewProcessorOperations = textViewProcessorOperations;
1391 void TextView::DoRelayOut( const Size& textViewSize, const RelayoutOperationMask relayoutOperationMask )
1393 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1394 if( !mTextViewProcessorOperations.empty() )
1396 PerformTextViewProcessorOperations();
1399 CombineExceedPolicies();
1402 if( mVisualParameters.mSnapshotModeEnabled )
1404 rootActor = mOffscreenRootActor;
1411 mRelayoutData.mTextViewSize = textViewSize;
1412 switch( mLayoutParameters.mMultilinePolicy )
1414 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1416 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1418 } // SplitByNewLineChar
1420 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1422 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1426 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1428 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1431 } // switch( mMultilinePolicy )
1433 // Remove done operations from the mask.
1434 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1437 void TextView::ProcessSnapshot( const Size& textViewSize )
1439 if( mVisualParameters.mSnapshotModeEnabled )
1441 // If layout options change, it's needed generate a new image.
1443 if( mOffscreenRootActor )
1445 // Set the root actor visible.
1446 // The root actor is set to non visible after the render task is processed.
1447 mOffscreenRootActor.SetVisible( true );
1449 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1450 mOffscreenRootActor.SetSize( textViewSize );
1453 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1454 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1456 // Set the image actor visible.
1457 // The image actor is set to non visible if there is no text to render.
1458 mOffscreenImageActor.SetVisible( true );
1460 // Calculates the offscreen image's size. It takes into account different points:
1461 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1462 // * There is a maximum texture size the graphic subsystem can load on the memory.
1463 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1465 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1466 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1467 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1468 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1470 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1474 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1475 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1476 offscreenSize.height,
1479 // Stores current text-view size to avoid create new Dali resources if text changes.
1480 mCurrentOffscreenSize = offscreenSize;
1482 if( !mOffscreenCameraActor )
1484 // Creates a new camera actor.
1485 mOffscreenCameraActor = CameraActor::New();
1486 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1487 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1488 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1490 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1492 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1495 // Calculate camera parameters for current text size.
1496 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1499 if( mVisualParameters.mScrollEnabled )
1501 // Updates the offscreen camera position with the new scroll offset.
1502 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1503 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1507 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1508 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1513 // Creates a new render task.
1514 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1516 mRenderTask.SetSourceActor( mOffscreenRootActor );
1517 mRenderTask.SetInputEnabled( false );
1518 mRenderTask.SetClearColor( Color::TRANSPARENT );
1519 mRenderTask.SetClearEnabled( true );
1520 mRenderTask.SetExclusive( true );
1522 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1523 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1528 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1529 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1532 // Process the render task only once every time the text changes or the text-view's size canges.
1533 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1537 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1538 mOffscreenImageActor.SetVisible( false );
1543 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1545 float xPosition = 0.f;
1546 float yPosition = 0.f;
1547 Vector3 parentOrigin = ParentOrigin::CENTER;
1548 Vector3 anchorPoint = AnchorPoint::CENTER;
1550 switch( mLayoutParameters.mHorizontalAlignment )
1552 case Toolkit::Alignment::HorizontalLeft:
1554 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1555 parentOrigin.x = 0.f;
1556 anchorPoint.x = 0.f;
1559 case Toolkit::Alignment::HorizontalCenter:
1564 case Toolkit::Alignment::HorizontalRight:
1566 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1567 parentOrigin.x = 1.f;
1568 anchorPoint.x = 1.f;
1573 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1577 switch( mLayoutParameters.mVerticalAlignment )
1579 case Toolkit::Alignment::VerticalTop:
1581 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1582 parentOrigin.y = 0.f;
1583 anchorPoint.y = 0.f;
1586 case Toolkit::Alignment::VerticalCenter:
1591 case Toolkit::Alignment::VerticalBottom:
1593 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1594 parentOrigin.y = 1.f;
1595 anchorPoint.y = 1.f;
1600 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1604 mOffscreenCameraActor.SetX( xPosition );
1605 mOffscreenCameraActor.SetY( yPosition );
1607 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1608 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1611 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1613 // not to process the offscreen root actor by setting its visibility to false.
1614 mOffscreenRootActor.SetVisible( false );
1616 // Sets the new size and the new frame buffer to the image actor.
1617 // Image actor must have same size as text. Otherwise text can be truncated.
1618 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1619 mOffscreenImageActor.SetImage( mFrameBufferImage );
1622 void TextView::DestroyOffscreenRenderingResources()
1626 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1628 if( Stage::IsInstalled() )
1630 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1633 mRenderTask.Reset();
1636 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1637 if( mOffscreenCameraActor )
1639 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1641 mOffscreenCameraActor.Reset();
1644 if( mOffscreenRootActor )
1646 mOffscreenRootActor.Reset();
1649 if( mOffscreenImageActor )
1651 mOffscreenImageActor.Reset();
1654 mCurrentOffscreenSize = Size( 0.f, 0.f );
1656 if( mFrameBufferImage )
1658 mFrameBufferImage.Reset();
1662 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1664 if( 1u == gesture.numberOfTouches )
1666 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1670 void TextView::TrimScrollPosition()
1672 const Vector3& textViewSize = GetControlSize();
1674 // Before use the text's size, relayout the text is needed to get the actual text size.
1675 GetTextLayoutInfo();
1677 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1678 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1679 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1680 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1681 float minVerticalDisplacement = -maxVerticalDisplacement;
1683 // Updates the range if the text is aligned on the right or left.
1684 switch( mLayoutParameters.mHorizontalAlignment )
1686 case Toolkit::Alignment::HorizontalLeft:
1688 maxHorizontalDisplacement *= 2.f;
1689 minHorizontalDisplacement = 0.f;
1692 case Toolkit::Alignment::HorizontalCenter:
1697 case Toolkit::Alignment::HorizontalRight:
1699 maxHorizontalDisplacement = 0.f;
1700 minHorizontalDisplacement *= 2.f;
1705 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1709 // Updates the range if the text is aligned on the top or bottom.
1710 switch( mLayoutParameters.mVerticalAlignment )
1712 case Toolkit::Alignment::VerticalTop:
1714 maxVerticalDisplacement *= 2.f;
1715 minVerticalDisplacement = 0.f;
1718 case Toolkit::Alignment::VerticalCenter:
1723 case Toolkit::Alignment::VerticalBottom:
1725 maxVerticalDisplacement = 0.f;
1726 minVerticalDisplacement *= 2.f;
1731 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1735 // Trims the scroll position to be within the range.
1736 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1737 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1739 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1740 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1743 void TextView::DoSetScrollPosition( const Vector2& position )
1745 // Stores old scroll position.
1746 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1748 // Updates the scroll position
1749 mVisualParameters.mCameraScrollPosition = position;
1751 // Ensures the text-view is covered with text.
1752 TrimScrollPosition();
1754 // Calculate the difference with the previous scroll position
1755 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1756 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1758 if( mOffscreenRootActor )
1760 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1762 mOffscreenRootActor.SetVisible( true );
1765 if( mOffscreenCameraActor )
1767 // Update the offscreen camera with the new scroll position.
1768 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1769 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1774 // Refresh the render-task.
1775 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1779 Toolkit::TextView handle( GetOwner() );
1780 mScrolledSignalV2.Emit( handle, delta );
1783 void TextView::CombineExceedPolicies()
1785 // Calculates the combination of exceed policies.
1787 switch( mLayoutParameters.mWidthExceedPolicy )
1789 case Toolkit::TextView::Original:
1791 switch( mLayoutParameters.mHeightExceedPolicy )
1793 case Toolkit::TextView::Original:
1795 mLayoutParameters.mExceedPolicy = Original;
1798 case Toolkit::TextView::Fade:
1800 mLayoutParameters.mExceedPolicy = OriginalFade;
1803 case Toolkit::TextView::ShrinkToFit:
1805 mLayoutParameters.mExceedPolicy = OriginalShrink;
1810 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1815 case Toolkit::TextView::Split:
1817 switch( mLayoutParameters.mHeightExceedPolicy )
1819 case Toolkit::TextView::Original:
1821 mLayoutParameters.mExceedPolicy = SplitOriginal;
1824 case Toolkit::TextView::Fade:
1826 mLayoutParameters.mExceedPolicy = SplitFade;
1829 case Toolkit::TextView::ShrinkToFit:
1831 mLayoutParameters.mExceedPolicy = SplitShrink;
1836 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1841 case Toolkit::TextView::Fade:
1843 switch( mLayoutParameters.mHeightExceedPolicy )
1845 case Toolkit::TextView::Original:
1847 mLayoutParameters.mExceedPolicy = FadeOriginal;
1850 case Toolkit::TextView::Fade:
1852 mLayoutParameters.mExceedPolicy = Fade;
1857 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1862 case Toolkit::TextView::ShrinkToFit:
1864 switch( mLayoutParameters.mHeightExceedPolicy )
1866 case Toolkit::TextView::Original:
1868 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1871 case Toolkit::TextView::Fade:
1873 mLayoutParameters.mExceedPolicy = ShrinkFade;
1876 case Toolkit::TextView::ShrinkToFit:
1878 mLayoutParameters.mExceedPolicy = Shrink;
1883 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1888 case Toolkit::TextView::EllipsizeEnd:
1890 switch( mLayoutParameters.mHeightExceedPolicy )
1892 case Toolkit::TextView::Original:
1894 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1897 case Toolkit::TextView::EllipsizeEnd:
1899 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1904 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1911 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1916 Actor TextView::GetRootActor() const
1918 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1922 if( mVisualParameters.mSnapshotModeEnabled )
1924 rootActor = mOffscreenRootActor;
1934 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1936 std::string policyName( propertyValue.Get<std::string>() );
1937 if(policyName == "SplitByNewLineChar")
1939 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1941 else if(policyName == "SplitByWord")
1943 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1945 else if(policyName == "SplitByChar")
1947 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1951 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1955 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1957 std::string policyName( propertyValue.Get<std::string>() );
1958 if(policyName == "Original")
1960 SetWidthExceedPolicy(Toolkit::TextView::Original);
1962 else if(policyName == "Truncate")
1964 SetWidthExceedPolicy(Toolkit::TextView::Truncate);
1966 else if(policyName == "Fade")
1968 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1970 else if(policyName == "Split")
1972 SetWidthExceedPolicy(Toolkit::TextView::Split);
1974 else if(policyName == "ShrinkToFit")
1976 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1978 else if(policyName == "EllipsizeEnd")
1980 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1984 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1988 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1990 std::string policyName( propertyValue.Get<std::string>() );
1991 if(policyName == "Original")
1993 SetHeightExceedPolicy(Toolkit::TextView::Original);
1995 else if(policyName == "Truncate")
1997 SetHeightExceedPolicy(Toolkit::TextView::Truncate);
1999 else if(policyName == "Fade")
2001 SetHeightExceedPolicy(Toolkit::TextView::Fade);
2003 else if(policyName == "Split")
2005 SetHeightExceedPolicy(Toolkit::TextView::Split);
2007 else if(policyName == "ShrinkToFit")
2009 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
2013 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
2017 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
2019 std::string policyName( propertyValue.Get<std::string>() );
2020 if(policyName == "Left")
2022 SetLineJustification(Toolkit::TextView::Left);
2024 else if(policyName == "Center")
2026 SetLineJustification(Toolkit::TextView::Center);
2028 else if(policyName == "Right")
2030 SetLineJustification(Toolkit::TextView::Right);
2032 else if(policyName == "Justified")
2034 SetLineJustification(Toolkit::TextView::Justified);
2038 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2042 void TextView::OnFadeBoundaryPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2044 PixelSize boundary( propertyValue.Get<unsigned int>() );
2046 if ( propertyIndex == mPropertyFadeBoundaryLeft )
2048 mVisualParameters.mFadeBoundary.mLeft = boundary;
2050 else if ( propertyIndex == mPropertyFadeBoundaryRight )
2052 mVisualParameters.mFadeBoundary.mRight = boundary;
2054 else if ( propertyIndex == mPropertyFadeBoundaryTop )
2056 mVisualParameters.mFadeBoundary.mTop = boundary;
2058 else if ( propertyIndex == mPropertyFadeBoundaryBottom )
2060 mVisualParameters.mFadeBoundary.mBottom = boundary;
2064 DALI_ASSERT_ALWAYS( !"TextView::OnFadeBoundaryPropertySet(). Invalid Property value." );
2068 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2070 std::string value( propertyValue.Get<std::string>() );
2072 if( propertyIndex == mPropertyHorizontalAlignment )
2074 if(value == "HorizontalLeft")
2076 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2078 else if( value == "HorizontalCenter")
2080 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2082 else if( value == "HorizontalRight")
2084 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2088 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2091 else if( propertyIndex == mPropertyVerticalAlignment )
2093 if( value == "VerticalTop" )
2095 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2097 else if( value == "VerticalCenter")
2099 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2101 else if( value == "VerticalBottom")
2103 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2107 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2112 } // namespace Internal
2114 } // namespace Toolkit