2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include "text-view-impl.h"
21 #include "split-by-new-line-char-policies.h"
22 #include "split-by-word-policies.h"
23 #include "split-by-char-policies.h"
24 #include "text-view-processor.h"
25 #include "text-view-word-processor.h"
26 #include "relayout-utilities.h"
27 #include "text-view-processor-dbg.h"
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 );
716 self.Add( mOffscreenRootActor );
717 self.Add( mOffscreenImageActor );
718 mOffscreenImageActor.SetScale(Vector3(1.f, -1.f, 1.f));
724 if( mOffscreenRootActor )
726 self.Remove( mOffscreenRootActor );
729 if( mOffscreenImageActor )
731 self.Remove( mOffscreenImageActor );
734 DestroyOffscreenRenderingResources();
737 if( RELAYOUT_ALL != mRelayoutOperations )
739 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
740 RELAYOUT_REMOVE_TEXT_ACTORS |
741 RELAYOUT_TEXT_ACTOR_UPDATE |
742 RELAYOUT_INSERT_TO_TEXT_VIEW |
743 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
749 bool TextView::IsSnapshotModeEnabled() const
751 return mVisualParameters.mSnapshotModeEnabled;
754 void TextView::SetMarkupProcessingEnabled( bool enable )
756 mMarkUpEnabled = enable;
759 bool TextView::IsMarkupProcessingEnabled() const
761 return mMarkUpEnabled;
764 void TextView::SetScrollEnabled( bool enable )
766 if( enable != mVisualParameters.mScrollEnabled )
768 mVisualParameters.mScrollEnabled = enable;
770 if( mVisualParameters.mScrollEnabled )
772 // Offscreen rendering is needed to enable text scroll.
774 // Stores previous value of the snapshot mode.
775 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
778 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
779 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
780 Lock lock( mLockPreviousSnapshotMode );
781 SetSnapshotModeEnabled( true );
784 // Creates the pan gesture detector and attach the text-view.
785 mPanGestureDetector = PanGestureDetector::New();
786 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
787 mPanGestureDetector.Attach( Self() );
791 // Removes the pan gesture detector.
792 if( mPanGestureDetector )
794 mPanGestureDetector.Detach( Self() );
795 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
796 mPanGestureDetector.Reset();
799 // Restores the previous state for snapshot mode.
800 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
805 bool TextView::IsScrollEnabled() const
807 return mVisualParameters.mScrollEnabled;
810 void TextView::SetScrollPosition( const Vector2& position )
812 if( position != mVisualParameters.mCameraScrollPosition )
814 // Guard against destruction during signal emission
815 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
816 Toolkit::TextView handle( GetOwner() );
818 DoSetScrollPosition( position );
820 // Check if the new scroll position has been trimmed.
821 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
825 const Vector2& TextView::GetScrollPosition() const
827 return mVisualParameters.mCameraScrollPosition;
830 bool TextView::IsScrollPositionTrimmed() const
832 return mVisualParameters.mScrollPositionTrimmed;
835 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
837 return mScrolledSignalV2;
840 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
842 Dali::BaseHandle handle( object );
844 bool connected( true );
845 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
847 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
849 textView.ScrolledSignal().Connect( tracker, functor );
853 // signalName does not match any signal
860 TextView::LayoutParameters::LayoutParameters()
861 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
862 mWidthExceedPolicy( Toolkit::TextView::Original ),
863 mHeightExceedPolicy( Toolkit::TextView::Original ),
864 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
865 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
866 mLineJustification( Toolkit::TextView::Left ),
867 mLineHeightOffset( 0.f ),
869 mMarkUpEnabled( false )
871 // Sets ellipsize text
872 MarkupProcessor::StyledTextArray styledEllipsize;
873 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
876 TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy,
877 Toolkit::TextView::ExceedPolicy widthExceedPolicy,
878 Toolkit::TextView::ExceedPolicy heightExceedPolicy,
879 Toolkit::Alignment::Type alignmentType,
880 Toolkit::TextView::LineJustification lineJustification,
881 float lineHeightOffset,
882 const std::string& ellipsizeText,
884 : mMultilinePolicy( multilinePolicy ),
885 mWidthExceedPolicy( widthExceedPolicy ),
886 mHeightExceedPolicy( heightExceedPolicy ),
887 mHorizontalAlignment(),
888 mVerticalAlignment(),
889 mLineJustification( lineJustification ),
890 mLineHeightOffset( lineHeightOffset ),
892 mMarkUpEnabled( markUpEnabled )
895 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
896 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
897 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
898 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
899 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
900 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
902 mHorizontalAlignment = horizontalAlignment;
903 mVerticalAlignment = verticalAlignment;
905 // Sets ellipsize text
906 MarkupProcessor::StyledTextArray styledEllipsize;
907 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
910 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
911 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
912 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
913 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
914 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
915 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
916 mLineJustification( layoutParameters.mLineJustification ),
917 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
918 mEllipsizeText( layoutParameters.mEllipsizeText ),
919 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
923 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
925 mMultilinePolicy = layoutParameters.mMultilinePolicy;
926 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
927 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
928 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
929 mVerticalAlignment = layoutParameters.mVerticalAlignment;
930 mLineJustification = layoutParameters.mLineJustification;
931 mLineHeightOffset = layoutParameters.mLineHeightOffset;
932 mEllipsizeText = layoutParameters.mEllipsizeText;
933 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
938 TextView::VisualParameters::VisualParameters()
940 mSortModifier( 0.f ),
941 mCameraScrollPosition( 0.f, 0.f ),
942 mSnapshotModeEnabled( false ),
943 mScrollEnabled( false ),
944 mScrollPositionTrimmed( false )
948 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
949 : mFadeBoundary( visualParameters.mFadeBoundary ),
950 mSortModifier( visualParameters.mSortModifier ),
951 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
952 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
953 mScrollEnabled( visualParameters.mScrollEnabled ),
954 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
958 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
960 mFadeBoundary = visualParameters.mFadeBoundary;
961 mSortModifier = visualParameters.mSortModifier;
962 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
963 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
964 mScrollEnabled = visualParameters.mScrollEnabled;
965 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
970 TextView::RelayoutData::RelayoutData()
972 mShrinkFactor( 1.f ),
974 mCharacterLogicalToVisualMap(),
975 mCharacterVisualToLogicalMap(),
977 mCharacterLayoutInfoTable(),
979 mTextSizeForRelayoutOption()
983 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
984 : mTextViewSize( relayoutData.mTextViewSize ),
985 mShrinkFactor( relayoutData.mShrinkFactor ),
986 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
987 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
988 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
989 mGlyphActors( relayoutData.mGlyphActors ),
990 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
991 mLines( relayoutData.mLines ),
992 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
996 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
998 mTextViewSize = relayoutData.mTextViewSize;
999 mShrinkFactor = relayoutData.mShrinkFactor;
1000 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
1001 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
1002 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
1003 mGlyphActors = relayoutData.mGlyphActors;
1004 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1005 mLines = relayoutData.mLines;
1006 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1011 TextView::TextView()
1012 : Control( REQUIRES_STYLE_CHANGE_SIGNALS ),
1013 mCurrentStyledText(),
1014 mTextViewProcessorOperations(),
1015 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1016 Toolkit::TextView::Original,
1017 Toolkit::TextView::Original,
1018 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1019 Toolkit::TextView::Left,
1021 std::string( "..." ),
1023 mVisualParameters(),
1025 mRelayoutOperations( NO_RELAYOUT ),
1026 mOffscreenRootActor(),
1027 mOffscreenImageActor(),
1028 mOffscreenCameraActor(),
1029 mCurrentOffscreenSize(),
1030 mFrameBufferImage(),
1032 mPanGestureDetector(),
1033 mLockPreviousSnapshotMode( false ),
1034 mPreviousSnapshotModeEnabled( false ),
1035 mMarkUpEnabled( false )
1037 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1038 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1041 TextView::~TextView()
1043 // Destroys offscreen rendering resources.
1044 DestroyOffscreenRenderingResources();
1046 // Destroys scroll pan gesture detector.
1047 if( mPanGestureDetector )
1049 mPanGestureDetector.Reset();
1053 Vector3 TextView::GetNaturalSize()
1055 if( !mTextViewProcessorOperations.empty() )
1057 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1059 if( !mRelayoutData.mGlyphActors.empty() )
1061 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1062 // add them to the text-actor cache.
1063 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1064 mRelayoutData.mGlyphActors.clear();
1066 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1067 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1070 PerformTextViewProcessorOperations();
1073 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1076 float TextView::GetHeightForWidth( float width )
1080 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1081 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1082 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1084 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1085 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1086 height = GetNaturalSize().height;
1090 // Check if the given width is different than the current one.
1091 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1093 // Check if the text-view has glyph-actors.
1094 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1096 // Check which layout operations need to be done.
1097 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1099 if( relayoutSizeAndPositionNeeded )
1101 if( hasGlyphActors )
1103 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1104 // add them to the text-actor cache.
1105 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1106 mRelayoutData.mGlyphActors.clear();
1109 // Use the given width.
1110 const Vector2 textViewSize( width, GetControlSize().height );
1112 // Relays-out but doesn't add glyph-actors to the text-view.
1113 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1116 // Retrieve the text height after relayout the text.
1117 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1119 if( differentWidth )
1121 // Revert the relayout operation mask
1122 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1125 if( hasGlyphActors )
1127 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1128 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1131 if( differentWidth || hasGlyphActors )
1140 float TextView::GetWidthForHeight( float height )
1142 // TODO: Needs implementing properly, for now just return the natural width.
1143 return GetNaturalSize().width;
1147 void TextView::OnInitialize()
1152 void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
1154 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1155 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1156 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1158 SetText( mCurrentStyledText );
1161 void TextView::OnControlSizeSet( const Vector3& size )
1163 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1165 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1166 mRelayoutOperations = RELAYOUT_ALL;
1168 // Request to be relaid out
1173 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1175 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1177 // Not worth to relayout if width or height is equal to zero.
1181 if( size != mRelayoutData.mTextViewSize )
1183 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1184 if( RELAYOUT_ALL != mRelayoutOperations )
1186 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1187 RELAYOUT_REMOVE_TEXT_ACTORS |
1188 RELAYOUT_SIZE_POSITION |
1189 RELAYOUT_ALIGNMENT |
1190 RELAYOUT_VISIBILITY |
1191 RELAYOUT_TEXT_ACTOR_UPDATE |
1192 RELAYOUT_INSERT_TO_TEXT_VIEW |
1193 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1197 // Remove glyph-actors from text-view
1198 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1200 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1201 mRelayoutData.mGlyphActors.clear();
1204 if( NO_RELAYOUT != mRelayoutOperations )
1206 // Relays-out and add glyph-actors to the text-view.
1207 DoRelayOut( size, mRelayoutOperations );
1208 ProcessSnapshot( size );
1211 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1212 mRelayoutData.mTextActorCache.ClearTexts();
1215 void TextView::PerformTextViewProcessorOperations()
1217 // Traverse the relayout operation vector ...
1219 // Optimizes some operations.
1220 OptimizeTextViewProcessorOperations();
1222 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1224 const TextViewProcessorMetadata& relayoutMetadata( *it );
1226 switch( relayoutMetadata.mType )
1228 case TextView::TextSet:
1230 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1235 case TextView::TextInserted:
1237 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1238 relayoutMetadata.mText,
1243 case TextView::TextReplaced:
1245 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1246 relayoutMetadata.mNumberOfCharacters,
1247 relayoutMetadata.mText,
1252 case TextView::TextRemoved:
1254 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1255 relayoutMetadata.mNumberOfCharacters,
1258 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1261 case TextView::NewLineHeight:
1263 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1264 mRelayoutData.mTextLayoutInfo );
1267 case TextView::NewStyle:
1269 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1270 relayoutMetadata.mStyleMask,
1277 // Clear all operations when they are done.
1278 mTextViewProcessorOperations.clear();
1281 void TextView::OptimizeTextViewProcessorOperations()
1283 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1285 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1286 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1287 // use the cache without clearing the text-actors.
1289 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1291 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1293 const TextViewProcessorMetadata& relayoutMetadata( *it );
1295 switch( relayoutMetadata.mType )
1297 case TextView::TextRemoved:
1299 bool optimizationDone = false;
1301 if( it + 1 != endIt )
1303 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1304 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1306 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1308 optimizationDone = true;
1309 TextViewProcessorMetadata newRelayoutMetadata;
1310 newRelayoutMetadata.mType = TextView::TextReplaced;
1311 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1312 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1313 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1314 textViewProcessorOperations.push_back( newRelayoutMetadata );
1316 // do not access the TextInserted operation in next iteration.
1322 if( !optimizationDone )
1324 textViewProcessorOperations.push_back( relayoutMetadata );
1330 textViewProcessorOperations.push_back( relayoutMetadata );
1335 mTextViewProcessorOperations = textViewProcessorOperations;
1338 void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask )
1340 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1341 if( !mTextViewProcessorOperations.empty() )
1343 PerformTextViewProcessorOperations();
1346 CombineExceedPolicies();
1349 if( mVisualParameters.mSnapshotModeEnabled )
1351 rootActor = mOffscreenRootActor;
1358 mRelayoutData.mTextViewSize = textViewSize;
1359 switch( mLayoutParameters.mMultilinePolicy )
1361 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1363 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1365 } // SplitByNewLineChar
1367 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1369 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1373 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1375 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1378 } // switch( mMultilinePolicy )
1380 // Remove done operations from the mask.
1381 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1384 void TextView::ProcessSnapshot( const Size& textViewSize )
1386 if( mVisualParameters.mSnapshotModeEnabled )
1388 // If layout options change, it's needed generate a new image.
1390 if( mOffscreenRootActor )
1392 // Set the root actor visible.
1393 // The root actor is set to non visible after the render task is processed.
1394 mOffscreenRootActor.SetVisible( true );
1396 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1397 mOffscreenRootActor.SetSize( textViewSize );
1400 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1401 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1403 // Set the image actor visible.
1404 // The image actor is set to non visible if there is no text to render.
1405 mOffscreenImageActor.SetVisible( true );
1407 // Calculates the offscreen image's size. It takes into account different points:
1408 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1409 // * There is a maximum texture size the graphic subsystem can load on the memory.
1410 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1412 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1413 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1414 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1415 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1417 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1421 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1422 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1423 offscreenSize.height,
1426 // Stores current text-view size to avoid create new Dali resources if text changes.
1427 mCurrentOffscreenSize = offscreenSize;
1429 if( !mOffscreenCameraActor )
1431 // Creates a new camera actor.
1432 mOffscreenCameraActor = CameraActor::New();
1433 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1434 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1435 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1437 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1439 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1442 // Calculate camera parameters for current text size.
1443 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1446 if( mVisualParameters.mScrollEnabled )
1448 // Updates the offscreen camera position with the new scroll offset.
1449 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1450 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1454 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1455 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1460 // Creates a new render task.
1461 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1463 mRenderTask.SetSourceActor( mOffscreenRootActor );
1464 mRenderTask.SetInputEnabled( false );
1465 mRenderTask.SetClearColor( Color::TRANSPARENT );
1466 mRenderTask.SetClearEnabled( true );
1467 mRenderTask.SetExclusive( true );
1469 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1470 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1475 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1476 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1479 // Process the render task only once every time the text changes or the text-view's size canges.
1480 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1484 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1485 mOffscreenImageActor.SetVisible( false );
1490 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1492 float xPosition = 0.f;
1493 float yPosition = 0.f;
1494 Vector3 parentOrigin = ParentOrigin::CENTER;
1495 Vector3 anchorPoint = AnchorPoint::CENTER;
1497 switch( mLayoutParameters.mHorizontalAlignment )
1499 case Toolkit::Alignment::HorizontalLeft:
1501 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1502 parentOrigin.x = 0.f;
1503 anchorPoint.x = 0.f;
1506 case Toolkit::Alignment::HorizontalCenter:
1511 case Toolkit::Alignment::HorizontalRight:
1513 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1514 parentOrigin.x = 1.f;
1515 anchorPoint.x = 1.f;
1520 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1524 switch( mLayoutParameters.mVerticalAlignment )
1526 case Toolkit::Alignment::VerticalTop:
1528 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1529 parentOrigin.y = 0.f;
1530 anchorPoint.y = 0.f;
1533 case Toolkit::Alignment::VerticalCenter:
1538 case Toolkit::Alignment::VerticalBottom:
1540 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1541 parentOrigin.y = 1.f;
1542 anchorPoint.y = 1.f;
1547 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1551 mOffscreenCameraActor.SetX( xPosition );
1552 mOffscreenCameraActor.SetY( yPosition );
1554 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1555 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1558 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1560 // not to process the offscreen root actor by setting its visibility to false.
1561 mOffscreenRootActor.SetVisible( false );
1563 // Sets the new size and the new frame buffer to the image actor.
1564 // Image actor must have same size as text. Otherwise text can be truncated.
1565 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1566 mOffscreenImageActor.SetImage( mFrameBufferImage );
1569 void TextView::DestroyOffscreenRenderingResources()
1573 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1575 if( Stage::IsInstalled() )
1577 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1580 mRenderTask.Reset();
1583 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1584 if( mOffscreenCameraActor )
1586 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1588 mOffscreenCameraActor.Reset();
1591 if( mOffscreenRootActor )
1593 mOffscreenRootActor.Reset();
1596 if( mOffscreenImageActor )
1598 mOffscreenImageActor.Reset();
1601 mCurrentOffscreenSize = Size( 0.f, 0.f );
1603 if( mFrameBufferImage )
1605 mFrameBufferImage.Reset();
1609 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1611 if( 1u == gesture.numberOfTouches )
1613 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1617 void TextView::TrimScrollPosition()
1619 const Vector3& textViewSize = GetControlSize();
1621 // Before use the text's size, relayout the text is needed to get the actual text size.
1622 GetTextLayoutInfo();
1624 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1625 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1626 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1627 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1628 float minVerticalDisplacement = -maxVerticalDisplacement;
1630 // Updates the range if the text is aligned on the right or left.
1631 switch( mLayoutParameters.mHorizontalAlignment )
1633 case Toolkit::Alignment::HorizontalLeft:
1635 maxHorizontalDisplacement *= 2.f;
1636 minHorizontalDisplacement = 0.f;
1639 case Toolkit::Alignment::HorizontalCenter:
1644 case Toolkit::Alignment::HorizontalRight:
1646 maxHorizontalDisplacement = 0.f;
1647 minHorizontalDisplacement *= 2.f;
1652 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1656 // Updates the range if the text is aligned on the top or bottom.
1657 switch( mLayoutParameters.mVerticalAlignment )
1659 case Toolkit::Alignment::VerticalTop:
1661 maxVerticalDisplacement *= 2.f;
1662 minVerticalDisplacement = 0.f;
1665 case Toolkit::Alignment::VerticalCenter:
1670 case Toolkit::Alignment::VerticalBottom:
1672 maxVerticalDisplacement = 0.f;
1673 minVerticalDisplacement *= 2.f;
1678 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1682 // Trims the scroll position to be within the range.
1683 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1684 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1686 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1687 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1690 void TextView::DoSetScrollPosition( const Vector2& position )
1692 // Stores old scroll position.
1693 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1695 // Updates the scroll position
1696 mVisualParameters.mCameraScrollPosition = position;
1698 // Ensures the text-view is covered with text.
1699 TrimScrollPosition();
1701 // Calculate the difference with the previous scroll position
1702 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1703 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1705 if( mOffscreenRootActor )
1707 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1709 mOffscreenRootActor.SetVisible( true );
1712 if( mOffscreenCameraActor )
1714 // Update the offscreen camera with the new scroll position.
1715 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1716 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1721 // Refresh the render-task.
1722 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1726 Toolkit::TextView handle( GetOwner() );
1727 mScrolledSignalV2.Emit( handle, delta );
1730 void TextView::CombineExceedPolicies()
1732 // Calculates the combination of exceed policies.
1734 switch( mLayoutParameters.mWidthExceedPolicy )
1736 case Toolkit::TextView::Original:
1738 switch( mLayoutParameters.mHeightExceedPolicy )
1740 case Toolkit::TextView::Original:
1742 mLayoutParameters.mExceedPolicy = Original;
1745 case Toolkit::TextView::Fade:
1747 mLayoutParameters.mExceedPolicy = OriginalFade;
1750 case Toolkit::TextView::ShrinkToFit:
1752 mLayoutParameters.mExceedPolicy = OriginalShrink;
1757 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1762 case Toolkit::TextView::Split:
1764 switch( mLayoutParameters.mHeightExceedPolicy )
1766 case Toolkit::TextView::Original:
1768 mLayoutParameters.mExceedPolicy = SplitOriginal;
1771 case Toolkit::TextView::Fade:
1773 mLayoutParameters.mExceedPolicy = SplitFade;
1776 case Toolkit::TextView::ShrinkToFit:
1778 mLayoutParameters.mExceedPolicy = SplitShrink;
1781 case Toolkit::TextView::EllipsizeEnd:
1783 mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd;
1788 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1793 case Toolkit::TextView::Fade:
1795 switch( mLayoutParameters.mHeightExceedPolicy )
1797 case Toolkit::TextView::Original:
1799 mLayoutParameters.mExceedPolicy = FadeOriginal;
1802 case Toolkit::TextView::Fade:
1804 mLayoutParameters.mExceedPolicy = Fade;
1809 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1814 case Toolkit::TextView::ShrinkToFit:
1816 switch( mLayoutParameters.mHeightExceedPolicy )
1818 case Toolkit::TextView::Original:
1820 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1823 case Toolkit::TextView::Fade:
1825 mLayoutParameters.mExceedPolicy = ShrinkFade;
1828 case Toolkit::TextView::ShrinkToFit:
1830 mLayoutParameters.mExceedPolicy = Shrink;
1835 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1840 case Toolkit::TextView::EllipsizeEnd:
1842 switch( mLayoutParameters.mHeightExceedPolicy )
1844 case Toolkit::TextView::Original:
1846 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1849 case Toolkit::TextView::EllipsizeEnd:
1851 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1856 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1863 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1868 Actor TextView::GetRootActor() const
1870 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1874 if( mVisualParameters.mSnapshotModeEnabled )
1876 rootActor = mOffscreenRootActor;
1886 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1888 bool newValue( propertyValue.Get<bool>() );
1889 if( newValue != IsMarkupProcessingEnabled() )
1891 SetMarkupProcessingEnabled( newValue );
1894 // If markup processing has been enabled, Ensure current text is reprocessed.
1895 const std::string& currentText( GetText() );
1896 if( ! currentText.empty() )
1898 SetText( currentText );
1904 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1906 std::string policyName( propertyValue.Get<std::string>() );
1907 if(policyName == "SplitByNewLineChar")
1909 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1911 else if(policyName == "SplitByWord")
1913 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1915 else if(policyName == "SplitByChar")
1917 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1921 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1925 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1927 std::string policyName( propertyValue.Get<std::string>() );
1928 if(policyName == "Original")
1930 SetWidthExceedPolicy(Toolkit::TextView::Original);
1932 else if(policyName == "Truncate")
1934 SetWidthExceedPolicy(Toolkit::TextView::Truncate);
1936 else if(policyName == "Fade")
1938 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1940 else if(policyName == "Split")
1942 SetWidthExceedPolicy(Toolkit::TextView::Split);
1944 else if(policyName == "ShrinkToFit")
1946 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1948 else if(policyName == "EllipsizeEnd")
1950 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1954 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1958 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1960 std::string policyName( propertyValue.Get<std::string>() );
1961 if(policyName == "Original")
1963 SetHeightExceedPolicy(Toolkit::TextView::Original);
1965 else if(policyName == "Truncate")
1967 SetHeightExceedPolicy(Toolkit::TextView::Truncate);
1969 else if(policyName == "Fade")
1971 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1973 else if(policyName == "Split")
1975 SetHeightExceedPolicy(Toolkit::TextView::Split);
1977 else if(policyName == "ShrinkToFit")
1979 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1983 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1987 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1989 std::string policyName( propertyValue.Get<std::string>() );
1990 if(policyName == "Left")
1992 SetLineJustification(Toolkit::TextView::Left);
1994 else if(policyName == "Center")
1996 SetLineJustification(Toolkit::TextView::Center);
1998 else if(policyName == "Right")
2000 SetLineJustification(Toolkit::TextView::Right);
2002 else if(policyName == "Justified")
2004 SetLineJustification(Toolkit::TextView::Justified);
2008 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2012 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
2014 Vector4 value( propertyValue.Get<Vector4>() );
2015 DALI_ASSERT_ALWAYS( value.x >= 0 && value.y >= 0 && value.z >= 0 && value.w >= 0
2016 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2018 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2019 PixelSize( static_cast<unsigned int>( value.y ) ),
2020 PixelSize( static_cast<unsigned int>( value.z ) ),
2021 PixelSize( static_cast<unsigned int>( value.w ) ) );
2023 SetFadeBoundary( fadeBoundary );
2026 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2028 std::string value( propertyValue.Get<std::string>() );
2030 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2032 if(value == "HorizontalLeft")
2034 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2036 else if( value == "HorizontalCenter")
2038 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2040 else if( value == "HorizontalRight")
2042 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2046 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2049 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2051 if( value == "VerticalTop" )
2053 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2055 else if( value == "VerticalCenter")
2057 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2059 else if( value == "VerticalBottom")
2061 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2065 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2071 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2072 if( RELAYOUT_ALL != mRelayoutOperations )
2074 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2075 RELAYOUT_TEXT_ACTOR_UPDATE |
2076 RELAYOUT_ALIGNMENT |
2077 RELAYOUT_VISIBILITY );
2081 std::string TextView::OnHorizontalAlignmentPropertyGet()
2083 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2085 return "HorizontalLeft";
2087 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2089 return "HorizontalCenter";
2091 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2093 return "HorizontalRight";
2097 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2101 std::string TextView::OnVerticalAlignmentPropertyGet()
2103 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2105 return "VerticalTop";
2107 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2109 return "VerticalCenter";
2111 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2113 return "VerticalBottom";
2117 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2121 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2123 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2127 TextView& textViewImpl( GetImpl( textView ) );
2130 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2132 textViewImpl.OnMarkupEnabledPeopertySet( value );
2135 case Toolkit::TextView::PROPERTY_TEXT:
2137 textViewImpl.SetText( value.Get<std::string>() );
2140 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2142 textViewImpl.OnMultilinePolicyPropertySet( value );
2145 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2147 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2150 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2152 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2155 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2157 textViewImpl.OnLineJustificationPropertySet( value );
2160 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2162 textViewImpl.OnFadeBoundaryPropertySet( value );
2165 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2167 Dali::PointSize pointSize( value.Get<float>() );
2168 textViewImpl.SetLineHeightOffset(pointSize);
2171 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2172 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2174 textViewImpl.OnAlignmentPropertySet( index, value );
2181 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2183 Property::Value value;
2185 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2189 TextView& textViewImpl( GetImpl( textView ) );
2192 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2194 value = textViewImpl.IsMarkupProcessingEnabled();
2197 case Toolkit::TextView::PROPERTY_TEXT:
2199 value = textViewImpl.GetText();
2202 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2204 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2207 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2209 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2212 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2214 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2217 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2219 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2222 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2224 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2225 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2226 static_cast<float>( boundary.mRight.value ),
2227 static_cast<float>( boundary.mTop.value ),
2228 static_cast<float>( boundary.mBottom.value ) );
2231 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2233 value = textViewImpl.GetLineHeightOffset().value;
2236 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2238 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2241 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2243 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2251 } // namespace Internal
2253 } // namespace Toolkit