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( 0 ),
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 |
315 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
320 PointSize TextView::GetLineHeightOffset() const
322 return PointSize( mLayoutParameters.mLineHeightOffset );
325 void TextView::SetStyleToCurrentText( const TextStyle& style, TextStyle::Mask mask )
327 if( !mCurrentStyledText.empty() )
329 const bool checkFontName = mask & TextStyle::FONT;
330 const bool checkFontSize = mask & TextStyle::SIZE;
331 const bool checkFontStyle = mask & TextStyle::STYLE;
333 // Check first if metrics have changed.
334 bool metricsChanged = false;
335 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
337 const MarkupProcessor::StyledText& styledText( *it );
339 metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
340 ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
341 ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
346 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
348 // If metrics change, new text measurements are needed.
349 SetText( mCurrentStyledText );
353 // Deletes any previous operation which sets a new style.
354 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
355 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
357 // Creates metadata with the new style operation.
358 TextViewProcessorMetadata metadata;
359 metadata.mType = TextView::NewStyle;
361 MarkupProcessor::StyledText text;
363 metadata.mText.push_back( text );
364 metadata.mStyleMask = mask;
366 mTextViewProcessorOperations.push_back( metadata );
368 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
372 if( RELAYOUT_ALL != mRelayoutOperations )
374 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
375 RELAYOUT_TEXT_ACTOR_UPDATE );
380 // Sets the new style to the ellipsize text
381 if( !mLayoutParameters.mEllipsizeText.empty() )
383 for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
385 (*it).mStyle.Copy( style, mask );
388 SetEllipsizeText( mLayoutParameters.mEllipsizeText );
392 void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
394 if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
396 Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
397 ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
398 ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
399 Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
400 ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
401 ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
403 mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
404 mLayoutParameters.mVerticalAlignment = verticalAlignment;
408 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
409 if( RELAYOUT_ALL != mRelayoutOperations )
411 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
412 RELAYOUT_TEXT_ACTOR_UPDATE |
414 RELAYOUT_VISIBILITY );
419 Toolkit::Alignment::Type TextView::GetTextAlignment() const
421 return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
424 void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
426 if( policy != mLayoutParameters.mMultilinePolicy )
428 mLayoutParameters.mMultilinePolicy = policy;
430 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
431 mRelayoutOperations = RELAYOUT_ALL;
437 Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
439 return mLayoutParameters.mMultilinePolicy;
442 void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
444 // The layout info could be invalid depending on the current exceed policy and the new one.
445 // i.e. if the current policy is Split and the new one is ShrinkToFit then
446 // the layout info generated for each char is not needed.
447 if( policy != mLayoutParameters.mWidthExceedPolicy )
449 mLayoutParameters.mWidthExceedPolicy = policy;
451 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
452 mRelayoutOperations = RELAYOUT_ALL;
458 Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
460 return mLayoutParameters.mWidthExceedPolicy;
463 void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
465 if( policy != mLayoutParameters.mHeightExceedPolicy )
467 mLayoutParameters.mHeightExceedPolicy = policy;
471 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
472 if( RELAYOUT_ALL != mRelayoutOperations )
474 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
475 RELAYOUT_REMOVE_TEXT_ACTORS |
476 RELAYOUT_SIZE_POSITION |
478 RELAYOUT_VISIBILITY |
479 RELAYOUT_TEXT_ACTOR_UPDATE |
480 RELAYOUT_INSERT_TO_TEXT_VIEW |
481 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
486 Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
488 return mLayoutParameters.mHeightExceedPolicy;
491 void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
493 if( justification != mLayoutParameters.mLineJustification )
495 mLayoutParameters.mLineJustification = justification;
499 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
500 if( RELAYOUT_ALL != mRelayoutOperations )
502 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
503 RELAYOUT_REMOVE_TEXT_ACTORS |
504 RELAYOUT_SIZE_POSITION |
506 RELAYOUT_VISIBILITY |
507 RELAYOUT_TEXT_ACTOR_UPDATE |
508 RELAYOUT_INSERT_TO_TEXT_VIEW |
509 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
514 Toolkit::TextView::LineJustification TextView::GetLineJustification() const
516 return mLayoutParameters.mLineJustification;
519 void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
521 if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
522 ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
523 ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
524 ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
526 mVisualParameters.mFadeBoundary = fadeBoundary;
530 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
531 if( RELAYOUT_ALL != mRelayoutOperations )
533 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
534 RELAYOUT_REMOVE_TEXT_ACTORS |
535 RELAYOUT_VISIBILITY |
536 RELAYOUT_TEXT_ACTOR_UPDATE |
537 RELAYOUT_INSERT_TO_TEXT_VIEW |
538 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
543 const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
545 return mVisualParameters.mFadeBoundary;
548 void TextView::SetEllipsizeText( const std::string& ellipsizeText )
550 // Creates a styled text with the markup or plain string.
551 MarkupProcessor::StyledTextArray styledText;
552 MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() );
554 SetEllipsizeText( styledText );
557 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
559 mLayoutParameters.mEllipsizeText = ellipsizeText;
561 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
563 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
564 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
566 // Request to be relaid out
569 mRelayoutOperations = RELAYOUT_ALL;
572 std::string TextView::GetEllipsizeText() const
575 for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
577 text.append( (*it).mText.GetText() );
583 void TextView::GetTextLayoutInfo()
585 const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
586 const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
587 const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
589 if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
591 Vector3 textViewSize = GetControlSize();
593 if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
594 ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
595 ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
596 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
597 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
599 // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
600 // the text natural size can be used.
601 textViewSize = GetNaturalSize();
604 if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
605 ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
607 // Check if the text-view has glyph-actors.
608 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
610 RelayoutOperationMask mask = NO_RELAYOUT;
611 if( relayoutSizeAndPositionNeeded )
613 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
615 if( relayoutAlignmentNeeded )
617 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
619 if( relayoutVisibilityNeeded )
621 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
626 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
627 // add them to the text-actor cache.
628 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
629 mRelayoutData.mGlyphActors.clear();
632 // Relays-out but doesn't add glyph-actors to the text-view.
633 DoRelayOut( textViewSize.GetVectorXY(), mask );
637 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
638 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
645 void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
649 textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
650 textLayoutInfo.mLines = mRelayoutData.mLines;
652 textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
653 textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
655 textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
657 textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
660 void TextView::SetSortModifier( float depthOffset )
662 mVisualParameters.mSortModifier = depthOffset;
664 for( std::vector<RenderableActor>::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.end();
668 ( *it ).SetSortModifier( depthOffset );
671 if( mOffscreenImageActor )
673 mOffscreenImageActor.SetSortModifier( depthOffset );
677 void TextView::SetSnapshotModeEnabled( bool enable )
679 if( enable != mVisualParameters.mSnapshotModeEnabled )
681 // Remove first all glyph-actors
682 if( !mRelayoutData.mGlyphActors.empty() )
684 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
687 mVisualParameters.mSnapshotModeEnabled = enable;
688 if( !mLockPreviousSnapshotMode )
690 // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
691 // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
693 // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
694 // to smash the stored value.
695 mPreviousSnapshotModeEnabled = enable;
698 if( mVisualParameters.mSnapshotModeEnabled )
700 // Create a root actor and an image actor for offscreen rendering.
701 mOffscreenRootActor = Layer::New();
702 mOffscreenImageActor = ImageActor::New();
704 mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
705 mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
706 mOffscreenRootActor.SetInheritRotation( false );
707 mOffscreenRootActor.SetInheritScale( false );
708 mOffscreenRootActor.SetDepthTestDisabled( true );
710 mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
712 mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
713 mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
714 mOffscreenImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
715 BlendingFactor::ONE, BlendingFactor::ONE );
718 self.Add( mOffscreenRootActor );
719 self.Add( mOffscreenImageActor );
720 mOffscreenImageActor.SetScale( Vector3( 1.f, -1.f, 1.f ) );
726 if( mOffscreenRootActor )
728 self.Remove( mOffscreenRootActor );
731 if( mOffscreenImageActor )
733 self.Remove( mOffscreenImageActor );
736 DestroyOffscreenRenderingResources();
739 if( RELAYOUT_ALL != mRelayoutOperations )
741 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
742 RELAYOUT_REMOVE_TEXT_ACTORS |
743 RELAYOUT_TEXT_ACTOR_UPDATE |
744 RELAYOUT_INSERT_TO_TEXT_VIEW |
745 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
751 bool TextView::IsSnapshotModeEnabled() const
753 return mVisualParameters.mSnapshotModeEnabled;
756 void TextView::SetMarkupProcessingEnabled( bool enable )
758 mMarkUpEnabled = enable;
761 bool TextView::IsMarkupProcessingEnabled() const
763 return mMarkUpEnabled;
766 void TextView::SetScrollEnabled( bool enable )
768 if( enable != mVisualParameters.mScrollEnabled )
770 mVisualParameters.mScrollEnabled = enable;
772 if( mVisualParameters.mScrollEnabled )
774 // Offscreen rendering is needed to enable text scroll.
776 // Stores previous value of the snapshot mode.
777 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
780 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
781 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
782 Lock lock( mLockPreviousSnapshotMode );
783 SetSnapshotModeEnabled( true );
786 // Creates the pan gesture detector and attach the text-view.
787 mPanGestureDetector = PanGestureDetector::New();
788 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
789 mPanGestureDetector.Attach( Self() );
793 // Removes the pan gesture detector.
794 if( mPanGestureDetector )
796 mPanGestureDetector.Detach( Self() );
797 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
798 mPanGestureDetector.Reset();
801 // Restores the previous state for snapshot mode.
802 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
807 bool TextView::IsScrollEnabled() const
809 return mVisualParameters.mScrollEnabled;
812 void TextView::SetScrollPosition( const Vector2& position )
814 if( position != mVisualParameters.mCameraScrollPosition )
816 // Guard against destruction during signal emission
817 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
818 Toolkit::TextView handle( GetOwner() );
820 DoSetScrollPosition( position );
822 // Check if the new scroll position has been trimmed.
823 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
827 const Vector2& TextView::GetScrollPosition() const
829 return mVisualParameters.mCameraScrollPosition;
832 bool TextView::IsScrollPositionTrimmed() const
834 return mVisualParameters.mScrollPositionTrimmed;
837 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
839 return mScrolledSignalV2;
842 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
844 Dali::BaseHandle handle( object );
846 bool connected( true );
847 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
849 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
851 textView.ScrolledSignal().Connect( tracker, functor );
855 // signalName does not match any signal
862 TextView::LayoutParameters::LayoutParameters()
863 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
864 mWidthExceedPolicy( Toolkit::TextView::Original ),
865 mHeightExceedPolicy( Toolkit::TextView::Original ),
866 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
867 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
868 mLineJustification( Toolkit::TextView::Left ),
869 mLineHeightOffset( 0.f ),
871 mMarkUpEnabled( false )
873 // Sets ellipsize text
874 MarkupProcessor::StyledTextArray styledEllipsize;
875 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
878 TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy,
879 Toolkit::TextView::ExceedPolicy widthExceedPolicy,
880 Toolkit::TextView::ExceedPolicy heightExceedPolicy,
881 Toolkit::Alignment::Type alignmentType,
882 Toolkit::TextView::LineJustification lineJustification,
883 float lineHeightOffset,
884 const std::string& ellipsizeText,
886 : mMultilinePolicy( multilinePolicy ),
887 mWidthExceedPolicy( widthExceedPolicy ),
888 mHeightExceedPolicy( heightExceedPolicy ),
889 mHorizontalAlignment(),
890 mVerticalAlignment(),
891 mLineJustification( lineJustification ),
892 mLineHeightOffset( lineHeightOffset ),
894 mMarkUpEnabled( markUpEnabled )
897 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
898 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
899 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
900 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
901 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
902 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
904 mHorizontalAlignment = horizontalAlignment;
905 mVerticalAlignment = verticalAlignment;
907 // Sets ellipsize text
908 MarkupProcessor::StyledTextArray styledEllipsize;
909 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
912 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
913 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
914 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
915 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
916 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
917 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
918 mLineJustification( layoutParameters.mLineJustification ),
919 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
920 mEllipsizeText( layoutParameters.mEllipsizeText ),
921 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
925 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
927 mMultilinePolicy = layoutParameters.mMultilinePolicy;
928 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
929 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
930 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
931 mVerticalAlignment = layoutParameters.mVerticalAlignment;
932 mLineJustification = layoutParameters.mLineJustification;
933 mLineHeightOffset = layoutParameters.mLineHeightOffset;
934 mEllipsizeText = layoutParameters.mEllipsizeText;
935 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
940 TextView::VisualParameters::VisualParameters()
942 mSortModifier( 0.f ),
943 mCameraScrollPosition( 0.f, 0.f ),
944 mSnapshotModeEnabled( false ),
945 mScrollEnabled( false ),
946 mScrollPositionTrimmed( false )
950 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
951 : mFadeBoundary( visualParameters.mFadeBoundary ),
952 mSortModifier( visualParameters.mSortModifier ),
953 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
954 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
955 mScrollEnabled( visualParameters.mScrollEnabled ),
956 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
960 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
962 mFadeBoundary = visualParameters.mFadeBoundary;
963 mSortModifier = visualParameters.mSortModifier;
964 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
965 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
966 mScrollEnabled = visualParameters.mScrollEnabled;
967 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
972 TextView::RelayoutData::RelayoutData()
974 mShrinkFactor( 1.f ),
976 mCharacterLogicalToVisualMap(),
977 mCharacterVisualToLogicalMap(),
979 mCharacterLayoutInfoTable(),
981 mTextSizeForRelayoutOption()
985 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
986 : mTextViewSize( relayoutData.mTextViewSize ),
987 mShrinkFactor( relayoutData.mShrinkFactor ),
988 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
989 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
990 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
991 mGlyphActors( relayoutData.mGlyphActors ),
992 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
993 mLines( relayoutData.mLines ),
994 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
998 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
1000 mTextViewSize = relayoutData.mTextViewSize;
1001 mShrinkFactor = relayoutData.mShrinkFactor;
1002 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
1003 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
1004 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
1005 mGlyphActors = relayoutData.mGlyphActors;
1006 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1007 mLines = relayoutData.mLines;
1008 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1013 TextView::TextView()
1014 : Control( REQUIRES_STYLE_CHANGE_SIGNALS ),
1015 mCurrentStyledText(),
1016 mTextViewProcessorOperations(),
1017 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1018 Toolkit::TextView::Original,
1019 Toolkit::TextView::Original,
1020 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1021 Toolkit::TextView::Left,
1023 std::string( "..." ),
1025 mVisualParameters(),
1027 mRelayoutOperations( NO_RELAYOUT ),
1028 mOffscreenRootActor(),
1029 mOffscreenImageActor(),
1030 mOffscreenCameraActor(),
1031 mCurrentOffscreenSize(),
1032 mFrameBufferImage(),
1034 mPanGestureDetector(),
1035 mLockPreviousSnapshotMode( false ),
1036 mPreviousSnapshotModeEnabled( false ),
1037 mMarkUpEnabled( false )
1039 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1040 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1043 TextView::~TextView()
1045 // Destroys offscreen rendering resources.
1046 DestroyOffscreenRenderingResources();
1048 // Destroys scroll pan gesture detector.
1049 if( mPanGestureDetector )
1051 mPanGestureDetector.Reset();
1055 Vector3 TextView::GetNaturalSize()
1057 if( !mTextViewProcessorOperations.empty() )
1059 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1061 if( !mRelayoutData.mGlyphActors.empty() )
1063 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1064 // add them to the text-actor cache.
1065 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1066 mRelayoutData.mGlyphActors.clear();
1068 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1069 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1072 PerformTextViewProcessorOperations();
1075 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1078 float TextView::GetHeightForWidth( float width )
1082 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1083 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1084 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1086 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1087 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1088 height = GetNaturalSize().height;
1092 // Check if the given width is different than the current one.
1093 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1095 // Check if the text-view has glyph-actors.
1096 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1098 // Check which layout operations need to be done.
1099 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1101 if( relayoutSizeAndPositionNeeded )
1103 if( hasGlyphActors )
1105 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1106 // add them to the text-actor cache.
1107 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1108 mRelayoutData.mGlyphActors.clear();
1111 // Use the given width.
1112 const Vector2 textViewSize( width, GetControlSize().height );
1114 // Relays-out but doesn't add glyph-actors to the text-view.
1115 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1118 // Retrieve the text height after relayout the text.
1119 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1121 if( differentWidth )
1123 // Revert the relayout operation mask
1124 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1127 if( hasGlyphActors )
1129 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1130 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1133 if( differentWidth || hasGlyphActors )
1142 float TextView::GetWidthForHeight( float height )
1144 // TODO: Needs implementing properly, for now just return the natural width.
1145 return GetNaturalSize().width;
1149 void TextView::OnInitialize()
1154 void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
1156 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1157 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1158 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1160 SetText( mCurrentStyledText );
1163 void TextView::OnControlSizeSet( const Vector3& size )
1165 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1167 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1168 mRelayoutOperations = RELAYOUT_ALL;
1170 // Request to be relaid out
1175 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1177 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1179 // Not worth to relayout if width or height is equal to zero.
1183 if( size != mRelayoutData.mTextViewSize )
1185 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1186 if( RELAYOUT_ALL != mRelayoutOperations )
1188 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1189 RELAYOUT_REMOVE_TEXT_ACTORS |
1190 RELAYOUT_SIZE_POSITION |
1191 RELAYOUT_ALIGNMENT |
1192 RELAYOUT_VISIBILITY |
1193 RELAYOUT_TEXT_ACTOR_UPDATE |
1194 RELAYOUT_INSERT_TO_TEXT_VIEW |
1195 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1199 // Remove glyph-actors from text-view
1200 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1202 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1203 mRelayoutData.mGlyphActors.clear();
1206 if( NO_RELAYOUT != mRelayoutOperations )
1208 // Relays-out and add glyph-actors to the text-view.
1209 DoRelayOut( size, mRelayoutOperations );
1210 ProcessSnapshot( size );
1213 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1214 mRelayoutData.mTextActorCache.ClearTexts();
1217 void TextView::PerformTextViewProcessorOperations()
1219 // Traverse the relayout operation vector ...
1221 // Optimizes some operations.
1222 OptimizeTextViewProcessorOperations();
1224 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1226 const TextViewProcessorMetadata& relayoutMetadata( *it );
1228 switch( relayoutMetadata.mType )
1230 case TextView::TextSet:
1232 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1237 case TextView::TextInserted:
1239 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1240 relayoutMetadata.mText,
1245 case TextView::TextReplaced:
1247 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1248 relayoutMetadata.mNumberOfCharacters,
1249 relayoutMetadata.mText,
1254 case TextView::TextRemoved:
1256 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1257 relayoutMetadata.mNumberOfCharacters,
1260 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1263 case TextView::NewLineHeight:
1265 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1266 mRelayoutData.mTextLayoutInfo );
1269 case TextView::NewStyle:
1271 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1272 relayoutMetadata.mStyleMask,
1279 // Clear all operations when they are done.
1280 mTextViewProcessorOperations.clear();
1283 void TextView::OptimizeTextViewProcessorOperations()
1285 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1287 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1288 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1289 // use the cache without clearing the text-actors.
1291 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1293 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1295 const TextViewProcessorMetadata& relayoutMetadata( *it );
1297 switch( relayoutMetadata.mType )
1299 case TextView::TextRemoved:
1301 bool optimizationDone = false;
1303 if( it + 1 != endIt )
1305 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1306 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1308 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1310 optimizationDone = true;
1311 TextViewProcessorMetadata newRelayoutMetadata;
1312 newRelayoutMetadata.mType = TextView::TextReplaced;
1313 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1314 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1315 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1316 textViewProcessorOperations.push_back( newRelayoutMetadata );
1318 // do not access the TextInserted operation in next iteration.
1324 if( !optimizationDone )
1326 textViewProcessorOperations.push_back( relayoutMetadata );
1332 textViewProcessorOperations.push_back( relayoutMetadata );
1337 mTextViewProcessorOperations = textViewProcessorOperations;
1340 void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask )
1342 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1343 if( !mTextViewProcessorOperations.empty() )
1345 PerformTextViewProcessorOperations();
1348 CombineExceedPolicies();
1351 if( mVisualParameters.mSnapshotModeEnabled )
1353 rootActor = mOffscreenRootActor;
1360 mRelayoutData.mTextViewSize = textViewSize;
1361 switch( mLayoutParameters.mMultilinePolicy )
1363 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1365 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1367 } // SplitByNewLineChar
1369 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1371 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1375 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1377 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1380 } // switch( mMultilinePolicy )
1382 // Remove done operations from the mask.
1383 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1386 void TextView::ProcessSnapshot( const Size& textViewSize )
1388 if( mVisualParameters.mSnapshotModeEnabled )
1390 // If layout options change, it's needed generate a new image.
1392 if( mOffscreenRootActor )
1394 // Set the root actor visible.
1395 // The root actor is set to non visible after the render task is processed.
1396 mOffscreenRootActor.SetVisible( true );
1398 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1399 mOffscreenRootActor.SetSize( textViewSize );
1402 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1403 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1405 // Set the image actor visible.
1406 // The image actor is set to non visible if there is no text to render.
1407 mOffscreenImageActor.SetVisible( true );
1409 // Calculates the offscreen image's size. It takes into account different points:
1410 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1411 // * There is a maximum texture size the graphic subsystem can load on the memory.
1412 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1414 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1415 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1416 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1417 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1419 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1423 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1424 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1425 offscreenSize.height,
1428 // Stores current text-view size to avoid create new Dali resources if text changes.
1429 mCurrentOffscreenSize = offscreenSize;
1431 if( !mOffscreenCameraActor )
1433 // Creates a new camera actor.
1434 mOffscreenCameraActor = CameraActor::New();
1435 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1436 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1437 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1439 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1441 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1444 // Calculate camera parameters for current text size.
1445 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1448 if( mVisualParameters.mScrollEnabled )
1450 // Updates the offscreen camera position with the new scroll offset.
1451 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1452 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1456 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1457 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1462 // Creates a new render task.
1463 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1465 mRenderTask.SetSourceActor( mOffscreenRootActor );
1466 mRenderTask.SetInputEnabled( false );
1467 mRenderTask.SetClearColor( Color::TRANSPARENT );
1468 mRenderTask.SetClearEnabled( true );
1469 mRenderTask.SetExclusive( true );
1471 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1472 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1477 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1478 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1481 // Process the render task only once every time the text changes or the text-view's size canges.
1482 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1486 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1487 mOffscreenImageActor.SetVisible( false );
1492 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1494 float xPosition = 0.f;
1495 float yPosition = 0.f;
1496 Vector3 parentOrigin = ParentOrigin::CENTER;
1497 Vector3 anchorPoint = AnchorPoint::CENTER;
1499 switch( mLayoutParameters.mHorizontalAlignment )
1501 case Toolkit::Alignment::HorizontalLeft:
1503 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1504 parentOrigin.x = 0.f;
1505 anchorPoint.x = 0.f;
1508 case Toolkit::Alignment::HorizontalCenter:
1513 case Toolkit::Alignment::HorizontalRight:
1515 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1516 parentOrigin.x = 1.f;
1517 anchorPoint.x = 1.f;
1522 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1526 switch( mLayoutParameters.mVerticalAlignment )
1528 case Toolkit::Alignment::VerticalTop:
1530 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1531 parentOrigin.y = 0.f;
1532 anchorPoint.y = 0.f;
1535 case Toolkit::Alignment::VerticalCenter:
1540 case Toolkit::Alignment::VerticalBottom:
1542 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1543 parentOrigin.y = 1.f;
1544 anchorPoint.y = 1.f;
1549 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1553 mOffscreenCameraActor.SetX( xPosition );
1554 mOffscreenCameraActor.SetY( yPosition );
1556 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1557 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1560 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1562 // not to process the offscreen root actor by setting its visibility to false.
1563 mOffscreenRootActor.SetVisible( false );
1565 // Sets the new size and the new frame buffer to the image actor.
1566 // Image actor must have same size as text. Otherwise text can be truncated.
1567 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1568 mOffscreenImageActor.SetImage( mFrameBufferImage );
1571 void TextView::DestroyOffscreenRenderingResources()
1575 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1577 if( Stage::IsInstalled() )
1579 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1582 mRenderTask.Reset();
1585 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1586 if( mOffscreenCameraActor )
1588 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1590 mOffscreenCameraActor.Reset();
1593 if( mOffscreenRootActor )
1595 mOffscreenRootActor.Reset();
1598 if( mOffscreenImageActor )
1600 mOffscreenImageActor.Reset();
1603 mCurrentOffscreenSize = Size( 0.f, 0.f );
1605 if( mFrameBufferImage )
1607 mFrameBufferImage.Reset();
1611 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1613 if( 1u == gesture.numberOfTouches )
1615 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1619 void TextView::TrimScrollPosition()
1621 const Vector3& textViewSize = GetControlSize();
1623 // Before use the text's size, relayout the text is needed to get the actual text size.
1624 GetTextLayoutInfo();
1626 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1627 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1628 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1629 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1630 float minVerticalDisplacement = -maxVerticalDisplacement;
1632 // Updates the range if the text is aligned on the right or left.
1633 switch( mLayoutParameters.mHorizontalAlignment )
1635 case Toolkit::Alignment::HorizontalLeft:
1637 maxHorizontalDisplacement *= 2.f;
1638 minHorizontalDisplacement = 0.f;
1641 case Toolkit::Alignment::HorizontalCenter:
1646 case Toolkit::Alignment::HorizontalRight:
1648 maxHorizontalDisplacement = 0.f;
1649 minHorizontalDisplacement *= 2.f;
1654 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1658 // Updates the range if the text is aligned on the top or bottom.
1659 switch( mLayoutParameters.mVerticalAlignment )
1661 case Toolkit::Alignment::VerticalTop:
1663 maxVerticalDisplacement *= 2.f;
1664 minVerticalDisplacement = 0.f;
1667 case Toolkit::Alignment::VerticalCenter:
1672 case Toolkit::Alignment::VerticalBottom:
1674 maxVerticalDisplacement = 0.f;
1675 minVerticalDisplacement *= 2.f;
1680 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1684 // Trims the scroll position to be within the range.
1685 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1686 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1688 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1689 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1692 void TextView::DoSetScrollPosition( const Vector2& position )
1694 // Stores old scroll position.
1695 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1697 // Updates the scroll position
1698 mVisualParameters.mCameraScrollPosition = position;
1700 // Ensures the text-view is covered with text.
1701 TrimScrollPosition();
1703 // Calculate the difference with the previous scroll position
1704 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1705 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1707 if( mOffscreenRootActor )
1709 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1711 mOffscreenRootActor.SetVisible( true );
1714 if( mOffscreenCameraActor )
1716 // Update the offscreen camera with the new scroll position.
1717 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1718 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1723 // Refresh the render-task.
1724 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1728 Toolkit::TextView handle( GetOwner() );
1729 mScrolledSignalV2.Emit( handle, delta );
1732 void TextView::CombineExceedPolicies()
1734 // Calculates the combination of exceed policies.
1736 switch( mLayoutParameters.mWidthExceedPolicy )
1738 case Toolkit::TextView::Original:
1740 switch( mLayoutParameters.mHeightExceedPolicy )
1742 case Toolkit::TextView::Original:
1744 mLayoutParameters.mExceedPolicy = Original;
1747 case Toolkit::TextView::Fade:
1749 mLayoutParameters.mExceedPolicy = OriginalFade;
1752 case Toolkit::TextView::ShrinkToFit:
1754 mLayoutParameters.mExceedPolicy = OriginalShrink;
1759 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1764 case Toolkit::TextView::Split:
1766 switch( mLayoutParameters.mHeightExceedPolicy )
1768 case Toolkit::TextView::Original:
1770 mLayoutParameters.mExceedPolicy = SplitOriginal;
1773 case Toolkit::TextView::Fade:
1775 mLayoutParameters.mExceedPolicy = SplitFade;
1778 case Toolkit::TextView::ShrinkToFit:
1780 mLayoutParameters.mExceedPolicy = SplitShrink;
1783 case Toolkit::TextView::EllipsizeEnd:
1785 mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd;
1790 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1795 case Toolkit::TextView::Fade:
1797 switch( mLayoutParameters.mHeightExceedPolicy )
1799 case Toolkit::TextView::Original:
1801 mLayoutParameters.mExceedPolicy = FadeOriginal;
1804 case Toolkit::TextView::Fade:
1806 mLayoutParameters.mExceedPolicy = Fade;
1811 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1816 case Toolkit::TextView::ShrinkToFit:
1818 switch( mLayoutParameters.mHeightExceedPolicy )
1820 case Toolkit::TextView::Original:
1822 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1825 case Toolkit::TextView::Fade:
1827 mLayoutParameters.mExceedPolicy = ShrinkFade;
1830 case Toolkit::TextView::ShrinkToFit:
1832 mLayoutParameters.mExceedPolicy = Shrink;
1837 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1842 case Toolkit::TextView::EllipsizeEnd:
1844 switch( mLayoutParameters.mHeightExceedPolicy )
1846 case Toolkit::TextView::Original:
1848 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1851 case Toolkit::TextView::EllipsizeEnd:
1853 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1858 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1865 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1870 Actor TextView::GetRootActor() const
1872 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1876 if( mVisualParameters.mSnapshotModeEnabled )
1878 rootActor = mOffscreenRootActor;
1888 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1890 bool newValue( propertyValue.Get<bool>() );
1891 if( newValue != IsMarkupProcessingEnabled() )
1893 SetMarkupProcessingEnabled( newValue );
1896 // If markup processing has been enabled, Ensure current text is reprocessed.
1897 const std::string& currentText( GetText() );
1898 if( ! currentText.empty() )
1900 SetText( currentText );
1906 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1908 std::string policyName( propertyValue.Get<std::string>() );
1909 if(policyName == "SplitByNewLineChar")
1911 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1913 else if(policyName == "SplitByWord")
1915 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1917 else if(policyName == "SplitByChar")
1919 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1923 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1927 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1929 std::string policyName( propertyValue.Get<std::string>() );
1930 if(policyName == "Original")
1932 SetWidthExceedPolicy(Toolkit::TextView::Original);
1934 else if(policyName == "Fade")
1936 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1938 else if(policyName == "Split")
1940 SetWidthExceedPolicy(Toolkit::TextView::Split);
1942 else if(policyName == "ShrinkToFit")
1944 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1946 else if(policyName == "EllipsizeEnd")
1948 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1952 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1956 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1958 std::string policyName( propertyValue.Get<std::string>() );
1959 if(policyName == "Original")
1961 SetHeightExceedPolicy(Toolkit::TextView::Original);
1963 else if(policyName == "Fade")
1965 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1967 else if(policyName == "Split")
1969 SetHeightExceedPolicy(Toolkit::TextView::Split);
1971 else if(policyName == "ShrinkToFit")
1973 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1977 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1981 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1983 std::string policyName( propertyValue.Get<std::string>() );
1984 if(policyName == "Left")
1986 SetLineJustification(Toolkit::TextView::Left);
1988 else if(policyName == "Center")
1990 SetLineJustification(Toolkit::TextView::Center);
1992 else if(policyName == "Right")
1994 SetLineJustification(Toolkit::TextView::Right);
1996 else if(policyName == "Justified")
1998 SetLineJustification(Toolkit::TextView::Justified);
2002 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2006 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
2008 Vector4 value( propertyValue.Get<Vector4>() );
2009 DALI_ASSERT_ALWAYS( value.x >= 0 && value.y >= 0 && value.z >= 0 && value.w >= 0
2010 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2012 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2013 PixelSize( static_cast<unsigned int>( value.y ) ),
2014 PixelSize( static_cast<unsigned int>( value.z ) ),
2015 PixelSize( static_cast<unsigned int>( value.w ) ) );
2017 SetFadeBoundary( fadeBoundary );
2020 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2022 std::string value( propertyValue.Get<std::string>() );
2024 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2026 if(value == "HorizontalLeft")
2028 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2030 else if( value == "HorizontalCenter")
2032 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2034 else if( value == "HorizontalRight")
2036 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2040 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2043 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2045 if( value == "VerticalTop" )
2047 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2049 else if( value == "VerticalCenter")
2051 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2053 else if( value == "VerticalBottom")
2055 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2059 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2065 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2066 if( RELAYOUT_ALL != mRelayoutOperations )
2068 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2069 RELAYOUT_TEXT_ACTOR_UPDATE |
2070 RELAYOUT_ALIGNMENT |
2071 RELAYOUT_VISIBILITY );
2075 std::string TextView::OnHorizontalAlignmentPropertyGet()
2077 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2079 return "HorizontalLeft";
2081 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2083 return "HorizontalCenter";
2085 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2087 return "HorizontalRight";
2091 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2095 std::string TextView::OnVerticalAlignmentPropertyGet()
2097 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2099 return "VerticalTop";
2101 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2103 return "VerticalCenter";
2105 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2107 return "VerticalBottom";
2111 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2115 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2117 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2121 TextView& textViewImpl( GetImpl( textView ) );
2124 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2126 textViewImpl.OnMarkupEnabledPeopertySet( value );
2129 case Toolkit::TextView::PROPERTY_TEXT:
2131 textViewImpl.SetText( value.Get<std::string>() );
2134 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2136 textViewImpl.OnMultilinePolicyPropertySet( value );
2139 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2141 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2144 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2146 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2149 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2151 textViewImpl.OnLineJustificationPropertySet( value );
2154 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2156 textViewImpl.OnFadeBoundaryPropertySet( value );
2159 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2161 Dali::PointSize pointSize( value.Get<float>() );
2162 textViewImpl.SetLineHeightOffset(pointSize);
2165 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2166 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2168 textViewImpl.OnAlignmentPropertySet( index, value );
2175 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2177 Property::Value value;
2179 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2183 TextView& textViewImpl( GetImpl( textView ) );
2186 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2188 value = textViewImpl.IsMarkupProcessingEnabled();
2191 case Toolkit::TextView::PROPERTY_TEXT:
2193 value = textViewImpl.GetText();
2196 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2198 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2201 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2203 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2206 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2208 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2211 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2213 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2216 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2218 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2219 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2220 static_cast<float>( boundary.mRight.value ),
2221 static_cast<float>( boundary.mTop.value ),
2222 static_cast<float>( boundary.mBottom.value ) );
2225 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2227 value = textViewImpl.GetLineHeightOffset().value;
2230 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2232 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2235 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2237 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2245 } // namespace Internal
2247 } // namespace Toolkit