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-view-processor.h>
26 #include <dali-toolkit/internal/controls/text-view/text-view-word-processor.h>
27 #include <dali-toolkit/internal/controls/text-view/relayout-utilities.h>
35 const Property::Index TextView::PROPERTY_MARKUP_ENABLED( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX );
36 const Property::Index TextView::PROPERTY_TEXT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 1 );
37 const Property::Index TextView::PROPERTY_MULTILINE_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 2 );
38 const Property::Index TextView::PROPERTY_WIDTH_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 3 );
39 const Property::Index TextView::PROPERTY_HEIGHT_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 4 );
40 const Property::Index TextView::PROPERTY_LINE_JUSTIFICATION( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 5 );
41 const Property::Index TextView::PROPERTY_FADE_BOUNDARY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 6 );
42 const Property::Index TextView::PROPERTY_LINE_HEIGHT_OFFSET( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 7 );
43 const Property::Index TextView::PROPERTY_HORIZONTAL_ALIGNMENT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 8 );
44 const Property::Index TextView::PROPERTY_VERTICAL_ALIGNMENT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 9 );
52 const char* MULTILINE_POLICY_NAME[] = {"SplitByNewLineChar", "SplitByWord", "SplitByChar"};
53 const char* EXCEED_POLICY_NAME[] = {"Original", "Truncate", "Fade", "Split","ShrinkToFit","EllipsizeEnd"};
54 const char* LINE_JUSTIFICATION_NAME[] = {"Left","Center","Right","Justified"};
56 // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
57 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
62 return Toolkit::TextView::New();
65 TypeRegistration typeRegistration( typeid(Toolkit::TextView), typeid(Toolkit::Control), Create );
67 SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal );
69 PropertyRegistration property1( typeRegistration, "markup-enabled", Toolkit::TextView::PROPERTY_MARKUP_ENABLED, Property::BOOLEAN, &TextView::SetProperty, &TextView::GetProperty );
70 PropertyRegistration property2( typeRegistration, "text", Toolkit::TextView::PROPERTY_TEXT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
71 PropertyRegistration property3( typeRegistration, "multiline-policy", Toolkit::TextView::PROPERTY_MULTILINE_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
72 PropertyRegistration property4( typeRegistration, "width-exceed-policy", Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
73 PropertyRegistration property5( typeRegistration, "height-exceed-policy", Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
74 PropertyRegistration property6( typeRegistration, "line-justification", Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
75 PropertyRegistration property7( typeRegistration, "fade-boundary", Toolkit::TextView::PROPERTY_FADE_BOUNDARY, Property::VECTOR4, &TextView::SetProperty, &TextView::GetProperty );
76 PropertyRegistration property8( typeRegistration, "line-height-offset", Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET, Property::FLOAT, &TextView::SetProperty, &TextView::GetProperty );
77 PropertyRegistration property9( typeRegistration, "horizontal-alignment", Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
78 PropertyRegistration property10( typeRegistration, "vertical-alignment", Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
81 * Whether the text-view-processor operation sets, inserts, replaces, removes text.
83 * @param[in] metadata The text-view-processor operation.
85 * @return \e true if the given text-view-processor operation is modifying the text.
87 bool IsTextViewProcessorRelayoutOperation( const TextView::TextViewProcessorMetadata& metadata )
89 return ( ( metadata.mType == TextView::TextSet ) ||
90 ( metadata.mType == TextView::TextInserted ) ||
91 ( metadata.mType == TextView::TextReplaced ) ||
92 ( metadata.mType == TextView::TextRemoved ) ||
93 ( metadata.mType == TextView::NewStyle ));
97 * Whether the text-view-processor operation sets a new line height offset.
99 * @param[in] metadata The text-view-processor operation.
101 * @return \e true if the given text-view-processor operation sets a new line height offset.
103 bool IsTextViewProcessorLineHeightOffsetOperation( const TextView::TextViewProcessorMetadata& metadata )
105 return ( metadata.mType == TextView::NewLineHeight );
109 * Whether the text-view-processor operation sets a new style.
111 * @param[in] metadata The text-view-processor operation.
113 * @return \e true if the given text-view-processor operation sets a new style.
115 bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMetadata& metadata )
117 return ( metadata.mType == TextView::NewStyle );
122 TextView::TextViewProcessorMetadata::TextViewProcessorMetadata()
123 : mType( TextView::TextSet ),
125 mNumberOfCharacters( 0u ),
130 Toolkit::TextView TextView::New()
132 // Create the implementation, temporarily owned on stack
133 IntrusivePtr<TextView> textView = new TextView();
135 // Pass ownership to CustomActor
136 Toolkit::TextView handle( *textView );
138 // Second-phase init of the implementation
139 // This can only be done after the CustomActor connection has been made...
140 textView->Initialize();
142 // Disables by default the offscreen rendering.
143 textView->SetSnapshotModeEnabled( false );
148 void TextView::SetText( const std::string& text )
150 // Creates a styled text with the markup or plain string.
151 MarkupProcessor::StyledTextArray styledText;
152 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
154 // Calls SetText() with the styled text array.
155 SetText( styledText );
158 void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
160 // mTextViewProcessorOperations stores the InsertTextAt and RemoveTextFrom operations to transform the initial text to mCurrentStyledText.
161 // Once again, if a new text is set, any previous call to InsertTextAt or RemoveTextFrom can be discarted.
163 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorRelayoutOperation );
164 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
166 // Creates metadata with the Set operation.
167 TextViewProcessorMetadata metadata;
168 metadata.mType = TextView::TextSet;
169 metadata.mText = text;
172 mTextViewProcessorOperations.push_back( metadata );
174 // Updates current styled text.
175 mCurrentStyledText = text;
177 // Request to be relaid out
180 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
181 mRelayoutOperations = RELAYOUT_ALL;
184 void TextView::InsertTextAt( std::size_t position, const std::string& text )
186 // Creates a styled text with the markup or plain string.
187 MarkupProcessor::StyledTextArray styledText;
188 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
190 // Calls InsertTextAt() with the styled text array.
191 InsertTextAt( position, styledText );
194 void TextView::InsertTextAt( std::size_t position, const MarkupProcessor::StyledTextArray& text )
196 // Creates metadata with the Insert operation.
197 TextViewProcessorMetadata metadata;
198 metadata.mType = TextView::TextInserted;
199 metadata.mPosition = position;
200 metadata.mText = text;
203 mTextViewProcessorOperations.push_back( metadata );
205 // Updates current styled text.
206 mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
208 // Request to be relaid out
211 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
212 mRelayoutOperations = RELAYOUT_ALL;
215 void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const std::string& text )
217 // Creates a styled text with the markup or plain string.
218 MarkupProcessor::StyledTextArray styledText;
219 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
221 // Calls ReplaceTextFromTo() with the styled text array.
222 ReplaceTextFromTo( position, numberOfCharacters, styledText );
225 void TextView::ReplaceTextFromTo( std::size_t position, std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
227 // Creates metadata with the Insert operation.
228 TextViewProcessorMetadata metadata;
229 metadata.mType = TextView::TextReplaced;
230 metadata.mPosition = position;
231 metadata.mNumberOfCharacters = numberOfCharacters;
232 metadata.mText = text;
235 mTextViewProcessorOperations.push_back( metadata );
237 // Updates current styled text.
238 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
239 mCurrentStyledText.erase( it, it + numberOfCharacters );
240 it = mCurrentStyledText.begin() + position;
241 mCurrentStyledText.insert( it, text.begin(), text.end() );
243 // Request to be relaid out
246 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
247 mRelayoutOperations = RELAYOUT_ALL;
250 void TextView::RemoveTextFrom( std::size_t position, std::size_t numberOfCharacters )
252 // Creates metadata with the Remove operation.
253 TextViewProcessorMetadata metadata;
254 metadata.mType = TextView::TextRemoved;
255 metadata.mPosition = position;
256 metadata.mNumberOfCharacters = numberOfCharacters;
259 mTextViewProcessorOperations.push_back( metadata );
261 // Updates current styled text.
262 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
263 mCurrentStyledText.erase( it, it + numberOfCharacters );
265 // Request to be relaid out
268 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
269 mRelayoutOperations = RELAYOUT_ALL;
272 std::string TextView::GetText() const
274 // Traverses the styled text array getting only the text.
275 // Note that for some languages a 'character' could be represented by more than one 'char'
278 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); it != endIt; ++it )
280 text.append( (*it).mText.GetText() );
286 void TextView::SetLineHeightOffset( PointSize offset )
288 if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 )
290 // Removes any previous operation which modifies the line height offset.
291 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorLineHeightOffsetOperation );
292 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
294 // Creates metadata with the new line height operation.
295 TextViewProcessorMetadata metadata;
296 metadata.mType = TextView::NewLineHeight;
298 mTextViewProcessorOperations.push_back( metadata );
300 // Updates line height offset.
301 mLayoutParameters.mLineHeightOffset = offset;
305 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
306 if( RELAYOUT_ALL != mRelayoutOperations )
308 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
309 RELAYOUT_REMOVE_TEXT_ACTORS |
310 RELAYOUT_SIZE_POSITION |
312 RELAYOUT_VISIBILITY |
313 RELAYOUT_TEXT_ACTOR_UPDATE |
314 RELAYOUT_INSERT_TO_TEXT_VIEW );
319 PointSize TextView::GetLineHeightOffset() const
321 return PointSize( mLayoutParameters.mLineHeightOffset );
324 void TextView::SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask )
326 if( !mCurrentStyledText.empty() )
328 const bool checkFontName = mask & TextStyle::FONT;
329 const bool checkFontSize = mask & TextStyle::SIZE;
330 const bool checkFontStyle = mask & TextStyle::STYLE;
332 // Check first if metrics have changed.
333 bool metricsChanged = false;
334 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
336 const MarkupProcessor::StyledText& styledText( *it );
338 metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
339 ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
340 ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
345 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
347 // If metrics change, new text measurements are needed.
348 SetText( mCurrentStyledText );
352 // Deletes any previous operation which sets a new style.
353 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
354 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
356 // Creates metadata with the new style operation.
357 TextViewProcessorMetadata metadata;
358 metadata.mType = TextView::NewStyle;
360 MarkupProcessor::StyledText text;
362 metadata.mText.push_back( text );
363 metadata.mStyleMask = mask;
365 mTextViewProcessorOperations.push_back( metadata );
367 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
371 if( RELAYOUT_ALL != mRelayoutOperations )
373 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
374 RELAYOUT_TEXT_ACTOR_UPDATE );
379 // Sets the new style to the ellipsize text
380 if( !mLayoutParameters.mEllipsizeText.empty() )
382 for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
384 (*it).mStyle.Copy( style, mask );
387 SetEllipsizeText( mLayoutParameters.mEllipsizeText );
391 void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
393 if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
395 Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
396 ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
397 ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
398 Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
399 ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
400 ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
402 mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
403 mLayoutParameters.mVerticalAlignment = verticalAlignment;
407 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
408 if( RELAYOUT_ALL != mRelayoutOperations )
410 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
411 RELAYOUT_TEXT_ACTOR_UPDATE |
413 RELAYOUT_VISIBILITY );
418 Toolkit::Alignment::Type TextView::GetTextAlignment() const
420 return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
423 void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
425 if( policy != mLayoutParameters.mMultilinePolicy )
427 mLayoutParameters.mMultilinePolicy = policy;
429 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
430 mRelayoutOperations = RELAYOUT_ALL;
436 Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
438 return mLayoutParameters.mMultilinePolicy;
441 void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
443 // The layout info could be invalid depending on the current exceed policy and the new one.
444 // i.e. if the current policy is Split and the new one is ShrinkToFit then
445 // the layout info generated for each char is not needed.
446 if( policy != mLayoutParameters.mWidthExceedPolicy )
448 mLayoutParameters.mWidthExceedPolicy = policy;
450 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
451 mRelayoutOperations = RELAYOUT_ALL;
457 Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
459 return mLayoutParameters.mWidthExceedPolicy;
462 void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
464 if( policy != mLayoutParameters.mHeightExceedPolicy )
466 mLayoutParameters.mHeightExceedPolicy = policy;
470 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
471 if( RELAYOUT_ALL != mRelayoutOperations )
473 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
474 RELAYOUT_REMOVE_TEXT_ACTORS |
475 RELAYOUT_SIZE_POSITION |
477 RELAYOUT_VISIBILITY |
478 RELAYOUT_TEXT_ACTOR_UPDATE |
479 RELAYOUT_INSERT_TO_TEXT_VIEW );
484 Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
486 return mLayoutParameters.mHeightExceedPolicy;
489 void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
491 if( justification != mLayoutParameters.mLineJustification )
493 mLayoutParameters.mLineJustification = justification;
497 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
498 if( RELAYOUT_ALL != mRelayoutOperations )
500 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
501 RELAYOUT_REMOVE_TEXT_ACTORS |
502 RELAYOUT_SIZE_POSITION |
504 RELAYOUT_VISIBILITY |
505 RELAYOUT_TEXT_ACTOR_UPDATE |
506 RELAYOUT_INSERT_TO_TEXT_VIEW );
511 Toolkit::TextView::LineJustification TextView::GetLineJustification() const
513 return mLayoutParameters.mLineJustification;
516 void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
518 if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
519 ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
520 ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
521 ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
523 mVisualParameters.mFadeBoundary = fadeBoundary;
527 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
528 if( RELAYOUT_ALL != mRelayoutOperations )
530 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
531 RELAYOUT_REMOVE_TEXT_ACTORS |
532 RELAYOUT_VISIBILITY |
533 RELAYOUT_TEXT_ACTOR_UPDATE |
534 RELAYOUT_INSERT_TO_TEXT_VIEW );
539 const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
541 return mVisualParameters.mFadeBoundary;
544 void TextView::SetEllipsizeText( const std::string& ellipsizeText )
546 // Creates a styled text with the markup or plain string.
547 MarkupProcessor::StyledTextArray styledText;
548 MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() );
550 SetEllipsizeText( styledText );
553 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
555 mLayoutParameters.mEllipsizeText = ellipsizeText;
557 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
559 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
560 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
562 // Request to be relaid out
565 mRelayoutOperations = RELAYOUT_ALL;
568 std::string TextView::GetEllipsizeText() const
571 for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
573 text.append( (*it).mText.GetText() );
579 void TextView::GetTextLayoutInfo()
581 const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
582 const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
583 const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
585 if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
587 Vector3 textViewSize = GetControlSize();
589 if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
590 ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
591 ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
592 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
593 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
595 // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
596 // the text natural size can be used.
597 textViewSize = GetNaturalSize();
600 if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
601 ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
603 // Check if the text-view has glyph-actors.
604 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
606 RelayoutOperationMask mask = NO_RELAYOUT;
607 if( relayoutSizeAndPositionNeeded )
609 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
611 if( relayoutAlignmentNeeded )
613 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
615 if( relayoutVisibilityNeeded )
617 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
622 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
623 // add them to the text-actor cache.
624 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
625 mRelayoutData.mGlyphActors.clear();
628 // Relays-out but doesn't add glyph-actors to the text-view.
629 DoRelayOut( textViewSize.GetVectorXY(), mask );
633 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
640 void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
644 textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
645 textLayoutInfo.mLines = mRelayoutData.mLines;
647 textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
648 textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
650 textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
652 textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
655 void TextView::SetSortModifier( float depthOffset )
657 mVisualParameters.mSortModifier = depthOffset;
659 for( std::vector<RenderableActor>::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.end();
663 ( *it ).SetSortModifier( depthOffset );
666 if( mOffscreenImageActor )
668 mOffscreenImageActor.SetSortModifier( depthOffset );
672 void TextView::SetSnapshotModeEnabled( bool enable )
674 if( enable != mVisualParameters.mSnapshotModeEnabled )
676 // Remove first all glyph-actors
677 if( !mRelayoutData.mGlyphActors.empty() )
679 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
682 mVisualParameters.mSnapshotModeEnabled = enable;
683 if( !mLockPreviousSnapshotMode )
685 // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
686 // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
688 // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
689 // to smash the stored value.
690 mPreviousSnapshotModeEnabled = enable;
693 if( mVisualParameters.mSnapshotModeEnabled )
695 // Create a root actor and an image actor for offscreen rendering.
696 mOffscreenRootActor = Layer::New();
697 mOffscreenImageActor = ImageActor::New();
699 mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
700 mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
701 mOffscreenRootActor.SetInheritRotation( false );
702 mOffscreenRootActor.SetInheritScale( false );
703 mOffscreenRootActor.SetDepthTestDisabled( true );
705 mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
707 mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
708 mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
709 mOffscreenImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
710 BlendingFactor::ONE, BlendingFactor::ONE );
713 self.Add( mOffscreenRootActor );
714 self.Add( mOffscreenImageActor );
715 mOffscreenImageActor.SetScale( Vector3( 1.f, -1.f, 1.f ) );
721 if( mOffscreenRootActor )
723 self.Remove( mOffscreenRootActor );
726 if( mOffscreenImageActor )
728 self.Remove( mOffscreenImageActor );
731 DestroyOffscreenRenderingResources();
734 if( RELAYOUT_ALL != mRelayoutOperations )
736 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
737 RELAYOUT_REMOVE_TEXT_ACTORS |
738 RELAYOUT_TEXT_ACTOR_UPDATE |
739 RELAYOUT_INSERT_TO_TEXT_VIEW );
745 bool TextView::IsSnapshotModeEnabled() const
747 return mVisualParameters.mSnapshotModeEnabled;
750 void TextView::SetMarkupProcessingEnabled( bool enable )
752 mMarkUpEnabled = enable;
755 bool TextView::IsMarkupProcessingEnabled() const
757 return mMarkUpEnabled;
760 void TextView::SetScrollEnabled( bool enable )
762 if( enable != mVisualParameters.mScrollEnabled )
764 mVisualParameters.mScrollEnabled = enable;
766 if( mVisualParameters.mScrollEnabled )
768 // Offscreen rendering is needed to enable text scroll.
770 // Stores previous value of the snapshot mode.
771 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
774 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
775 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
776 Lock lock( mLockPreviousSnapshotMode );
777 SetSnapshotModeEnabled( true );
780 // Creates the pan gesture detector and attach the text-view.
781 mPanGestureDetector = PanGestureDetector::New();
782 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
783 mPanGestureDetector.Attach( Self() );
787 // Removes the pan gesture detector.
788 if( mPanGestureDetector )
790 mPanGestureDetector.Detach( Self() );
791 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
792 mPanGestureDetector.Reset();
795 // Restores the previous state for snapshot mode.
796 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
801 bool TextView::IsScrollEnabled() const
803 return mVisualParameters.mScrollEnabled;
806 void TextView::SetScrollPosition( const Vector2& position )
808 if( position != mVisualParameters.mCameraScrollPosition )
810 // Guard against destruction during signal emission
811 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
812 Toolkit::TextView handle( GetOwner() );
814 DoSetScrollPosition( position );
816 // Check if the new scroll position has been trimmed.
817 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
821 const Vector2& TextView::GetScrollPosition() const
823 return mVisualParameters.mCameraScrollPosition;
826 bool TextView::IsScrollPositionTrimmed() const
828 return mVisualParameters.mScrollPositionTrimmed;
831 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
833 return mScrolledSignalV2;
836 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
838 Dali::BaseHandle handle( object );
840 bool connected( true );
841 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
843 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
845 textView.ScrolledSignal().Connect( tracker, functor );
849 // signalName does not match any signal
856 TextView::LayoutParameters::LayoutParameters()
857 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
858 mWidthExceedPolicy( Toolkit::TextView::Original ),
859 mHeightExceedPolicy( Toolkit::TextView::Original ),
860 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
861 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
862 mLineJustification( Toolkit::TextView::Left ),
863 mLineHeightOffset( 0.f ),
865 mMarkUpEnabled( false )
867 // Sets ellipsize text
868 MarkupProcessor::StyledTextArray styledEllipsize;
869 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
872 TextView::LayoutParameters::~LayoutParameters()
876 TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy,
877 Toolkit::TextView::ExceedPolicy widthExceedPolicy,
878 Toolkit::TextView::ExceedPolicy heightExceedPolicy,
879 Toolkit::Alignment::Type alignmentType,
880 Toolkit::TextView::LineJustification lineJustification,
881 float lineHeightOffset,
882 const std::string& ellipsizeText,
884 : mMultilinePolicy( multilinePolicy ),
885 mWidthExceedPolicy( widthExceedPolicy ),
886 mHeightExceedPolicy( heightExceedPolicy ),
887 mHorizontalAlignment(),
888 mVerticalAlignment(),
889 mLineJustification( lineJustification ),
890 mLineHeightOffset( lineHeightOffset ),
892 mMarkUpEnabled( markUpEnabled )
895 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
896 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
897 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
898 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
899 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
900 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
902 mHorizontalAlignment = horizontalAlignment;
903 mVerticalAlignment = verticalAlignment;
905 // Sets ellipsize text
906 MarkupProcessor::StyledTextArray styledEllipsize;
907 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
910 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
911 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
912 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
913 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
914 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
915 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
916 mLineJustification( layoutParameters.mLineJustification ),
917 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
918 mEllipsizeText( layoutParameters.mEllipsizeText ),
919 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
923 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
925 mMultilinePolicy = layoutParameters.mMultilinePolicy;
926 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
927 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
928 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
929 mVerticalAlignment = layoutParameters.mVerticalAlignment;
930 mLineJustification = layoutParameters.mLineJustification;
931 mLineHeightOffset = layoutParameters.mLineHeightOffset;
932 mEllipsizeText = layoutParameters.mEllipsizeText;
933 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
938 TextView::VisualParameters::VisualParameters()
940 mSortModifier( 0.f ),
941 mCameraScrollPosition( 0.f, 0.f ),
942 mSnapshotModeEnabled( false ),
943 mScrollEnabled( false ),
944 mScrollPositionTrimmed( false )
948 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
949 : mFadeBoundary( visualParameters.mFadeBoundary ),
950 mSortModifier( visualParameters.mSortModifier ),
951 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
952 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
953 mScrollEnabled( visualParameters.mScrollEnabled ),
954 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
958 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
960 mFadeBoundary = visualParameters.mFadeBoundary;
961 mSortModifier = visualParameters.mSortModifier;
962 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
963 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
964 mScrollEnabled = visualParameters.mScrollEnabled;
965 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
970 TextView::RelayoutData::RelayoutData()
972 mShrinkFactor( 1.f ),
974 mCharacterLogicalToVisualMap(),
975 mCharacterVisualToLogicalMap(),
977 mCharacterLayoutInfoTable(),
979 mTextSizeForRelayoutOption()
983 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
984 : mTextViewSize( relayoutData.mTextViewSize ),
985 mShrinkFactor( relayoutData.mShrinkFactor ),
986 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
987 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
988 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
989 mGlyphActors( relayoutData.mGlyphActors ),
990 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
991 mLines( relayoutData.mLines ),
992 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
996 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
998 mTextViewSize = relayoutData.mTextViewSize;
999 mShrinkFactor = relayoutData.mShrinkFactor;
1000 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
1001 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
1002 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
1003 mGlyphActors = relayoutData.mGlyphActors;
1004 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1005 mLines = relayoutData.mLines;
1006 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1011 TextView::TextView()
1012 : Control( REQUIRES_STYLE_CHANGE_SIGNALS ),
1013 mCurrentStyledText(),
1014 mTextViewProcessorOperations(),
1015 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1016 Toolkit::TextView::Original,
1017 Toolkit::TextView::Original,
1018 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1019 Toolkit::TextView::Left,
1021 std::string( "..." ),
1023 mVisualParameters(),
1025 mRelayoutOperations( NO_RELAYOUT ),
1026 mOffscreenRootActor(),
1027 mOffscreenImageActor(),
1028 mOffscreenCameraActor(),
1029 mCurrentOffscreenSize(),
1030 mFrameBufferImage(),
1032 mPanGestureDetector(),
1033 mLockPreviousSnapshotMode( false ),
1034 mPreviousSnapshotModeEnabled( false ),
1035 mMarkUpEnabled( false )
1037 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1038 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1041 TextView::~TextView()
1043 // Destroys offscreen rendering resources.
1044 DestroyOffscreenRenderingResources();
1046 // Destroys scroll pan gesture detector.
1047 if( mPanGestureDetector )
1049 mPanGestureDetector.Reset();
1053 Vector3 TextView::GetNaturalSize()
1055 if( !mTextViewProcessorOperations.empty() )
1057 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1059 if( !mRelayoutData.mGlyphActors.empty() )
1061 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1062 // add them to the text-actor cache.
1063 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1064 mRelayoutData.mGlyphActors.clear();
1066 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1069 PerformTextViewProcessorOperations();
1072 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1075 float TextView::GetHeightForWidth( float width )
1079 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1080 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1081 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1083 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1084 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1085 height = GetNaturalSize().height;
1089 // Check if the given width is different than the current one.
1090 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1092 // Check if the text-view has glyph-actors.
1093 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1095 // Check which layout operations need to be done.
1096 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1098 if( relayoutSizeAndPositionNeeded )
1100 if( hasGlyphActors )
1102 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1103 // add them to the text-actor cache.
1104 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1105 mRelayoutData.mGlyphActors.clear();
1108 // Use the given width.
1109 const Vector2 textViewSize( width, GetControlSize().height );
1111 // Relays-out but doesn't add glyph-actors to the text-view.
1112 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1115 // Retrieve the text height after relayout the text.
1116 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1118 if( differentWidth )
1120 // Revert the relayout operation mask
1121 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1124 if( hasGlyphActors )
1126 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1129 if( differentWidth || hasGlyphActors )
1138 float TextView::GetWidthForHeight( float height )
1140 // TODO: Needs implementing properly, for now just return the natural width.
1141 return GetNaturalSize().width;
1145 void TextView::OnInitialize()
1150 void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
1152 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1153 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1154 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1156 SetText( mCurrentStyledText );
1159 void TextView::OnControlSizeSet( const Vector3& size )
1161 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1163 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1164 mRelayoutOperations = RELAYOUT_ALL;
1166 // Request to be relaid out
1171 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1173 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1175 // Not worth to relayout if width or height is equal to zero.
1179 if( size != mRelayoutData.mTextViewSize )
1181 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1182 if( RELAYOUT_ALL != mRelayoutOperations )
1184 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1185 RELAYOUT_REMOVE_TEXT_ACTORS |
1186 RELAYOUT_SIZE_POSITION |
1187 RELAYOUT_ALIGNMENT |
1188 RELAYOUT_VISIBILITY |
1189 RELAYOUT_TEXT_ACTOR_UPDATE |
1190 RELAYOUT_INSERT_TO_TEXT_VIEW );
1194 // Remove glyph-actors from text-view
1195 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1197 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1198 mRelayoutData.mGlyphActors.clear();
1201 if( NO_RELAYOUT != mRelayoutOperations )
1203 // Relays-out and add glyph-actors to the text-view.
1204 DoRelayOut( size, mRelayoutOperations );
1205 ProcessSnapshot( size );
1208 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1209 mRelayoutData.mTextActorCache.ClearTexts();
1212 void TextView::PerformTextViewProcessorOperations()
1214 // Traverse the relayout operation vector ...
1216 // Optimizes some operations.
1217 OptimizeTextViewProcessorOperations();
1219 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1221 const TextViewProcessorMetadata& relayoutMetadata( *it );
1223 switch( relayoutMetadata.mType )
1225 case TextView::TextSet:
1227 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1232 case TextView::TextInserted:
1234 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1235 relayoutMetadata.mText,
1240 case TextView::TextReplaced:
1242 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1243 relayoutMetadata.mNumberOfCharacters,
1244 relayoutMetadata.mText,
1249 case TextView::TextRemoved:
1251 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1252 relayoutMetadata.mNumberOfCharacters,
1255 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1258 case TextView::NewLineHeight:
1260 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1261 mRelayoutData.mTextLayoutInfo );
1264 case TextView::NewStyle:
1266 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1267 relayoutMetadata.mStyleMask,
1274 // Clear all operations when they are done.
1275 mTextViewProcessorOperations.clear();
1278 void TextView::OptimizeTextViewProcessorOperations()
1280 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1282 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1283 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1284 // use the cache without clearing the text-actors.
1286 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1288 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1290 const TextViewProcessorMetadata& relayoutMetadata( *it );
1292 switch( relayoutMetadata.mType )
1294 case TextView::TextRemoved:
1296 bool optimizationDone = false;
1298 if( it + 1u != endIt )
1300 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1u ) );
1301 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1303 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1305 optimizationDone = true;
1306 TextViewProcessorMetadata newRelayoutMetadata;
1307 newRelayoutMetadata.mType = TextView::TextReplaced;
1308 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1309 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1310 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1311 textViewProcessorOperations.push_back( newRelayoutMetadata );
1313 // do not access the TextInserted operation in next iteration.
1319 if( !optimizationDone )
1321 textViewProcessorOperations.push_back( relayoutMetadata );
1327 textViewProcessorOperations.push_back( relayoutMetadata );
1332 mTextViewProcessorOperations = textViewProcessorOperations;
1335 void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask )
1337 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1338 if( !mTextViewProcessorOperations.empty() )
1340 PerformTextViewProcessorOperations();
1343 CombineExceedPolicies();
1346 if( mVisualParameters.mSnapshotModeEnabled )
1348 rootActor = mOffscreenRootActor;
1355 mRelayoutData.mTextViewSize = textViewSize;
1356 switch( mLayoutParameters.mMultilinePolicy )
1358 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1360 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1362 } // SplitByNewLineChar
1364 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1366 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1370 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1372 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1375 } // switch( mMultilinePolicy )
1377 // Remove done operations from the mask.
1378 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1381 void TextView::ProcessSnapshot( const Size& textViewSize )
1383 if( mVisualParameters.mSnapshotModeEnabled )
1385 // If layout options change, it's needed generate a new image.
1387 if( mOffscreenRootActor )
1389 // Set the root actor visible.
1390 // The root actor is set to non visible after the render task is processed.
1391 mOffscreenRootActor.SetVisible( true );
1393 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1394 mOffscreenRootActor.SetSize( textViewSize );
1397 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1398 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1400 // Set the image actor visible.
1401 // The image actor is set to non visible if there is no text to render.
1402 mOffscreenImageActor.SetVisible( true );
1404 // Calculates the offscreen image's size. It takes into account different points:
1405 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1406 // * There is a maximum texture size the graphic subsystem can load on the memory.
1407 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1409 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1410 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1411 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1412 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1414 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1418 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1419 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1420 offscreenSize.height,
1423 // Stores current text-view size to avoid create new Dali resources if text changes.
1424 mCurrentOffscreenSize = offscreenSize;
1426 if( !mOffscreenCameraActor )
1428 // Creates a new camera actor.
1429 mOffscreenCameraActor = CameraActor::New();
1430 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1431 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1432 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1434 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1436 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1439 // Calculate camera parameters for current text size.
1440 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1443 if( mVisualParameters.mScrollEnabled )
1445 // Updates the offscreen camera position with the new scroll offset.
1446 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1447 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1451 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1452 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1457 // Creates a new render task.
1458 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1460 mRenderTask.SetSourceActor( mOffscreenRootActor );
1461 mRenderTask.SetInputEnabled( false );
1462 mRenderTask.SetClearColor( Color::TRANSPARENT );
1463 mRenderTask.SetClearEnabled( true );
1464 mRenderTask.SetExclusive( true );
1466 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1467 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1472 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1473 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1476 // Process the render task only once every time the text changes or the text-view's size canges.
1477 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1481 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1482 mOffscreenImageActor.SetVisible( false );
1487 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1489 float xPosition = 0.f;
1490 float yPosition = 0.f;
1491 Vector3 parentOrigin = ParentOrigin::CENTER;
1492 Vector3 anchorPoint = AnchorPoint::CENTER;
1494 switch( mLayoutParameters.mHorizontalAlignment )
1496 case Toolkit::Alignment::HorizontalLeft:
1498 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1499 parentOrigin.x = 0.f;
1500 anchorPoint.x = 0.f;
1503 case Toolkit::Alignment::HorizontalCenter:
1508 case Toolkit::Alignment::HorizontalRight:
1510 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1511 parentOrigin.x = 1.f;
1512 anchorPoint.x = 1.f;
1517 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1521 switch( mLayoutParameters.mVerticalAlignment )
1523 case Toolkit::Alignment::VerticalTop:
1525 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1526 parentOrigin.y = 0.f;
1527 anchorPoint.y = 0.f;
1530 case Toolkit::Alignment::VerticalCenter:
1535 case Toolkit::Alignment::VerticalBottom:
1537 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1538 parentOrigin.y = 1.f;
1539 anchorPoint.y = 1.f;
1544 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1548 mOffscreenCameraActor.SetX( xPosition );
1549 mOffscreenCameraActor.SetY( yPosition );
1551 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1552 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1555 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1557 // not to process the offscreen root actor by setting its visibility to false.
1558 mOffscreenRootActor.SetVisible( false );
1560 // Sets the new size and the new frame buffer to the image actor.
1561 // Image actor must have same size as text. Otherwise text can be truncated.
1562 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1563 mOffscreenImageActor.SetImage( mFrameBufferImage );
1566 void TextView::DestroyOffscreenRenderingResources()
1570 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1572 if( Stage::IsInstalled() )
1574 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1577 mRenderTask.Reset();
1580 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1581 if( mOffscreenCameraActor )
1583 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1585 mOffscreenCameraActor.Reset();
1588 if( mOffscreenRootActor )
1590 mOffscreenRootActor.Reset();
1593 if( mOffscreenImageActor )
1595 mOffscreenImageActor.Reset();
1598 mCurrentOffscreenSize = Size( 0.f, 0.f );
1600 if( mFrameBufferImage )
1602 mFrameBufferImage.Reset();
1606 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1608 if( 1u == gesture.numberOfTouches )
1610 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1614 void TextView::TrimScrollPosition()
1616 const Vector3& textViewSize = GetControlSize();
1618 // Before use the text's size, relayout the text is needed to get the actual text size.
1619 GetTextLayoutInfo();
1621 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1622 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1623 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1624 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1625 float minVerticalDisplacement = -maxVerticalDisplacement;
1627 // Updates the range if the text is aligned on the right or left.
1628 switch( mLayoutParameters.mHorizontalAlignment )
1630 case Toolkit::Alignment::HorizontalLeft:
1632 maxHorizontalDisplacement *= 2.f;
1633 minHorizontalDisplacement = 0.f;
1636 case Toolkit::Alignment::HorizontalCenter:
1641 case Toolkit::Alignment::HorizontalRight:
1643 maxHorizontalDisplacement = 0.f;
1644 minHorizontalDisplacement *= 2.f;
1649 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1653 // Updates the range if the text is aligned on the top or bottom.
1654 switch( mLayoutParameters.mVerticalAlignment )
1656 case Toolkit::Alignment::VerticalTop:
1658 maxVerticalDisplacement *= 2.f;
1659 minVerticalDisplacement = 0.f;
1662 case Toolkit::Alignment::VerticalCenter:
1667 case Toolkit::Alignment::VerticalBottom:
1669 maxVerticalDisplacement = 0.f;
1670 minVerticalDisplacement *= 2.f;
1675 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1679 // Trims the scroll position to be within the range.
1680 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1681 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1683 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1684 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1687 void TextView::DoSetScrollPosition( const Vector2& position )
1689 // Stores old scroll position.
1690 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1692 // Updates the scroll position
1693 mVisualParameters.mCameraScrollPosition = position;
1695 // Ensures the text-view is covered with text.
1696 TrimScrollPosition();
1698 // Calculate the difference with the previous scroll position
1699 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1700 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1702 if( mOffscreenRootActor )
1704 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1706 mOffscreenRootActor.SetVisible( true );
1709 if( mOffscreenCameraActor )
1711 // Update the offscreen camera with the new scroll position.
1712 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1713 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1718 // Refresh the render-task.
1719 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1723 Toolkit::TextView handle( GetOwner() );
1724 mScrolledSignalV2.Emit( handle, delta );
1727 void TextView::CombineExceedPolicies()
1729 // Calculates the combination of exceed policies.
1731 switch( mLayoutParameters.mWidthExceedPolicy )
1733 case Toolkit::TextView::Original:
1735 switch( mLayoutParameters.mHeightExceedPolicy )
1737 case Toolkit::TextView::Original:
1739 mLayoutParameters.mExceedPolicy = Original;
1742 case Toolkit::TextView::Fade:
1744 mLayoutParameters.mExceedPolicy = OriginalFade;
1747 case Toolkit::TextView::ShrinkToFit:
1749 mLayoutParameters.mExceedPolicy = OriginalShrink;
1754 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1759 case Toolkit::TextView::Split:
1761 switch( mLayoutParameters.mHeightExceedPolicy )
1763 case Toolkit::TextView::Original:
1765 mLayoutParameters.mExceedPolicy = SplitOriginal;
1768 case Toolkit::TextView::Fade:
1770 mLayoutParameters.mExceedPolicy = SplitFade;
1773 case Toolkit::TextView::ShrinkToFit:
1775 mLayoutParameters.mExceedPolicy = SplitShrink;
1778 case Toolkit::TextView::EllipsizeEnd:
1780 mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd;
1785 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1790 case Toolkit::TextView::Fade:
1792 switch( mLayoutParameters.mHeightExceedPolicy )
1794 case Toolkit::TextView::Original:
1796 mLayoutParameters.mExceedPolicy = FadeOriginal;
1799 case Toolkit::TextView::Fade:
1801 mLayoutParameters.mExceedPolicy = Fade;
1806 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1811 case Toolkit::TextView::ShrinkToFit:
1813 switch( mLayoutParameters.mHeightExceedPolicy )
1815 case Toolkit::TextView::Original:
1817 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1820 case Toolkit::TextView::Fade:
1822 mLayoutParameters.mExceedPolicy = ShrinkFade;
1825 case Toolkit::TextView::ShrinkToFit:
1827 mLayoutParameters.mExceedPolicy = Shrink;
1832 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1837 case Toolkit::TextView::EllipsizeEnd:
1839 switch( mLayoutParameters.mHeightExceedPolicy )
1841 case Toolkit::TextView::Original:
1843 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1846 case Toolkit::TextView::EllipsizeEnd:
1848 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1853 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1860 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1865 Actor TextView::GetRootActor() const
1867 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1871 if( mVisualParameters.mSnapshotModeEnabled )
1873 rootActor = mOffscreenRootActor;
1883 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1885 bool newValue( propertyValue.Get<bool>() );
1886 if( newValue != IsMarkupProcessingEnabled() )
1888 SetMarkupProcessingEnabled( newValue );
1891 // If markup processing has been enabled, Ensure current text is reprocessed.
1892 const std::string& currentText( GetText() );
1893 if( ! currentText.empty() )
1895 SetText( currentText );
1901 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1903 std::string policyName( propertyValue.Get<std::string>() );
1904 if(policyName == "SplitByNewLineChar")
1906 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1908 else if(policyName == "SplitByWord")
1910 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1912 else if(policyName == "SplitByChar")
1914 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1918 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1922 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1924 std::string policyName( propertyValue.Get<std::string>() );
1925 if(policyName == "Original")
1927 SetWidthExceedPolicy(Toolkit::TextView::Original);
1929 else if(policyName == "Fade")
1931 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1933 else if(policyName == "Split")
1935 SetWidthExceedPolicy(Toolkit::TextView::Split);
1937 else if(policyName == "ShrinkToFit")
1939 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1941 else if(policyName == "EllipsizeEnd")
1943 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1947 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1951 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1953 std::string policyName( propertyValue.Get<std::string>() );
1954 if(policyName == "Original")
1956 SetHeightExceedPolicy(Toolkit::TextView::Original);
1958 else if(policyName == "Fade")
1960 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1962 else if(policyName == "Split")
1964 SetHeightExceedPolicy(Toolkit::TextView::Split);
1966 else if(policyName == "ShrinkToFit")
1968 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1972 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1976 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1978 std::string policyName( propertyValue.Get<std::string>() );
1979 if(policyName == "Left")
1981 SetLineJustification(Toolkit::TextView::Left);
1983 else if(policyName == "Center")
1985 SetLineJustification(Toolkit::TextView::Center);
1987 else if(policyName == "Right")
1989 SetLineJustification(Toolkit::TextView::Right);
1991 else if(policyName == "Justified")
1993 SetLineJustification(Toolkit::TextView::Justified);
1997 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2001 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
2003 Vector4 value( propertyValue.Get<Vector4>() );
2004 DALI_ASSERT_ALWAYS( ( value.x >= 0.f ) && ( value.y >= 0.f ) && ( value.z >= 0.f ) && ( value.w >= 0.f )
2005 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2007 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2008 PixelSize( static_cast<unsigned int>( value.y ) ),
2009 PixelSize( static_cast<unsigned int>( value.z ) ),
2010 PixelSize( static_cast<unsigned int>( value.w ) ) );
2012 SetFadeBoundary( fadeBoundary );
2015 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2017 std::string value( propertyValue.Get<std::string>() );
2019 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2021 if(value == "HorizontalLeft")
2023 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2025 else if( value == "HorizontalCenter")
2027 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2029 else if( value == "HorizontalRight")
2031 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2035 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2038 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2040 if( value == "VerticalTop" )
2042 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2044 else if( value == "VerticalCenter")
2046 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2048 else if( value == "VerticalBottom")
2050 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2054 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2060 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2061 if( RELAYOUT_ALL != mRelayoutOperations )
2063 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2064 RELAYOUT_TEXT_ACTOR_UPDATE |
2065 RELAYOUT_ALIGNMENT |
2066 RELAYOUT_VISIBILITY );
2070 std::string TextView::OnHorizontalAlignmentPropertyGet()
2072 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2074 return "HorizontalLeft";
2076 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2078 return "HorizontalCenter";
2080 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2082 return "HorizontalRight";
2086 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2090 std::string TextView::OnVerticalAlignmentPropertyGet()
2092 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2094 return "VerticalTop";
2096 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2098 return "VerticalCenter";
2100 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2102 return "VerticalBottom";
2106 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2110 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2112 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2116 TextView& textViewImpl( GetImpl( textView ) );
2119 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2121 textViewImpl.OnMarkupEnabledPeopertySet( value );
2124 case Toolkit::TextView::PROPERTY_TEXT:
2126 textViewImpl.SetText( value.Get<std::string>() );
2129 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2131 textViewImpl.OnMultilinePolicyPropertySet( value );
2134 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2136 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2139 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2141 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2144 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2146 textViewImpl.OnLineJustificationPropertySet( value );
2149 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2151 textViewImpl.OnFadeBoundaryPropertySet( value );
2154 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2156 Dali::PointSize pointSize( value.Get<float>() );
2157 textViewImpl.SetLineHeightOffset(pointSize);
2160 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2161 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2163 textViewImpl.OnAlignmentPropertySet( index, value );
2170 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2172 Property::Value value;
2174 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2178 TextView& textViewImpl( GetImpl( textView ) );
2181 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2183 value = textViewImpl.IsMarkupProcessingEnabled();
2186 case Toolkit::TextView::PROPERTY_TEXT:
2188 value = textViewImpl.GetText();
2191 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2193 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2196 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2198 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2201 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2203 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2206 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2208 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2211 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2213 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2214 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2215 static_cast<float>( boundary.mRight.value ),
2216 static_cast<float>( boundary.mTop.value ),
2217 static_cast<float>( boundary.mBottom.value ) );
2220 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2222 value = textViewImpl.GetLineHeightOffset().value;
2225 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2227 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2230 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2232 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2240 } // namespace Internal
2242 } // namespace Toolkit