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( Toolkit::TextView::MultilinePolicy multilinePolicy,
873 Toolkit::TextView::ExceedPolicy widthExceedPolicy,
874 Toolkit::TextView::ExceedPolicy heightExceedPolicy,
875 Toolkit::Alignment::Type alignmentType,
876 Toolkit::TextView::LineJustification lineJustification,
877 float lineHeightOffset,
878 const std::string& ellipsizeText,
880 : mMultilinePolicy( multilinePolicy ),
881 mWidthExceedPolicy( widthExceedPolicy ),
882 mHeightExceedPolicy( heightExceedPolicy ),
883 mHorizontalAlignment(),
884 mVerticalAlignment(),
885 mLineJustification( lineJustification ),
886 mLineHeightOffset( lineHeightOffset ),
888 mMarkUpEnabled( markUpEnabled )
891 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
892 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
893 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
894 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
895 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
896 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
898 mHorizontalAlignment = horizontalAlignment;
899 mVerticalAlignment = verticalAlignment;
901 // Sets ellipsize text
902 MarkupProcessor::StyledTextArray styledEllipsize;
903 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
906 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
907 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
908 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
909 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
910 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
911 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
912 mLineJustification( layoutParameters.mLineJustification ),
913 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
914 mEllipsizeText( layoutParameters.mEllipsizeText ),
915 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
919 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
921 mMultilinePolicy = layoutParameters.mMultilinePolicy;
922 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
923 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
924 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
925 mVerticalAlignment = layoutParameters.mVerticalAlignment;
926 mLineJustification = layoutParameters.mLineJustification;
927 mLineHeightOffset = layoutParameters.mLineHeightOffset;
928 mEllipsizeText = layoutParameters.mEllipsizeText;
929 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
934 TextView::VisualParameters::VisualParameters()
936 mSortModifier( 0.f ),
937 mCameraScrollPosition( 0.f, 0.f ),
938 mSnapshotModeEnabled( false ),
939 mScrollEnabled( false ),
940 mScrollPositionTrimmed( false )
944 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
945 : mFadeBoundary( visualParameters.mFadeBoundary ),
946 mSortModifier( visualParameters.mSortModifier ),
947 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
948 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
949 mScrollEnabled( visualParameters.mScrollEnabled ),
950 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
954 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
956 mFadeBoundary = visualParameters.mFadeBoundary;
957 mSortModifier = visualParameters.mSortModifier;
958 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
959 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
960 mScrollEnabled = visualParameters.mScrollEnabled;
961 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
966 TextView::RelayoutData::RelayoutData()
968 mShrinkFactor( 1.f ),
970 mCharacterLogicalToVisualMap(),
971 mCharacterVisualToLogicalMap(),
973 mCharacterLayoutInfoTable(),
975 mTextSizeForRelayoutOption()
979 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
980 : mTextViewSize( relayoutData.mTextViewSize ),
981 mShrinkFactor( relayoutData.mShrinkFactor ),
982 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
983 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
984 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
985 mGlyphActors( relayoutData.mGlyphActors ),
986 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
987 mLines( relayoutData.mLines ),
988 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
992 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
994 mTextViewSize = relayoutData.mTextViewSize;
995 mShrinkFactor = relayoutData.mShrinkFactor;
996 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
997 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
998 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
999 mGlyphActors = relayoutData.mGlyphActors;
1000 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1001 mLines = relayoutData.mLines;
1002 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1007 TextView::TextView()
1008 : Control( REQUIRES_STYLE_CHANGE_SIGNALS ),
1009 mCurrentStyledText(),
1010 mTextViewProcessorOperations(),
1011 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1012 Toolkit::TextView::Original,
1013 Toolkit::TextView::Original,
1014 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1015 Toolkit::TextView::Left,
1017 std::string( "..." ),
1019 mVisualParameters(),
1021 mRelayoutOperations( NO_RELAYOUT ),
1022 mOffscreenRootActor(),
1023 mOffscreenImageActor(),
1024 mOffscreenCameraActor(),
1025 mCurrentOffscreenSize(),
1026 mFrameBufferImage(),
1028 mPanGestureDetector(),
1029 mLockPreviousSnapshotMode( false ),
1030 mPreviousSnapshotModeEnabled( false ),
1031 mMarkUpEnabled( false )
1033 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1034 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1037 TextView::~TextView()
1039 // Destroys offscreen rendering resources.
1040 DestroyOffscreenRenderingResources();
1042 // Destroys scroll pan gesture detector.
1043 if( mPanGestureDetector )
1045 mPanGestureDetector.Reset();
1049 Vector3 TextView::GetNaturalSize()
1051 if( !mTextViewProcessorOperations.empty() )
1053 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1055 if( !mRelayoutData.mGlyphActors.empty() )
1057 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1058 // add them to the text-actor cache.
1059 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1060 mRelayoutData.mGlyphActors.clear();
1062 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1065 PerformTextViewProcessorOperations();
1068 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1071 float TextView::GetHeightForWidth( float width )
1075 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1076 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1077 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1079 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1080 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1081 height = GetNaturalSize().height;
1085 // Check if the given width is different than the current one.
1086 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1088 // Check if the text-view has glyph-actors.
1089 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1091 // Check which layout operations need to be done.
1092 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1094 if( relayoutSizeAndPositionNeeded )
1096 if( hasGlyphActors )
1098 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1099 // add them to the text-actor cache.
1100 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1101 mRelayoutData.mGlyphActors.clear();
1104 // Use the given width.
1105 const Vector2 textViewSize( width, GetControlSize().height );
1107 // Relays-out but doesn't add glyph-actors to the text-view.
1108 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1111 // Retrieve the text height after relayout the text.
1112 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1114 if( differentWidth )
1116 // Revert the relayout operation mask
1117 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1120 if( hasGlyphActors )
1122 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1125 if( differentWidth || hasGlyphActors )
1134 float TextView::GetWidthForHeight( float height )
1136 // TODO: Needs implementing properly, for now just return the natural width.
1137 return GetNaturalSize().width;
1141 void TextView::OnInitialize()
1146 void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
1148 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1149 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1150 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1152 SetText( mCurrentStyledText );
1155 void TextView::OnControlSizeSet( const Vector3& size )
1157 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1159 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1160 mRelayoutOperations = RELAYOUT_ALL;
1162 // Request to be relaid out
1167 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1169 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1171 // Not worth to relayout if width or height is equal to zero.
1175 if( size != mRelayoutData.mTextViewSize )
1177 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1178 if( RELAYOUT_ALL != mRelayoutOperations )
1180 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1181 RELAYOUT_REMOVE_TEXT_ACTORS |
1182 RELAYOUT_SIZE_POSITION |
1183 RELAYOUT_ALIGNMENT |
1184 RELAYOUT_VISIBILITY |
1185 RELAYOUT_TEXT_ACTOR_UPDATE |
1186 RELAYOUT_INSERT_TO_TEXT_VIEW );
1190 // Remove glyph-actors from text-view
1191 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1193 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1194 mRelayoutData.mGlyphActors.clear();
1197 if( NO_RELAYOUT != mRelayoutOperations )
1199 // Relays-out and add glyph-actors to the text-view.
1200 DoRelayOut( size, mRelayoutOperations );
1201 ProcessSnapshot( size );
1204 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1205 mRelayoutData.mTextActorCache.ClearTexts();
1208 void TextView::PerformTextViewProcessorOperations()
1210 // Traverse the relayout operation vector ...
1212 // Optimizes some operations.
1213 OptimizeTextViewProcessorOperations();
1215 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1217 const TextViewProcessorMetadata& relayoutMetadata( *it );
1219 switch( relayoutMetadata.mType )
1221 case TextView::TextSet:
1223 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1228 case TextView::TextInserted:
1230 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1231 relayoutMetadata.mText,
1236 case TextView::TextReplaced:
1238 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1239 relayoutMetadata.mNumberOfCharacters,
1240 relayoutMetadata.mText,
1245 case TextView::TextRemoved:
1247 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1248 relayoutMetadata.mNumberOfCharacters,
1251 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1254 case TextView::NewLineHeight:
1256 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1257 mRelayoutData.mTextLayoutInfo );
1260 case TextView::NewStyle:
1262 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1263 relayoutMetadata.mStyleMask,
1270 // Clear all operations when they are done.
1271 mTextViewProcessorOperations.clear();
1274 void TextView::OptimizeTextViewProcessorOperations()
1276 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1278 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1279 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1280 // use the cache without clearing the text-actors.
1282 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1284 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1286 const TextViewProcessorMetadata& relayoutMetadata( *it );
1288 switch( relayoutMetadata.mType )
1290 case TextView::TextRemoved:
1292 bool optimizationDone = false;
1294 if( it + 1u != endIt )
1296 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1u ) );
1297 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1299 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1301 optimizationDone = true;
1302 TextViewProcessorMetadata newRelayoutMetadata;
1303 newRelayoutMetadata.mType = TextView::TextReplaced;
1304 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1305 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1306 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1307 textViewProcessorOperations.push_back( newRelayoutMetadata );
1309 // do not access the TextInserted operation in next iteration.
1315 if( !optimizationDone )
1317 textViewProcessorOperations.push_back( relayoutMetadata );
1323 textViewProcessorOperations.push_back( relayoutMetadata );
1328 mTextViewProcessorOperations = textViewProcessorOperations;
1331 void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask )
1333 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1334 if( !mTextViewProcessorOperations.empty() )
1336 PerformTextViewProcessorOperations();
1339 CombineExceedPolicies();
1342 if( mVisualParameters.mSnapshotModeEnabled )
1344 rootActor = mOffscreenRootActor;
1351 mRelayoutData.mTextViewSize = textViewSize;
1352 switch( mLayoutParameters.mMultilinePolicy )
1354 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1356 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1358 } // SplitByNewLineChar
1360 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1362 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1366 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1368 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1371 } // switch( mMultilinePolicy )
1373 // Remove done operations from the mask.
1374 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1377 void TextView::ProcessSnapshot( const Size& textViewSize )
1379 if( mVisualParameters.mSnapshotModeEnabled )
1381 // If layout options change, it's needed generate a new image.
1383 if( mOffscreenRootActor )
1385 // Set the root actor visible.
1386 // The root actor is set to non visible after the render task is processed.
1387 mOffscreenRootActor.SetVisible( true );
1389 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1390 mOffscreenRootActor.SetSize( textViewSize );
1393 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1394 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1396 // Set the image actor visible.
1397 // The image actor is set to non visible if there is no text to render.
1398 mOffscreenImageActor.SetVisible( true );
1400 // Calculates the offscreen image's size. It takes into account different points:
1401 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1402 // * There is a maximum texture size the graphic subsystem can load on the memory.
1403 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1405 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1406 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1407 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1408 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1410 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1414 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1415 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1416 offscreenSize.height,
1419 // Stores current text-view size to avoid create new Dali resources if text changes.
1420 mCurrentOffscreenSize = offscreenSize;
1422 if( !mOffscreenCameraActor )
1424 // Creates a new camera actor.
1425 mOffscreenCameraActor = CameraActor::New();
1426 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1427 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1428 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1430 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1432 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1435 // Calculate camera parameters for current text size.
1436 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1439 if( mVisualParameters.mScrollEnabled )
1441 // Updates the offscreen camera position with the new scroll offset.
1442 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1443 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1447 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1448 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1453 // Creates a new render task.
1454 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1456 mRenderTask.SetSourceActor( mOffscreenRootActor );
1457 mRenderTask.SetInputEnabled( false );
1458 mRenderTask.SetClearColor( Color::TRANSPARENT );
1459 mRenderTask.SetClearEnabled( true );
1460 mRenderTask.SetExclusive( true );
1462 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1463 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1468 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1469 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1472 // Process the render task only once every time the text changes or the text-view's size canges.
1473 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1477 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1478 mOffscreenImageActor.SetVisible( false );
1483 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1485 float xPosition = 0.f;
1486 float yPosition = 0.f;
1487 Vector3 parentOrigin = ParentOrigin::CENTER;
1488 Vector3 anchorPoint = AnchorPoint::CENTER;
1490 switch( mLayoutParameters.mHorizontalAlignment )
1492 case Toolkit::Alignment::HorizontalLeft:
1494 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1495 parentOrigin.x = 0.f;
1496 anchorPoint.x = 0.f;
1499 case Toolkit::Alignment::HorizontalCenter:
1504 case Toolkit::Alignment::HorizontalRight:
1506 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1507 parentOrigin.x = 1.f;
1508 anchorPoint.x = 1.f;
1513 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1517 switch( mLayoutParameters.mVerticalAlignment )
1519 case Toolkit::Alignment::VerticalTop:
1521 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1522 parentOrigin.y = 0.f;
1523 anchorPoint.y = 0.f;
1526 case Toolkit::Alignment::VerticalCenter:
1531 case Toolkit::Alignment::VerticalBottom:
1533 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1534 parentOrigin.y = 1.f;
1535 anchorPoint.y = 1.f;
1540 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1544 mOffscreenCameraActor.SetX( xPosition );
1545 mOffscreenCameraActor.SetY( yPosition );
1547 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1548 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1551 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1553 // not to process the offscreen root actor by setting its visibility to false.
1554 mOffscreenRootActor.SetVisible( false );
1556 // Sets the new size and the new frame buffer to the image actor.
1557 // Image actor must have same size as text. Otherwise text can be truncated.
1558 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1559 mOffscreenImageActor.SetImage( mFrameBufferImage );
1562 void TextView::DestroyOffscreenRenderingResources()
1566 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1568 if( Stage::IsInstalled() )
1570 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1573 mRenderTask.Reset();
1576 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1577 if( mOffscreenCameraActor )
1579 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1581 mOffscreenCameraActor.Reset();
1584 if( mOffscreenRootActor )
1586 mOffscreenRootActor.Reset();
1589 if( mOffscreenImageActor )
1591 mOffscreenImageActor.Reset();
1594 mCurrentOffscreenSize = Size( 0.f, 0.f );
1596 if( mFrameBufferImage )
1598 mFrameBufferImage.Reset();
1602 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1604 if( 1u == gesture.numberOfTouches )
1606 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1610 void TextView::TrimScrollPosition()
1612 const Vector3& textViewSize = GetControlSize();
1614 // Before use the text's size, relayout the text is needed to get the actual text size.
1615 GetTextLayoutInfo();
1617 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1618 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1619 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1620 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1621 float minVerticalDisplacement = -maxVerticalDisplacement;
1623 // Updates the range if the text is aligned on the right or left.
1624 switch( mLayoutParameters.mHorizontalAlignment )
1626 case Toolkit::Alignment::HorizontalLeft:
1628 maxHorizontalDisplacement *= 2.f;
1629 minHorizontalDisplacement = 0.f;
1632 case Toolkit::Alignment::HorizontalCenter:
1637 case Toolkit::Alignment::HorizontalRight:
1639 maxHorizontalDisplacement = 0.f;
1640 minHorizontalDisplacement *= 2.f;
1645 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1649 // Updates the range if the text is aligned on the top or bottom.
1650 switch( mLayoutParameters.mVerticalAlignment )
1652 case Toolkit::Alignment::VerticalTop:
1654 maxVerticalDisplacement *= 2.f;
1655 minVerticalDisplacement = 0.f;
1658 case Toolkit::Alignment::VerticalCenter:
1663 case Toolkit::Alignment::VerticalBottom:
1665 maxVerticalDisplacement = 0.f;
1666 minVerticalDisplacement *= 2.f;
1671 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1675 // Trims the scroll position to be within the range.
1676 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1677 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1679 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1680 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1683 void TextView::DoSetScrollPosition( const Vector2& position )
1685 // Stores old scroll position.
1686 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1688 // Updates the scroll position
1689 mVisualParameters.mCameraScrollPosition = position;
1691 // Ensures the text-view is covered with text.
1692 TrimScrollPosition();
1694 // Calculate the difference with the previous scroll position
1695 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1696 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1698 if( mOffscreenRootActor )
1700 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1702 mOffscreenRootActor.SetVisible( true );
1705 if( mOffscreenCameraActor )
1707 // Update the offscreen camera with the new scroll position.
1708 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1709 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1714 // Refresh the render-task.
1715 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1719 Toolkit::TextView handle( GetOwner() );
1720 mScrolledSignalV2.Emit( handle, delta );
1723 void TextView::CombineExceedPolicies()
1725 // Calculates the combination of exceed policies.
1727 switch( mLayoutParameters.mWidthExceedPolicy )
1729 case Toolkit::TextView::Original:
1731 switch( mLayoutParameters.mHeightExceedPolicy )
1733 case Toolkit::TextView::Original:
1735 mLayoutParameters.mExceedPolicy = Original;
1738 case Toolkit::TextView::Fade:
1740 mLayoutParameters.mExceedPolicy = OriginalFade;
1743 case Toolkit::TextView::ShrinkToFit:
1745 mLayoutParameters.mExceedPolicy = OriginalShrink;
1750 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1755 case Toolkit::TextView::Split:
1757 switch( mLayoutParameters.mHeightExceedPolicy )
1759 case Toolkit::TextView::Original:
1761 mLayoutParameters.mExceedPolicy = SplitOriginal;
1764 case Toolkit::TextView::Fade:
1766 mLayoutParameters.mExceedPolicy = SplitFade;
1769 case Toolkit::TextView::ShrinkToFit:
1771 mLayoutParameters.mExceedPolicy = SplitShrink;
1774 case Toolkit::TextView::EllipsizeEnd:
1776 mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd;
1781 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1786 case Toolkit::TextView::Fade:
1788 switch( mLayoutParameters.mHeightExceedPolicy )
1790 case Toolkit::TextView::Original:
1792 mLayoutParameters.mExceedPolicy = FadeOriginal;
1795 case Toolkit::TextView::Fade:
1797 mLayoutParameters.mExceedPolicy = Fade;
1802 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1807 case Toolkit::TextView::ShrinkToFit:
1809 switch( mLayoutParameters.mHeightExceedPolicy )
1811 case Toolkit::TextView::Original:
1813 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1816 case Toolkit::TextView::Fade:
1818 mLayoutParameters.mExceedPolicy = ShrinkFade;
1821 case Toolkit::TextView::ShrinkToFit:
1823 mLayoutParameters.mExceedPolicy = Shrink;
1828 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1833 case Toolkit::TextView::EllipsizeEnd:
1835 switch( mLayoutParameters.mHeightExceedPolicy )
1837 case Toolkit::TextView::Original:
1839 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1842 case Toolkit::TextView::EllipsizeEnd:
1844 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1849 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1856 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1861 Actor TextView::GetRootActor() const
1863 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1867 if( mVisualParameters.mSnapshotModeEnabled )
1869 rootActor = mOffscreenRootActor;
1879 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1881 bool newValue( propertyValue.Get<bool>() );
1882 if( newValue != IsMarkupProcessingEnabled() )
1884 SetMarkupProcessingEnabled( newValue );
1887 // If markup processing has been enabled, Ensure current text is reprocessed.
1888 const std::string& currentText( GetText() );
1889 if( ! currentText.empty() )
1891 SetText( currentText );
1897 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1899 std::string policyName( propertyValue.Get<std::string>() );
1900 if(policyName == "SplitByNewLineChar")
1902 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1904 else if(policyName == "SplitByWord")
1906 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1908 else if(policyName == "SplitByChar")
1910 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1914 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1918 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1920 std::string policyName( propertyValue.Get<std::string>() );
1921 if(policyName == "Original")
1923 SetWidthExceedPolicy(Toolkit::TextView::Original);
1925 else if(policyName == "Fade")
1927 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1929 else if(policyName == "Split")
1931 SetWidthExceedPolicy(Toolkit::TextView::Split);
1933 else if(policyName == "ShrinkToFit")
1935 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1937 else if(policyName == "EllipsizeEnd")
1939 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1943 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1947 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1949 std::string policyName( propertyValue.Get<std::string>() );
1950 if(policyName == "Original")
1952 SetHeightExceedPolicy(Toolkit::TextView::Original);
1954 else if(policyName == "Fade")
1956 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1958 else if(policyName == "Split")
1960 SetHeightExceedPolicy(Toolkit::TextView::Split);
1962 else if(policyName == "ShrinkToFit")
1964 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1968 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1972 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1974 std::string policyName( propertyValue.Get<std::string>() );
1975 if(policyName == "Left")
1977 SetLineJustification(Toolkit::TextView::Left);
1979 else if(policyName == "Center")
1981 SetLineJustification(Toolkit::TextView::Center);
1983 else if(policyName == "Right")
1985 SetLineJustification(Toolkit::TextView::Right);
1987 else if(policyName == "Justified")
1989 SetLineJustification(Toolkit::TextView::Justified);
1993 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
1997 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
1999 Vector4 value( propertyValue.Get<Vector4>() );
2000 DALI_ASSERT_ALWAYS( ( value.x >= 0.f ) && ( value.y >= 0.f ) && ( value.z >= 0.f ) && ( value.w >= 0.f )
2001 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2003 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2004 PixelSize( static_cast<unsigned int>( value.y ) ),
2005 PixelSize( static_cast<unsigned int>( value.z ) ),
2006 PixelSize( static_cast<unsigned int>( value.w ) ) );
2008 SetFadeBoundary( fadeBoundary );
2011 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2013 std::string value( propertyValue.Get<std::string>() );
2015 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2017 if(value == "HorizontalLeft")
2019 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2021 else if( value == "HorizontalCenter")
2023 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2025 else if( value == "HorizontalRight")
2027 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2031 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2034 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2036 if( value == "VerticalTop" )
2038 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2040 else if( value == "VerticalCenter")
2042 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2044 else if( value == "VerticalBottom")
2046 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2050 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2056 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2057 if( RELAYOUT_ALL != mRelayoutOperations )
2059 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2060 RELAYOUT_TEXT_ACTOR_UPDATE |
2061 RELAYOUT_ALIGNMENT |
2062 RELAYOUT_VISIBILITY );
2066 std::string TextView::OnHorizontalAlignmentPropertyGet()
2068 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2070 return "HorizontalLeft";
2072 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2074 return "HorizontalCenter";
2076 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2078 return "HorizontalRight";
2082 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2086 std::string TextView::OnVerticalAlignmentPropertyGet()
2088 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2090 return "VerticalTop";
2092 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2094 return "VerticalCenter";
2096 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2098 return "VerticalBottom";
2102 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2106 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2108 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2112 TextView& textViewImpl( GetImpl( textView ) );
2115 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2117 textViewImpl.OnMarkupEnabledPeopertySet( value );
2120 case Toolkit::TextView::PROPERTY_TEXT:
2122 textViewImpl.SetText( value.Get<std::string>() );
2125 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2127 textViewImpl.OnMultilinePolicyPropertySet( value );
2130 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2132 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2135 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2137 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2140 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2142 textViewImpl.OnLineJustificationPropertySet( value );
2145 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2147 textViewImpl.OnFadeBoundaryPropertySet( value );
2150 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2152 Dali::PointSize pointSize( value.Get<float>() );
2153 textViewImpl.SetLineHeightOffset(pointSize);
2156 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2157 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2159 textViewImpl.OnAlignmentPropertySet( index, value );
2166 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2168 Property::Value value;
2170 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2174 TextView& textViewImpl( GetImpl( textView ) );
2177 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2179 value = textViewImpl.IsMarkupProcessingEnabled();
2182 case Toolkit::TextView::PROPERTY_TEXT:
2184 value = textViewImpl.GetText();
2187 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2189 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2192 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2194 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2197 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2199 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2202 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2204 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2207 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2209 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2210 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2211 static_cast<float>( boundary.mRight.value ),
2212 static_cast<float>( boundary.mTop.value ),
2213 static_cast<float>( boundary.mBottom.value ) );
2216 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2218 value = textViewImpl.GetLineHeightOffset().value;
2221 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2223 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2226 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2228 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2236 } // namespace Internal
2238 } // namespace Toolkit