2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/controls/text-view/text-view-impl.h>
22 #include <dali-toolkit/internal/controls/text-view/split-by-new-line-char-policies.h>
23 #include <dali-toolkit/internal/controls/text-view/split-by-word-policies.h>
24 #include <dali-toolkit/internal/controls/text-view/split-by-char-policies.h>
25 #include <dali-toolkit/internal/controls/text-view/text-processor-bidirectional-info.h>
26 #include <dali-toolkit/internal/controls/text-view/text-view-processor.h>
27 #include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
28 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
36 const Property::Index TextView::PROPERTY_MARKUP_ENABLED( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX );
37 const Property::Index TextView::PROPERTY_TEXT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 1 );
38 const Property::Index TextView::PROPERTY_MULTILINE_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 2 );
39 const Property::Index TextView::PROPERTY_WIDTH_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 3 );
40 const Property::Index TextView::PROPERTY_HEIGHT_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 4 );
41 const Property::Index TextView::PROPERTY_LINE_JUSTIFICATION( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 5 );
42 const Property::Index TextView::PROPERTY_FADE_BOUNDARY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 6 );
43 const Property::Index TextView::PROPERTY_LINE_HEIGHT_OFFSET( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 7 );
44 const Property::Index TextView::PROPERTY_HORIZONTAL_ALIGNMENT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 8 );
45 const Property::Index TextView::PROPERTY_VERTICAL_ALIGNMENT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 9 );
53 const char* MULTILINE_POLICY_NAME[] = {"SplitByNewLineChar", "SplitByWord", "SplitByChar"};
54 const char* EXCEED_POLICY_NAME[] = {"Original", "Truncate", "Fade", "Split","ShrinkToFit","EllipsizeEnd"};
55 const char* LINE_JUSTIFICATION_NAME[] = {"Left","Center","Right","Justified"};
57 // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
58 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
63 return Toolkit::TextView::New();
66 TypeRegistration typeRegistration( typeid(Toolkit::TextView), typeid(Toolkit::Control), Create );
68 SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal );
70 PropertyRegistration property1( typeRegistration, "markup-enabled", Toolkit::TextView::PROPERTY_MARKUP_ENABLED, Property::BOOLEAN, &TextView::SetProperty, &TextView::GetProperty );
71 PropertyRegistration property2( typeRegistration, "text", Toolkit::TextView::PROPERTY_TEXT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
72 PropertyRegistration property3( typeRegistration, "multiline-policy", Toolkit::TextView::PROPERTY_MULTILINE_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
73 PropertyRegistration property4( typeRegistration, "width-exceed-policy", Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
74 PropertyRegistration property5( typeRegistration, "height-exceed-policy", Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
75 PropertyRegistration property6( typeRegistration, "line-justification", Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
76 PropertyRegistration property7( typeRegistration, "fade-boundary", Toolkit::TextView::PROPERTY_FADE_BOUNDARY, Property::VECTOR4, &TextView::SetProperty, &TextView::GetProperty );
77 PropertyRegistration property8( typeRegistration, "line-height-offset", Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET, Property::FLOAT, &TextView::SetProperty, &TextView::GetProperty );
78 PropertyRegistration property9( typeRegistration, "horizontal-alignment", Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
79 PropertyRegistration property10( typeRegistration, "vertical-alignment", Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
82 * Whether the text-view-processor operation sets, inserts, replaces, removes text.
84 * @param[in] metadata The text-view-processor operation.
86 * @return \e true if the given text-view-processor operation is modifying the text.
88 bool IsTextViewProcessorRelayoutOperation( const TextView::TextViewProcessorMetadata& metadata )
90 return ( ( metadata.mType == TextView::TextSet ) ||
91 ( metadata.mType == TextView::TextInserted ) ||
92 ( metadata.mType == TextView::TextReplaced ) ||
93 ( metadata.mType == TextView::TextRemoved ) ||
94 ( metadata.mType == TextView::NewStyle ));
98 * Whether the text-view-processor operation sets a new line height offset.
100 * @param[in] metadata The text-view-processor operation.
102 * @return \e true if the given text-view-processor operation sets a new line height offset.
104 bool IsTextViewProcessorLineHeightOffsetOperation( const TextView::TextViewProcessorMetadata& metadata )
106 return ( metadata.mType == TextView::NewLineHeight );
110 * Whether the text-view-processor operation sets a new style.
112 * @param[in] metadata The text-view-processor operation.
114 * @return \e true if the given text-view-processor operation sets a new style.
116 bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMetadata& metadata )
118 return ( metadata.mType == TextView::NewStyle );
123 TextView::TextViewProcessorMetadata::TextViewProcessorMetadata()
124 : mType( TextView::TextSet ),
126 mNumberOfCharacters( 0u ),
131 Toolkit::TextView TextView::New()
133 // Create the implementation, temporarily owned on stack
134 IntrusivePtr<TextView> textView = new TextView();
136 // Pass ownership to CustomActor
137 Toolkit::TextView handle( *textView );
139 // Second-phase init of the implementation
140 // This can only be done after the CustomActor connection has been made...
141 textView->Initialize();
143 // Disables by default the offscreen rendering.
144 textView->SetSnapshotModeEnabled( false );
149 void TextView::SetText( const std::string& text )
151 // Creates a styled text with the markup or plain string.
152 MarkupProcessor::StyledTextArray styledText;
153 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
155 // Calls SetText() with the styled text array.
156 SetText( styledText );
159 void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
161 // mTextViewProcessorOperations stores the InsertTextAt and RemoveTextFrom operations to transform the initial text to mCurrentStyledText.
162 // Once again, if a new text is set, any previous call to InsertTextAt or RemoveTextFrom can be discarted.
164 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorRelayoutOperation );
165 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
167 // Creates metadata with the Set operation.
168 TextViewProcessorMetadata metadata;
169 metadata.mType = TextView::TextSet;
170 metadata.mText = text;
173 mTextViewProcessorOperations.push_back( metadata );
175 // Updates current styled text.
176 mCurrentStyledText = text;
178 // Request to be relaid out
181 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
182 mRelayoutOperations = RELAYOUT_ALL;
185 void TextView::InsertTextAt( std::size_t position, const std::string& text )
187 // Creates a styled text with the markup or plain string.
188 MarkupProcessor::StyledTextArray styledText;
189 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
191 // Calls InsertTextAt() with the styled text array.
192 InsertTextAt( position, styledText );
195 void TextView::InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text )
198 MarkupProcessor::GetPlainString( text, textStr );
200 if( TextProcessor::ContainsRightToLeftCharacter( Text( textStr ) ) ||
201 TextProcessor::ContainsRightToLeftCharacter( Text( GetText() ) ) )
203 // Temporary fix. Creates the whole layout if there is rtl text.
205 MarkupProcessor::StyledTextArray textToSet = mCurrentStyledText;
206 textToSet.insert( textToSet.begin() + position, text.begin(), text.end() );
207 SetText( textToSet );
211 // Creates metadata with the Insert operation.
212 TextViewProcessorMetadata metadata;
213 metadata.mType = TextView::TextInserted;
214 metadata.mPosition = position;
215 metadata.mText = text;
218 mTextViewProcessorOperations.push_back( metadata );
220 // Updates current styled text.
221 mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
223 // Request to be relaid out
226 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
227 mRelayoutOperations = RELAYOUT_ALL;
231 void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
233 // Creates a styled text with the markup or plain string.
234 MarkupProcessor::StyledTextArray styledText;
235 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
237 // Calls ReplaceTextFromTo() with the styled text array.
238 ReplaceTextFromTo( position, numberOfCharacters, styledText );
241 void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
243 // Creates metadata with the Insert operation.
244 TextViewProcessorMetadata metadata;
245 metadata.mType = TextView::TextReplaced;
246 metadata.mPosition = position;
247 metadata.mNumberOfCharacters = numberOfCharacters;
248 metadata.mText = text;
251 mTextViewProcessorOperations.push_back( metadata );
253 // Updates current styled text.
254 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
255 mCurrentStyledText.erase( it, it + numberOfCharacters );
256 it = mCurrentStyledText.begin() + position;
257 mCurrentStyledText.insert( it, text.begin(), text.end() );
259 // Request to be relaid out
262 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
263 mRelayoutOperations = RELAYOUT_ALL;
266 void TextView::RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters )
268 // Creates metadata with the Remove operation.
269 TextViewProcessorMetadata metadata;
270 metadata.mType = TextView::TextRemoved;
271 metadata.mPosition = position;
272 metadata.mNumberOfCharacters = numberOfCharacters;
275 mTextViewProcessorOperations.push_back( metadata );
277 // Updates current styled text.
278 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
279 mCurrentStyledText.erase( it, it + numberOfCharacters );
281 // Request to be relaid out
284 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
285 mRelayoutOperations = RELAYOUT_ALL;
288 std::string TextView::GetText() const
290 // Traverses the styled text array getting only the text.
291 // Note that for some languages a 'character' could be represented by more than one 'char'
294 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); it != endIt; ++it )
296 text.append( (*it).mText.GetText() );
302 void TextView::SetLineHeightOffset( PointSize offset )
304 if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 )
306 // Removes any previous operation which modifies the line height offset.
307 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorLineHeightOffsetOperation );
308 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
310 // Creates metadata with the new line height operation.
311 TextViewProcessorMetadata metadata;
312 metadata.mType = TextView::NewLineHeight;
314 mTextViewProcessorOperations.push_back( metadata );
316 // Updates line height offset.
317 mLayoutParameters.mLineHeightOffset = offset;
321 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
322 if( RELAYOUT_ALL != mRelayoutOperations )
324 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
325 RELAYOUT_REMOVE_TEXT_ACTORS |
326 RELAYOUT_SIZE_POSITION |
328 RELAYOUT_VISIBILITY |
329 RELAYOUT_TEXT_ACTOR_UPDATE |
330 RELAYOUT_INSERT_TO_TEXT_VIEW );
335 PointSize TextView::GetLineHeightOffset() const
337 return PointSize( mLayoutParameters.mLineHeightOffset );
340 void TextView::SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask )
342 if( !mCurrentStyledText.empty() )
344 const bool checkFontName = mask & TextStyle::FONT;
345 const bool checkFontSize = mask & TextStyle::SIZE;
346 const bool checkFontStyle = mask & TextStyle::STYLE;
348 // Check first if metrics have changed.
349 bool metricsChanged = false;
350 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
352 const MarkupProcessor::StyledText& styledText( *it );
354 metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
355 ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
356 ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
361 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
363 // If metrics change, new text measurements are needed.
364 SetText( mCurrentStyledText );
368 // Deletes any previous operation which sets a new style.
369 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
370 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
372 // Creates metadata with the new style operation.
373 TextViewProcessorMetadata metadata;
374 metadata.mType = TextView::NewStyle;
376 MarkupProcessor::StyledText text;
378 metadata.mText.push_back( text );
379 metadata.mStyleMask = mask;
381 mTextViewProcessorOperations.push_back( metadata );
383 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
387 if( RELAYOUT_ALL != mRelayoutOperations )
389 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
390 RELAYOUT_TEXT_ACTOR_UPDATE );
395 // Sets the new style to the ellipsize text
396 // TODO: fix this as a call to SetEllipsizeText will trigger the creation of new text actors.
397 if( 0u < mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Count() )
399 for( Vector<TextStyle*>::Iterator it = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.Begin(),
400 endIt = mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles.End();
404 (*it)->Copy( style, mask );
407 SetEllipsizeText( mRelayoutData.mTextLayoutInfo.mEllipsisText, mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles );
411 void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
413 if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
415 Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
416 ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
417 ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
418 Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
419 ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
420 ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
422 mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
423 mLayoutParameters.mVerticalAlignment = verticalAlignment;
427 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
428 if( RELAYOUT_ALL != mRelayoutOperations )
430 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
431 RELAYOUT_TEXT_ACTOR_UPDATE |
433 RELAYOUT_VISIBILITY );
438 Toolkit::Alignment::Type TextView::GetTextAlignment() const
440 return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
443 void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
445 if( policy != mLayoutParameters.mMultilinePolicy )
447 mLayoutParameters.mMultilinePolicy = policy;
449 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
450 mRelayoutOperations = RELAYOUT_ALL;
456 Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
458 return mLayoutParameters.mMultilinePolicy;
461 void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
463 // The layout info could be invalid depending on the current exceed policy and the new one.
464 // i.e. if the current policy is Split and the new one is ShrinkToFit then
465 // the layout info generated for each char is not needed.
466 if( policy != mLayoutParameters.mWidthExceedPolicy )
468 mLayoutParameters.mWidthExceedPolicy = policy;
470 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
471 mRelayoutOperations = RELAYOUT_ALL;
477 Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
479 return mLayoutParameters.mWidthExceedPolicy;
482 void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
484 if( policy != mLayoutParameters.mHeightExceedPolicy )
486 mLayoutParameters.mHeightExceedPolicy = policy;
490 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
491 if( RELAYOUT_ALL != mRelayoutOperations )
493 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
494 RELAYOUT_REMOVE_TEXT_ACTORS |
495 RELAYOUT_SIZE_POSITION |
497 RELAYOUT_VISIBILITY |
498 RELAYOUT_TEXT_ACTOR_UPDATE |
499 RELAYOUT_INSERT_TO_TEXT_VIEW );
504 Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
506 return mLayoutParameters.mHeightExceedPolicy;
509 void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
511 if( justification != mLayoutParameters.mLineJustification )
513 mLayoutParameters.mLineJustification = justification;
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_SIZE_POSITION |
524 RELAYOUT_VISIBILITY |
525 RELAYOUT_TEXT_ACTOR_UPDATE |
526 RELAYOUT_INSERT_TO_TEXT_VIEW );
531 Toolkit::TextView::LineJustification TextView::GetLineJustification() const
533 return mLayoutParameters.mLineJustification;
536 void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
538 if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
539 ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
540 ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
541 ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
543 mVisualParameters.mFadeBoundary = fadeBoundary;
547 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
548 if( RELAYOUT_ALL != mRelayoutOperations )
550 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
551 RELAYOUT_REMOVE_TEXT_ACTORS |
552 RELAYOUT_VISIBILITY |
553 RELAYOUT_TEXT_ACTOR_UPDATE |
554 RELAYOUT_INSERT_TO_TEXT_VIEW );
559 const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
561 return mVisualParameters.mFadeBoundary;
564 void TextView::SetEllipsizeText( const std::string& ellipsizeText )
566 // Creates a styled text with the markup or plain string.
567 MarkupProcessor::StyledTextArray styledText;
568 MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() );
570 // Creates the ellipsis layout info and sets the text and styles.
571 SetEllipsizeText( styledText );
574 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
576 // Converts the styled text array into a Text and a vector of TextStyles.
578 Vector<TextStyle*> styles;
579 for( MarkupProcessor::StyledTextArray::const_iterator it = ellipsizeText.begin(), endIt = ellipsizeText.end(); it != endIt; ++it )
581 const MarkupProcessor::StyledText& styledText( *it );
583 text.Append( styledText.mText );
584 styles.PushBack( new TextStyle( styledText.mStyle ) );
587 // Creates the ellipsis layout info and sets the text and styles.
588 SetEllipsizeText( text, styles );
591 void TextView::SetEllipsizeText( const Text& ellipsizeText, const Vector<TextStyle*>& ellipsizeStyles )
593 // Sets the text and styles for the ellipsis text.
594 mRelayoutData.mTextLayoutInfo.mEllipsisText = ellipsizeText;
595 mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles = ellipsizeStyles;
597 // Creates the ellipsis layout info.
598 CreateEllipsizeLayout();
600 // Request to be relaid out
603 mRelayoutOperations = RELAYOUT_ALL;
606 std::string TextView::GetEllipsizeText() const
608 return mRelayoutData.mTextLayoutInfo.mEllipsisText.GetText();
611 void TextView::GetTextLayoutInfo()
613 const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
614 const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
615 const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
617 if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
619 Vector3 textViewSize = GetControlSize();
621 if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
622 ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
623 ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
624 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
625 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
627 // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
628 // the text natural size can be used.
629 textViewSize = GetNaturalSize();
632 if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
633 ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
635 // Check if the text-view has glyph-actors.
636 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
638 RelayoutOperationMask mask = NO_RELAYOUT;
639 if( relayoutSizeAndPositionNeeded )
641 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
643 if( relayoutAlignmentNeeded )
645 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
647 if( relayoutVisibilityNeeded )
649 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
654 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
655 // add them to the text-actor cache.
656 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
657 mRelayoutData.mGlyphActors.clear();
660 // Relays-out but doesn't add glyph-actors to the text-view.
661 DoRelayOut( textViewSize.GetVectorXY(), mask );
665 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
671 void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
675 textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
676 textLayoutInfo.mLines = mRelayoutData.mLines;
678 textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
679 textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
681 textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
683 textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
686 void TextView::SetSortModifier( float depthOffset )
688 mVisualParameters.mSortModifier = depthOffset;
690 for( std::vector<RenderableActor>::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.end();
694 ( *it ).SetSortModifier( depthOffset );
697 if( mOffscreenImageActor )
699 mOffscreenImageActor.SetSortModifier( depthOffset );
703 void TextView::SetSnapshotModeEnabled( bool enable )
705 if( enable != mVisualParameters.mSnapshotModeEnabled )
707 // Remove first all glyph-actors
708 if( !mRelayoutData.mGlyphActors.empty() )
710 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
713 mVisualParameters.mSnapshotModeEnabled = enable;
714 if( !mLockPreviousSnapshotMode )
716 // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
717 // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
719 // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
720 // to smash the stored value.
721 mPreviousSnapshotModeEnabled = enable;
724 if( mVisualParameters.mSnapshotModeEnabled )
726 // Create a root actor and an image actor for offscreen rendering.
727 mOffscreenRootActor = Layer::New();
728 mOffscreenImageActor = ImageActor::New();
730 mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
731 mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
732 mOffscreenRootActor.SetInheritRotation( false );
733 mOffscreenRootActor.SetInheritScale( false );
734 mOffscreenRootActor.SetDepthTestDisabled( true );
736 mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
738 mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
739 mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
740 mOffscreenImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
741 BlendingFactor::ONE, BlendingFactor::ONE );
744 self.Add( mOffscreenRootActor );
745 self.Add( mOffscreenImageActor );
746 mOffscreenImageActor.SetScale( Vector3( 1.f, -1.f, 1.f ) );
752 if( mOffscreenRootActor )
754 self.Remove( mOffscreenRootActor );
757 if( mOffscreenImageActor )
759 self.Remove( mOffscreenImageActor );
762 DestroyOffscreenRenderingResources();
765 if( RELAYOUT_ALL != mRelayoutOperations )
767 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
768 RELAYOUT_REMOVE_TEXT_ACTORS |
769 RELAYOUT_TEXT_ACTOR_UPDATE |
770 RELAYOUT_INSERT_TO_TEXT_VIEW );
776 bool TextView::IsSnapshotModeEnabled() const
778 return mVisualParameters.mSnapshotModeEnabled;
781 void TextView::SetMarkupProcessingEnabled( bool enable )
783 mMarkUpEnabled = enable;
786 bool TextView::IsMarkupProcessingEnabled() const
788 return mMarkUpEnabled;
791 void TextView::SetScrollEnabled( bool enable )
793 if( enable != mVisualParameters.mScrollEnabled )
795 mVisualParameters.mScrollEnabled = enable;
797 if( mVisualParameters.mScrollEnabled )
799 // Offscreen rendering is needed to enable text scroll.
801 // Stores previous value of the snapshot mode.
802 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
805 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
806 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
807 Lock lock( mLockPreviousSnapshotMode );
808 SetSnapshotModeEnabled( true );
811 // Creates the pan gesture detector and attach the text-view.
812 mPanGestureDetector = PanGestureDetector::New();
813 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
814 mPanGestureDetector.Attach( Self() );
818 // Removes the pan gesture detector.
819 if( mPanGestureDetector )
821 mPanGestureDetector.Detach( Self() );
822 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
823 mPanGestureDetector.Reset();
826 // Restores the previous state for snapshot mode.
827 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
832 bool TextView::IsScrollEnabled() const
834 return mVisualParameters.mScrollEnabled;
837 void TextView::SetScrollPosition( const Vector2& position )
839 if( position != mVisualParameters.mCameraScrollPosition )
841 // Guard against destruction during signal emission
842 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
843 Toolkit::TextView handle( GetOwner() );
845 DoSetScrollPosition( position );
847 // Check if the new scroll position has been trimmed.
848 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
852 const Vector2& TextView::GetScrollPosition() const
854 return mVisualParameters.mCameraScrollPosition;
857 bool TextView::IsScrollPositionTrimmed() const
859 return mVisualParameters.mScrollPositionTrimmed;
862 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
864 return mScrolledSignalV2;
867 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
869 Dali::BaseHandle handle( object );
871 bool connected( true );
872 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
874 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
876 textView.ScrolledSignal().Connect( tracker, functor );
880 // signalName does not match any signal
887 TextView::LayoutParameters::LayoutParameters()
888 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
889 mWidthExceedPolicy( Toolkit::TextView::Original ),
890 mHeightExceedPolicy( Toolkit::TextView::Original ),
891 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
892 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
893 mLineJustification( Toolkit::TextView::Left ),
894 mLineHeightOffset( 0.f ),
895 mMarkUpEnabled( false )
899 TextView::LayoutParameters::~LayoutParameters()
903 TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy,
904 Toolkit::TextView::ExceedPolicy widthExceedPolicy,
905 Toolkit::TextView::ExceedPolicy heightExceedPolicy,
906 Toolkit::Alignment::Type alignmentType,
907 Toolkit::TextView::LineJustification lineJustification,
908 float lineHeightOffset,
910 : mMultilinePolicy( multilinePolicy ),
911 mWidthExceedPolicy( widthExceedPolicy ),
912 mHeightExceedPolicy( heightExceedPolicy ),
913 mHorizontalAlignment(),
914 mVerticalAlignment(),
915 mLineJustification( lineJustification ),
916 mLineHeightOffset( lineHeightOffset ),
917 mMarkUpEnabled( markUpEnabled )
920 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
921 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
922 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
923 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
924 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
925 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
927 mHorizontalAlignment = horizontalAlignment;
928 mVerticalAlignment = verticalAlignment;
931 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
932 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
933 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
934 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
935 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
936 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
937 mLineJustification( layoutParameters.mLineJustification ),
938 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
939 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
943 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
945 mMultilinePolicy = layoutParameters.mMultilinePolicy;
946 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
947 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
948 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
949 mVerticalAlignment = layoutParameters.mVerticalAlignment;
950 mLineJustification = layoutParameters.mLineJustification;
951 mLineHeightOffset = layoutParameters.mLineHeightOffset;
952 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
957 TextView::VisualParameters::VisualParameters()
959 mSortModifier( 0.f ),
960 mCameraScrollPosition( 0.f, 0.f ),
961 mSnapshotModeEnabled( false ),
962 mScrollEnabled( false ),
963 mScrollPositionTrimmed( false )
967 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
968 : mFadeBoundary( visualParameters.mFadeBoundary ),
969 mSortModifier( visualParameters.mSortModifier ),
970 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
971 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
972 mScrollEnabled( visualParameters.mScrollEnabled ),
973 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
977 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
979 mFadeBoundary = visualParameters.mFadeBoundary;
980 mSortModifier = visualParameters.mSortModifier;
981 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
982 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
983 mScrollEnabled = visualParameters.mScrollEnabled;
984 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
989 TextView::RelayoutData::RelayoutData()
991 mShrinkFactor( 1.f ),
993 mCharacterLogicalToVisualMap(),
994 mCharacterVisualToLogicalMap(),
996 mCharacterLayoutInfoTable(),
998 mTextSizeForRelayoutOption()
1002 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
1003 : mTextViewSize( relayoutData.mTextViewSize ),
1004 mShrinkFactor( relayoutData.mShrinkFactor ),
1005 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
1006 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
1007 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
1008 mGlyphActors( relayoutData.mGlyphActors ),
1009 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
1010 mLines( relayoutData.mLines ),
1011 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
1015 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
1017 mTextViewSize = relayoutData.mTextViewSize;
1018 mShrinkFactor = relayoutData.mShrinkFactor;
1019 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
1020 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
1021 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
1022 mGlyphActors = relayoutData.mGlyphActors;
1023 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1024 mLines = relayoutData.mLines;
1025 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1030 TextView::TextView()
1031 : Control( REQUIRES_STYLE_CHANGE_SIGNALS ),
1032 mCurrentStyledText(),
1033 mTextViewProcessorOperations(),
1034 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1035 Toolkit::TextView::Original,
1036 Toolkit::TextView::Original,
1037 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1038 Toolkit::TextView::Left,
1041 mVisualParameters(),
1043 mRelayoutOperations( NO_RELAYOUT ),
1044 mOffscreenRootActor(),
1045 mOffscreenImageActor(),
1046 mOffscreenCameraActor(),
1047 mCurrentOffscreenSize(),
1048 mFrameBufferImage(),
1050 mPanGestureDetector(),
1051 mLockPreviousSnapshotMode( false ),
1052 mPreviousSnapshotModeEnabled( false ),
1053 mMarkUpEnabled( false )
1055 // Creates the ellipsis layout info.
1056 CreateEllipsizeLayout();
1059 TextView::~TextView()
1061 // Destroys offscreen rendering resources.
1062 DestroyOffscreenRenderingResources();
1064 // Destroys scroll pan gesture detector.
1065 if( mPanGestureDetector )
1067 mPanGestureDetector.Reset();
1071 Vector3 TextView::GetNaturalSize()
1073 if( !mTextViewProcessorOperations.empty() )
1075 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1077 if( !mRelayoutData.mGlyphActors.empty() )
1079 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1080 // add them to the text-actor cache.
1081 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1082 mRelayoutData.mGlyphActors.clear();
1084 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1087 PerformTextViewProcessorOperations();
1090 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1093 float TextView::GetHeightForWidth( float width )
1097 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1098 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1099 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1101 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1102 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1103 height = GetNaturalSize().height;
1107 // Check if the given width is different than the current one.
1108 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1110 // Check if the text-view has glyph-actors.
1111 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1113 // Check which layout operations need to be done.
1114 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1116 if( relayoutSizeAndPositionNeeded )
1118 if( hasGlyphActors )
1120 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1121 // add them to the text-actor cache.
1122 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1123 mRelayoutData.mGlyphActors.clear();
1126 // Use the given width.
1127 const Vector2 textViewSize( width, GetControlSize().height );
1129 // Relays-out but doesn't add glyph-actors to the text-view.
1130 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1133 // Retrieve the text height after relayout the text.
1134 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1136 if( differentWidth )
1138 // Revert the relayout operation mask
1139 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1142 if( hasGlyphActors )
1144 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1147 if( differentWidth || hasGlyphActors )
1156 float TextView::GetWidthForHeight( float height )
1158 // TODO: Needs implementing properly, for now just return the natural width.
1159 return GetNaturalSize().width;
1163 void TextView::OnInitialize()
1168 void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
1170 // Creates the ellipsis layout info.
1171 CreateEllipsizeLayout();
1173 SetText( mCurrentStyledText );
1176 void TextView::OnControlSizeSet( const Vector3& size )
1178 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1180 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1181 mRelayoutOperations = RELAYOUT_ALL;
1183 // Request to be relaid out
1188 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1190 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1192 // Not worth to relayout if width or height is equal to zero.
1196 if( size != mRelayoutData.mTextViewSize )
1198 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1199 if( RELAYOUT_ALL != mRelayoutOperations )
1201 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1202 RELAYOUT_REMOVE_TEXT_ACTORS |
1203 RELAYOUT_SIZE_POSITION |
1204 RELAYOUT_ALIGNMENT |
1205 RELAYOUT_VISIBILITY |
1206 RELAYOUT_TEXT_ACTOR_UPDATE |
1207 RELAYOUT_INSERT_TO_TEXT_VIEW );
1211 if( ( Toolkit::TextView::Fade == mLayoutParameters.mWidthExceedPolicy ) ||
1212 ( Toolkit::TextView::Fade == mLayoutParameters.mHeightExceedPolicy ) )
1214 if( mRelayoutOperations & RELAYOUT_ALIGNMENT )
1216 // If the text of the alignment changes and a fade exceed policy is set,
1217 // some characters may need new TextActor.
1218 mRelayoutOperations = RELAYOUT_ALL;
1222 // Remove glyph-actors from text-view
1223 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1225 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1226 mRelayoutData.mGlyphActors.clear();
1229 if( NO_RELAYOUT != mRelayoutOperations )
1231 // Relays-out and add glyph-actors to the text-view.
1232 DoRelayOut( size, mRelayoutOperations );
1233 ProcessSnapshot( size );
1236 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1237 mRelayoutData.mTextActorCache.ClearTexts();
1240 void TextView::PerformTextViewProcessorOperations()
1242 // Traverse the relayout operation vector ...
1244 // Optimizes some operations.
1245 OptimizeTextViewProcessorOperations();
1247 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1249 const TextViewProcessorMetadata& relayoutMetadata( *it );
1251 switch( relayoutMetadata.mType )
1253 case TextView::TextSet:
1255 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1260 case TextView::TextInserted:
1262 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1263 relayoutMetadata.mText,
1268 case TextView::TextReplaced:
1270 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1271 relayoutMetadata.mNumberOfCharacters,
1272 relayoutMetadata.mText,
1277 case TextView::TextRemoved:
1279 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1280 relayoutMetadata.mNumberOfCharacters,
1283 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1286 case TextView::NewLineHeight:
1288 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1289 mRelayoutData.mTextLayoutInfo );
1292 case TextView::NewStyle:
1294 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1295 relayoutMetadata.mStyleMask,
1302 // Clear all operations when they are done.
1303 mTextViewProcessorOperations.clear();
1306 void TextView::OptimizeTextViewProcessorOperations()
1308 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1310 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1311 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1312 // use the cache without clearing the text-actors.
1314 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1316 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1318 const TextViewProcessorMetadata& relayoutMetadata( *it );
1320 switch( relayoutMetadata.mType )
1322 case TextView::TextRemoved:
1324 bool optimizationDone = false;
1326 if( it + 1u != endIt )
1328 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1u ) );
1329 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1331 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1333 optimizationDone = true;
1334 TextViewProcessorMetadata newRelayoutMetadata;
1335 newRelayoutMetadata.mType = TextView::TextReplaced;
1336 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1337 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1338 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1339 textViewProcessorOperations.push_back( newRelayoutMetadata );
1341 // do not access the TextInserted operation in next iteration.
1347 if( !optimizationDone )
1349 textViewProcessorOperations.push_back( relayoutMetadata );
1355 textViewProcessorOperations.push_back( relayoutMetadata );
1360 mTextViewProcessorOperations = textViewProcessorOperations;
1363 void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask )
1365 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1366 if( !mTextViewProcessorOperations.empty() )
1368 PerformTextViewProcessorOperations();
1371 CombineExceedPolicies();
1374 if( mVisualParameters.mSnapshotModeEnabled )
1376 rootActor = mOffscreenRootActor;
1383 mRelayoutData.mTextViewSize = textViewSize;
1384 switch( mLayoutParameters.mMultilinePolicy )
1386 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1388 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1390 } // SplitByNewLineChar
1392 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1394 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1398 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1400 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1403 } // switch( mMultilinePolicy )
1405 // Remove done operations from the mask.
1406 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1409 void TextView::ProcessSnapshot( const Size& textViewSize )
1411 if( mVisualParameters.mSnapshotModeEnabled )
1413 // If layout options change, it's needed generate a new image.
1415 if( mOffscreenRootActor )
1417 // Set the root actor visible.
1418 // The root actor is set to non visible after the render task is processed.
1419 mOffscreenRootActor.SetVisible( true );
1421 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1422 mOffscreenRootActor.SetSize( textViewSize );
1425 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1426 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1428 // Set the image actor visible.
1429 // The image actor is set to non visible if there is no text to render.
1430 mOffscreenImageActor.SetVisible( true );
1432 // Calculates the offscreen image's size. It takes into account different points:
1433 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1434 // * There is a maximum texture size the graphic subsystem can load on the memory.
1435 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1437 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1438 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1439 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1440 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1442 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1446 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1447 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1448 offscreenSize.height,
1451 // Stores current text-view size to avoid create new Dali resources if text changes.
1452 mCurrentOffscreenSize = offscreenSize;
1454 if( !mOffscreenCameraActor )
1456 // Creates a new camera actor.
1457 mOffscreenCameraActor = CameraActor::New();
1458 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1459 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1460 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1462 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1464 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1467 // Calculate camera parameters for current text size.
1468 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1471 if( mVisualParameters.mScrollEnabled )
1473 // Updates the offscreen camera position with the new scroll offset.
1474 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1475 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1479 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1480 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1485 // Creates a new render task.
1486 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1488 mRenderTask.SetSourceActor( mOffscreenRootActor );
1489 mRenderTask.SetInputEnabled( false );
1490 mRenderTask.SetClearColor( Color::TRANSPARENT );
1491 mRenderTask.SetClearEnabled( true );
1492 mRenderTask.SetExclusive( true );
1494 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1495 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1500 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1501 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1504 // Process the render task only once every time the text changes or the text-view's size canges.
1505 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1509 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1510 mOffscreenImageActor.SetVisible( false );
1515 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1517 float xPosition = 0.f;
1518 float yPosition = 0.f;
1519 Vector3 parentOrigin = ParentOrigin::CENTER;
1520 Vector3 anchorPoint = AnchorPoint::CENTER;
1522 switch( mLayoutParameters.mHorizontalAlignment )
1524 case Toolkit::Alignment::HorizontalLeft:
1526 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1527 parentOrigin.x = 0.f;
1528 anchorPoint.x = 0.f;
1531 case Toolkit::Alignment::HorizontalCenter:
1536 case Toolkit::Alignment::HorizontalRight:
1538 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1539 parentOrigin.x = 1.f;
1540 anchorPoint.x = 1.f;
1545 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1549 switch( mLayoutParameters.mVerticalAlignment )
1551 case Toolkit::Alignment::VerticalTop:
1553 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1554 parentOrigin.y = 0.f;
1555 anchorPoint.y = 0.f;
1558 case Toolkit::Alignment::VerticalCenter:
1563 case Toolkit::Alignment::VerticalBottom:
1565 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1566 parentOrigin.y = 1.f;
1567 anchorPoint.y = 1.f;
1572 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1576 mOffscreenCameraActor.SetX( xPosition );
1577 mOffscreenCameraActor.SetY( yPosition );
1579 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1580 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1583 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1585 // not to process the offscreen root actor by setting its visibility to false.
1586 mOffscreenRootActor.SetVisible( false );
1588 // Sets the new size and the new frame buffer to the image actor.
1589 // Image actor must have same size as text. Otherwise text can be truncated.
1590 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1591 mOffscreenImageActor.SetImage( mFrameBufferImage );
1594 void TextView::DestroyOffscreenRenderingResources()
1598 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1600 if( Stage::IsInstalled() )
1602 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1605 mRenderTask.Reset();
1608 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1609 if( mOffscreenCameraActor )
1611 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1613 mOffscreenCameraActor.Reset();
1616 if( mOffscreenRootActor )
1618 mOffscreenRootActor.Reset();
1621 if( mOffscreenImageActor )
1623 mOffscreenImageActor.Reset();
1626 mCurrentOffscreenSize = Size( 0.f, 0.f );
1628 if( mFrameBufferImage )
1630 mFrameBufferImage.Reset();
1634 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1636 if( 1u == gesture.numberOfTouches )
1638 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1642 void TextView::TrimScrollPosition()
1644 const Vector3& textViewSize = GetControlSize();
1646 // Before use the text's size, relayout the text is needed to get the actual text size.
1647 GetTextLayoutInfo();
1649 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1650 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1651 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1652 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1653 float minVerticalDisplacement = -maxVerticalDisplacement;
1655 // Updates the range if the text is aligned on the right or left.
1656 switch( mLayoutParameters.mHorizontalAlignment )
1658 case Toolkit::Alignment::HorizontalLeft:
1660 maxHorizontalDisplacement *= 2.f;
1661 minHorizontalDisplacement = 0.f;
1664 case Toolkit::Alignment::HorizontalCenter:
1669 case Toolkit::Alignment::HorizontalRight:
1671 maxHorizontalDisplacement = 0.f;
1672 minHorizontalDisplacement *= 2.f;
1677 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1681 // Updates the range if the text is aligned on the top or bottom.
1682 switch( mLayoutParameters.mVerticalAlignment )
1684 case Toolkit::Alignment::VerticalTop:
1686 maxVerticalDisplacement *= 2.f;
1687 minVerticalDisplacement = 0.f;
1690 case Toolkit::Alignment::VerticalCenter:
1695 case Toolkit::Alignment::VerticalBottom:
1697 maxVerticalDisplacement = 0.f;
1698 minVerticalDisplacement *= 2.f;
1703 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1707 // Trims the scroll position to be within the range.
1708 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1709 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1711 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1712 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1715 void TextView::DoSetScrollPosition( const Vector2& position )
1717 // Stores old scroll position.
1718 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1720 // Updates the scroll position
1721 mVisualParameters.mCameraScrollPosition = position;
1723 // Ensures the text-view is covered with text.
1724 TrimScrollPosition();
1726 // Calculate the difference with the previous scroll position
1727 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1728 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1730 if( mOffscreenRootActor )
1732 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1734 mOffscreenRootActor.SetVisible( true );
1737 if( mOffscreenCameraActor )
1739 // Update the offscreen camera with the new scroll position.
1740 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1741 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1746 // Refresh the render-task.
1747 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1751 Toolkit::TextView handle( GetOwner() );
1752 mScrolledSignalV2.Emit( handle, delta );
1755 void TextView::CombineExceedPolicies()
1757 // Calculates the combination of exceed policies.
1759 switch( mLayoutParameters.mWidthExceedPolicy )
1761 case Toolkit::TextView::Original:
1763 switch( mLayoutParameters.mHeightExceedPolicy )
1765 case Toolkit::TextView::Original:
1767 mLayoutParameters.mExceedPolicy = Original;
1770 case Toolkit::TextView::Fade:
1772 mLayoutParameters.mExceedPolicy = OriginalFade;
1775 case Toolkit::TextView::ShrinkToFit:
1777 mLayoutParameters.mExceedPolicy = OriginalShrink;
1782 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1787 case Toolkit::TextView::Split:
1789 switch( mLayoutParameters.mHeightExceedPolicy )
1791 case Toolkit::TextView::Original:
1793 mLayoutParameters.mExceedPolicy = SplitOriginal;
1796 case Toolkit::TextView::Fade:
1798 mLayoutParameters.mExceedPolicy = SplitFade;
1801 case Toolkit::TextView::ShrinkToFit:
1803 mLayoutParameters.mExceedPolicy = SplitShrink;
1806 case Toolkit::TextView::EllipsizeEnd:
1808 mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd;
1813 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1818 case Toolkit::TextView::Fade:
1820 switch( mLayoutParameters.mHeightExceedPolicy )
1822 case Toolkit::TextView::Original:
1824 mLayoutParameters.mExceedPolicy = FadeOriginal;
1827 case Toolkit::TextView::Fade:
1829 mLayoutParameters.mExceedPolicy = Fade;
1834 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1839 case Toolkit::TextView::ShrinkToFit:
1841 switch( mLayoutParameters.mHeightExceedPolicy )
1843 case Toolkit::TextView::Original:
1845 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1848 case Toolkit::TextView::Fade:
1850 mLayoutParameters.mExceedPolicy = ShrinkFade;
1853 case Toolkit::TextView::ShrinkToFit:
1855 mLayoutParameters.mExceedPolicy = Shrink;
1860 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1865 case Toolkit::TextView::EllipsizeEnd:
1867 switch( mLayoutParameters.mHeightExceedPolicy )
1869 case Toolkit::TextView::Original:
1871 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1874 case Toolkit::TextView::EllipsizeEnd:
1876 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1881 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1888 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1893 Actor TextView::GetRootActor() const
1895 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1899 if( mVisualParameters.mSnapshotModeEnabled )
1901 rootActor = mOffscreenRootActor;
1911 void TextView::CreateEllipsizeLayout()
1913 // Creates the ellipsis layout info for the ellipsis text and styles.
1914 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1915 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo.mCharactersLayoutInfo.resize( mRelayoutData.mTextLayoutInfo.mEllipsisText.GetLength(), TextViewProcessor::CharacterLayoutInfo() );
1916 TextViewProcessor::CreateWordTextInfo( mRelayoutData.mTextLayoutInfo.mEllipsisText,
1917 mRelayoutData.mTextLayoutInfo.mEllipsisTextStyles,
1918 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1921 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1923 bool newValue( propertyValue.Get<bool>() );
1924 if( newValue != IsMarkupProcessingEnabled() )
1926 SetMarkupProcessingEnabled( newValue );
1929 // If markup processing has been enabled, Ensure current text is reprocessed.
1930 const std::string& currentText( GetText() );
1931 if( ! currentText.empty() )
1933 SetText( currentText );
1939 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1941 std::string policyName( propertyValue.Get<std::string>() );
1942 if(policyName == "SplitByNewLineChar")
1944 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1946 else if(policyName == "SplitByWord")
1948 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1950 else if(policyName == "SplitByChar")
1952 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1956 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1960 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1962 std::string policyName( propertyValue.Get<std::string>() );
1963 if(policyName == "Original")
1965 SetWidthExceedPolicy(Toolkit::TextView::Original);
1967 else if(policyName == "Fade")
1969 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1971 else if(policyName == "Split")
1973 SetWidthExceedPolicy(Toolkit::TextView::Split);
1975 else if(policyName == "ShrinkToFit")
1977 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1979 else if(policyName == "EllipsizeEnd")
1981 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1985 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1989 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1991 std::string policyName( propertyValue.Get<std::string>() );
1992 if(policyName == "Original")
1994 SetHeightExceedPolicy(Toolkit::TextView::Original);
1996 else if(policyName == "Fade")
1998 SetHeightExceedPolicy(Toolkit::TextView::Fade);
2000 else if(policyName == "Split")
2002 SetHeightExceedPolicy(Toolkit::TextView::Split);
2004 else if(policyName == "ShrinkToFit")
2006 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
2010 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
2014 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
2016 std::string policyName( propertyValue.Get<std::string>() );
2017 if(policyName == "Left")
2019 SetLineJustification(Toolkit::TextView::Left);
2021 else if(policyName == "Center")
2023 SetLineJustification(Toolkit::TextView::Center);
2025 else if(policyName == "Right")
2027 SetLineJustification(Toolkit::TextView::Right);
2029 else if(policyName == "Justified")
2031 SetLineJustification(Toolkit::TextView::Justified);
2035 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2039 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
2041 Vector4 value( propertyValue.Get<Vector4>() );
2042 DALI_ASSERT_ALWAYS( ( value.x >= 0.f ) && ( value.y >= 0.f ) && ( value.z >= 0.f ) && ( value.w >= 0.f )
2043 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2045 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2046 PixelSize( static_cast<unsigned int>( value.y ) ),
2047 PixelSize( static_cast<unsigned int>( value.z ) ),
2048 PixelSize( static_cast<unsigned int>( value.w ) ) );
2050 SetFadeBoundary( fadeBoundary );
2053 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2055 std::string value( propertyValue.Get<std::string>() );
2057 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2059 if(value == "HorizontalLeft")
2061 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2063 else if( value == "HorizontalCenter")
2065 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2067 else if( value == "HorizontalRight")
2069 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2073 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2076 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2078 if( value == "VerticalTop" )
2080 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2082 else if( value == "VerticalCenter")
2084 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2086 else if( value == "VerticalBottom")
2088 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2092 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2098 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2099 if( RELAYOUT_ALL != mRelayoutOperations )
2101 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2102 RELAYOUT_TEXT_ACTOR_UPDATE |
2103 RELAYOUT_ALIGNMENT |
2104 RELAYOUT_VISIBILITY );
2108 std::string TextView::OnHorizontalAlignmentPropertyGet()
2110 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2112 return "HorizontalLeft";
2114 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2116 return "HorizontalCenter";
2118 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2120 return "HorizontalRight";
2124 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2128 std::string TextView::OnVerticalAlignmentPropertyGet()
2130 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2132 return "VerticalTop";
2134 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2136 return "VerticalCenter";
2138 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2140 return "VerticalBottom";
2144 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2148 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2150 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2154 TextView& textViewImpl( GetImpl( textView ) );
2157 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2159 textViewImpl.OnMarkupEnabledPeopertySet( value );
2162 case Toolkit::TextView::PROPERTY_TEXT:
2164 textViewImpl.SetText( value.Get<std::string>() );
2167 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2169 textViewImpl.OnMultilinePolicyPropertySet( value );
2172 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2174 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2177 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2179 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2182 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2184 textViewImpl.OnLineJustificationPropertySet( value );
2187 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2189 textViewImpl.OnFadeBoundaryPropertySet( value );
2192 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2194 Dali::PointSize pointSize( value.Get<float>() );
2195 textViewImpl.SetLineHeightOffset(pointSize);
2198 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2199 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2201 textViewImpl.OnAlignmentPropertySet( index, value );
2208 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2210 Property::Value value;
2212 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2216 TextView& textViewImpl( GetImpl( textView ) );
2219 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2221 value = textViewImpl.IsMarkupProcessingEnabled();
2224 case Toolkit::TextView::PROPERTY_TEXT:
2226 value = textViewImpl.GetText();
2229 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2231 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2234 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2236 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2239 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2241 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2244 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2246 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2249 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2251 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2252 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2253 static_cast<float>( boundary.mRight.value ),
2254 static_cast<float>( boundary.mTop.value ),
2255 static_cast<float>( boundary.mBottom.value ) );
2258 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2260 value = textViewImpl.GetLineHeightOffset().value;
2263 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2265 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2268 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2270 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2278 } // namespace Internal
2280 } // namespace Toolkit