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 );
53 const char* MULTILINE_POLICY_NAME[] = {"SplitByNewLineChar", "SplitByWord", "SplitByChar"};
54 const char* EXCEED_POLICY_NAME[] = {"Original", "Truncate", "Fade", "Split","ShrinkToFit","EllipsizeEnd"};
55 const char* LINE_JUSTIFICATION_NAME[] = {"Left","Center","Right","Justified"};
57 // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
58 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
63 return Toolkit::TextView::New();
66 TypeRegistration typeRegistration( typeid(Toolkit::TextView), typeid(Toolkit::Control), Create );
68 SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal );
70 PropertyRegistration property1( typeRegistration, "markup-enabled", Toolkit::TextView::PROPERTY_MARKUP_ENABLED, Property::BOOLEAN, &TextView::SetProperty, &TextView::GetProperty );
71 PropertyRegistration property2( typeRegistration, "text", Toolkit::TextView::PROPERTY_TEXT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
72 PropertyRegistration property3( typeRegistration, "multiline-policy", Toolkit::TextView::PROPERTY_MULTILINE_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
73 PropertyRegistration property4( typeRegistration, "width-exceed-policy", Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
74 PropertyRegistration property5( typeRegistration, "height-exceed-policy", Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
75 PropertyRegistration property6( typeRegistration, "line-justification", Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
76 PropertyRegistration property7( typeRegistration, "fade-boundary", Toolkit::TextView::PROPERTY_FADE_BOUNDARY, Property::VECTOR4, &TextView::SetProperty, &TextView::GetProperty );
77 PropertyRegistration property8( typeRegistration, "line-height-offset", Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET, Property::FLOAT, &TextView::SetProperty, &TextView::GetProperty );
78 PropertyRegistration property9( typeRegistration, "horizontal-alignment", Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
79 PropertyRegistration property10( typeRegistration, "vertical-alignment", Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
82 * Whether the text-view-processor operation sets, inserts, replaces, removes text.
84 * @param[in] metadata The text-view-processor operation.
86 * @return \e true if the given text-view-processor operation is modifying the text.
88 bool IsTextViewProcessorRelayoutOperation( const TextView::TextViewProcessorMetadata& metadata )
90 return ( ( metadata.mType == TextView::TextSet ) ||
91 ( metadata.mType == TextView::TextInserted ) ||
92 ( metadata.mType == TextView::TextReplaced ) ||
93 ( metadata.mType == TextView::TextRemoved ) ||
94 ( metadata.mType == TextView::NewStyle ));
98 * Whether the text-view-processor operation sets a new line height offset.
100 * @param[in] metadata The text-view-processor operation.
102 * @return \e true if the given text-view-processor operation sets a new line height offset.
104 bool IsTextViewProcessorLineHeightOffsetOperation( const TextView::TextViewProcessorMetadata& metadata )
106 return ( metadata.mType == TextView::NewLineHeight );
110 * Whether the text-view-processor operation sets a new style.
112 * @param[in] metadata The text-view-processor operation.
114 * @return \e true if the given text-view-processor operation sets a new style.
116 bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMetadata& metadata )
118 return ( metadata.mType == TextView::NewStyle );
123 TextView::TextViewProcessorMetadata::TextViewProcessorMetadata()
124 : mType( TextView::TextSet ),
126 mNumberOfCharacters( 0 ),
131 Toolkit::TextView TextView::New()
133 // Create the implementation, temporarily owned on stack
134 IntrusivePtr<TextView> textView = new TextView();
136 // Pass ownership to CustomActor
137 Toolkit::TextView handle( *textView );
139 // Second-phase init of the implementation
140 // This can only be done after the CustomActor connection has been made...
141 textView->Initialize();
143 // Enables by default the offscreen rendering.
144 textView->SetSnapshotModeEnabled( false ); /// @note Temporary disabled due to some issues with text quality and glyph loading.
149 void TextView::SetText( const std::string& text )
151 // Creates a styled text with the markup or plain string.
152 MarkupProcessor::StyledTextArray styledText;
153 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
155 // Calls SetText() with the styled text array.
156 SetText( styledText );
159 void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
161 // mTextViewProcessorOperations stores the InsertTextAt and RemoveTextFrom operations to transform the initial text to mCurrentStyledText.
162 // Once again, if a new text is set, any previous call to InsertTextAt or RemoveTextFrom can be discarted.
164 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorRelayoutOperation );
165 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
167 // Creates metadata with the Set operation.
168 TextViewProcessorMetadata metadata;
169 metadata.mType = TextView::TextSet;
170 metadata.mText = text;
173 mTextViewProcessorOperations.push_back( metadata );
175 // Updates current styled text.
176 mCurrentStyledText = text;
178 // Request to be relaid out
181 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
182 mRelayoutOperations = RELAYOUT_ALL;
185 void TextView::InsertTextAt( std::size_t position, const std::string& text )
187 // Creates a styled text with the markup or plain string.
188 MarkupProcessor::StyledTextArray styledText;
189 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
191 // Calls InsertTextAt() with the styled text array.
192 InsertTextAt( position, styledText );
195 void TextView::InsertTextAt( const std::size_t position, const MarkupProcessor::StyledTextArray& text )
197 // Creates metadata with the Insert operation.
198 TextViewProcessorMetadata metadata;
199 metadata.mType = TextView::TextInserted;
200 metadata.mPosition = position;
201 metadata.mText = text;
204 mTextViewProcessorOperations.push_back( metadata );
206 // Updates current styled text.
207 mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
209 // Request to be relaid out
212 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
213 mRelayoutOperations = RELAYOUT_ALL;
216 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const std::string& text )
218 // Creates a styled text with the markup or plain string.
219 MarkupProcessor::StyledTextArray styledText;
220 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
222 // Calls ReplaceTextFromTo() with the styled text array.
223 ReplaceTextFromTo( position, numberOfCharacters, styledText );
226 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
228 // Creates metadata with the Insert operation.
229 TextViewProcessorMetadata metadata;
230 metadata.mType = TextView::TextReplaced;
231 metadata.mPosition = position;
232 metadata.mNumberOfCharacters = numberOfCharacters;
233 metadata.mText = text;
236 mTextViewProcessorOperations.push_back( metadata );
238 // Updates current styled text.
239 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
240 mCurrentStyledText.erase( it, it + numberOfCharacters );
241 it = mCurrentStyledText.begin() + position;
242 mCurrentStyledText.insert( it, text.begin(), text.end() );
244 // Request to be relaid out
247 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
248 mRelayoutOperations = RELAYOUT_ALL;
251 void TextView::RemoveTextFrom( const std::size_t position, const std::size_t numberOfCharacters )
253 // Creates metadata with the Remove operation.
254 TextViewProcessorMetadata metadata;
255 metadata.mType = TextView::TextRemoved;
256 metadata.mPosition = position;
257 metadata.mNumberOfCharacters = numberOfCharacters;
260 mTextViewProcessorOperations.push_back( metadata );
262 // Updates current styled text.
263 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
264 mCurrentStyledText.erase( it, it + numberOfCharacters );
266 // Request to be relaid out
269 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
270 mRelayoutOperations = RELAYOUT_ALL;
273 std::string TextView::GetText() const
275 // Traverses the styled text array getting only the text.
276 // Note that for some languages a 'character' could be represented by more than one 'char'
279 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); it != endIt; ++it )
281 text.append( (*it).mText.GetText() );
287 void TextView::SetLineHeightOffset( const PointSize offset )
289 if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 )
291 // Removes any previous operation which modifies the line height offset.
292 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorLineHeightOffsetOperation );
293 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
295 // Creates metadata with the new line height operation.
296 TextViewProcessorMetadata metadata;
297 metadata.mType = TextView::NewLineHeight;
299 mTextViewProcessorOperations.push_back( metadata );
301 // Updates line height offset.
302 mLayoutParameters.mLineHeightOffset = offset;
306 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
307 if( RELAYOUT_ALL != mRelayoutOperations )
309 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
310 RELAYOUT_REMOVE_TEXT_ACTORS |
311 RELAYOUT_SIZE_POSITION |
313 RELAYOUT_VISIBILITY |
314 RELAYOUT_TEXT_ACTOR_UPDATE |
315 RELAYOUT_INSERT_TO_TEXT_VIEW |
316 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
321 PointSize TextView::GetLineHeightOffset() const
323 return PointSize( mLayoutParameters.mLineHeightOffset );
326 void TextView::SetStyleToCurrentText( const TextStyle& style, const TextStyle::Mask mask )
328 if( !mCurrentStyledText.empty() )
330 const bool checkFontName = mask & TextStyle::FONT;
331 const bool checkFontSize = mask & TextStyle::SIZE;
332 const bool checkFontStyle = mask & TextStyle::STYLE;
334 // Check first if metrics have changed.
335 bool metricsChanged = false;
336 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
338 const MarkupProcessor::StyledText& styledText( *it );
340 metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
341 ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
342 ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
347 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
349 // If metrics change, new text measurements are needed.
350 SetText( mCurrentStyledText );
354 // Deletes any previous operation which sets a new style.
355 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
356 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
358 // Creates metadata with the new style operation.
359 TextViewProcessorMetadata metadata;
360 metadata.mType = TextView::NewStyle;
362 MarkupProcessor::StyledText text;
364 metadata.mText.push_back( text );
365 metadata.mStyleMask = mask;
367 mTextViewProcessorOperations.push_back( metadata );
369 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
373 if( RELAYOUT_ALL != mRelayoutOperations )
375 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
376 RELAYOUT_TEXT_ACTOR_UPDATE );
381 // Sets the new style to the ellipsize text
382 if( !mLayoutParameters.mEllipsizeText.empty() )
384 for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
386 (*it).mStyle.Copy( style, mask );
389 SetEllipsizeText( mLayoutParameters.mEllipsizeText );
393 void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
395 if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
397 Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
398 ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
399 ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
400 Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
401 ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
402 ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
404 mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
405 mLayoutParameters.mVerticalAlignment = verticalAlignment;
409 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
410 if( RELAYOUT_ALL != mRelayoutOperations )
412 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
413 RELAYOUT_TEXT_ACTOR_UPDATE |
415 RELAYOUT_VISIBILITY );
420 Toolkit::Alignment::Type TextView::GetTextAlignment() const
422 return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
425 void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
427 if( policy != mLayoutParameters.mMultilinePolicy )
429 mLayoutParameters.mMultilinePolicy = policy;
431 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
432 mRelayoutOperations = RELAYOUT_ALL;
438 Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
440 return mLayoutParameters.mMultilinePolicy;
443 void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
445 // The layout info could be invalid depending on the current exceed policy and the new one.
446 // i.e. if the current policy is Split and the new one is ShrinkToFit then
447 // the layout info generated for each char is not needed.
448 if( policy != mLayoutParameters.mWidthExceedPolicy )
450 mLayoutParameters.mWidthExceedPolicy = policy;
452 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
453 mRelayoutOperations = RELAYOUT_ALL;
459 Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
461 return mLayoutParameters.mWidthExceedPolicy;
464 void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
466 if( policy != mLayoutParameters.mHeightExceedPolicy )
468 mLayoutParameters.mHeightExceedPolicy = policy;
472 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
473 if( RELAYOUT_ALL != mRelayoutOperations )
475 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
476 RELAYOUT_REMOVE_TEXT_ACTORS |
477 RELAYOUT_SIZE_POSITION |
479 RELAYOUT_VISIBILITY |
480 RELAYOUT_TEXT_ACTOR_UPDATE |
481 RELAYOUT_INSERT_TO_TEXT_VIEW |
482 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
487 Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
489 return mLayoutParameters.mHeightExceedPolicy;
492 void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
494 if( justification != mLayoutParameters.mLineJustification )
496 mLayoutParameters.mLineJustification = justification;
500 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
501 if( RELAYOUT_ALL != mRelayoutOperations )
503 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
504 RELAYOUT_REMOVE_TEXT_ACTORS |
505 RELAYOUT_SIZE_POSITION |
507 RELAYOUT_VISIBILITY |
508 RELAYOUT_TEXT_ACTOR_UPDATE |
509 RELAYOUT_INSERT_TO_TEXT_VIEW |
510 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
515 Toolkit::TextView::LineJustification TextView::GetLineJustification() const
517 return mLayoutParameters.mLineJustification;
520 void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
522 if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
523 ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
524 ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
525 ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
527 mVisualParameters.mFadeBoundary = fadeBoundary;
531 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
532 if( RELAYOUT_ALL != mRelayoutOperations )
534 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
535 RELAYOUT_REMOVE_TEXT_ACTORS |
536 RELAYOUT_VISIBILITY |
537 RELAYOUT_TEXT_ACTOR_UPDATE |
538 RELAYOUT_INSERT_TO_TEXT_VIEW |
539 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
544 const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
546 return mVisualParameters.mFadeBoundary;
549 void TextView::SetEllipsizeText( const std::string& ellipsizeText )
551 // Creates a styled text with the markup or plain string.
552 MarkupProcessor::StyledTextArray styledText;
553 MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() );
555 SetEllipsizeText( styledText );
558 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
560 mLayoutParameters.mEllipsizeText = ellipsizeText;
562 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
564 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
565 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
567 // Request to be relaid out
570 mRelayoutOperations = RELAYOUT_ALL;
573 std::string TextView::GetEllipsizeText() const
576 for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
578 text.append( (*it).mText.GetText() );
584 void TextView::GetTextLayoutInfo()
586 const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
587 const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
588 const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
590 if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
592 Vector3 textViewSize = GetControlSize();
594 if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
595 ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
596 ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
597 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
598 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
600 // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
601 // the text natural size can be used.
602 textViewSize = GetNaturalSize();
605 if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
606 ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
608 // Check if the text-view has glyph-actors.
609 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
611 RelayoutOperationMask mask = NO_RELAYOUT;
612 if( relayoutSizeAndPositionNeeded )
614 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
616 if( relayoutAlignmentNeeded )
618 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
620 if( relayoutVisibilityNeeded )
622 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
627 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
628 // add them to the text-actor cache.
629 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
630 mRelayoutData.mGlyphActors.clear();
633 // Relays-out but doesn't add glyph-actors to the text-view.
634 DoRelayOut( textViewSize.GetVectorXY(), mask );
638 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
639 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
646 void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
650 textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
651 textLayoutInfo.mLines = mRelayoutData.mLines;
653 textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
654 textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
656 textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
658 textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
661 void TextView::SetSortModifier( float depthOffset )
663 mVisualParameters.mSortModifier = depthOffset;
665 for( std::vector<RenderableActor>::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.end();
669 ( *it ).SetSortModifier( depthOffset );
672 if( mOffscreenImageActor )
674 mOffscreenImageActor.SetSortModifier( depthOffset );
678 void TextView::SetSnapshotModeEnabled( bool enable )
680 if( enable != mVisualParameters.mSnapshotModeEnabled )
682 // Remove first all glyph-actors
683 if( !mRelayoutData.mGlyphActors.empty() )
685 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
688 mVisualParameters.mSnapshotModeEnabled = enable;
689 if( !mLockPreviousSnapshotMode )
691 // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
692 // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
694 // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
695 // to smash the stored value.
696 mPreviousSnapshotModeEnabled = enable;
699 if( mVisualParameters.mSnapshotModeEnabled )
701 // Create a root actor and an image actor for offscreen rendering.
702 mOffscreenRootActor = Layer::New();
703 mOffscreenImageActor = ImageActor::New();
705 mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
706 mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
707 mOffscreenRootActor.SetInheritRotation( false );
708 mOffscreenRootActor.SetInheritScale( false );
709 mOffscreenRootActor.SetDepthTestDisabled( true );
711 mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
713 mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
714 mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
717 self.Add( mOffscreenRootActor );
718 self.Add( mOffscreenImageActor );
719 mOffscreenImageActor.SetScale(Vector3(1.f, -1.f, 1.f));
725 if( mOffscreenRootActor )
727 self.Remove( mOffscreenRootActor );
730 if( mOffscreenImageActor )
732 self.Remove( mOffscreenImageActor );
735 DestroyOffscreenRenderingResources();
738 if( RELAYOUT_ALL != mRelayoutOperations )
740 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
741 RELAYOUT_REMOVE_TEXT_ACTORS |
742 RELAYOUT_TEXT_ACTOR_UPDATE |
743 RELAYOUT_INSERT_TO_TEXT_VIEW |
744 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
750 bool TextView::IsSnapshotModeEnabled() const
752 return mVisualParameters.mSnapshotModeEnabled;
755 void TextView::SetMarkupProcessingEnabled( bool enable )
757 mMarkUpEnabled = enable;
760 bool TextView::IsMarkupProcessingEnabled() const
762 return mMarkUpEnabled;
765 void TextView::SetScrollEnabled( const bool enable )
767 if( enable != mVisualParameters.mScrollEnabled )
769 mVisualParameters.mScrollEnabled = enable;
771 if( mVisualParameters.mScrollEnabled )
773 // Offscreen rendering is needed to enable text scroll.
775 // Stores previous value of the snapshot mode.
776 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
779 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
780 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
781 Lock lock( mLockPreviousSnapshotMode );
782 SetSnapshotModeEnabled( true );
785 // Creates the pan gesture detector and attach the text-view.
786 mPanGestureDetector = PanGestureDetector::New();
787 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
788 mPanGestureDetector.Attach( Self() );
792 // Removes the pan gesture detector.
793 if( mPanGestureDetector )
795 mPanGestureDetector.Detach( Self() );
796 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
797 mPanGestureDetector.Reset();
800 // Restores the previous state for snapshot mode.
801 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
806 bool TextView::IsScrollEnabled() const
808 return mVisualParameters.mScrollEnabled;
811 void TextView::SetScrollPosition( const Vector2& position )
813 if( position != mVisualParameters.mCameraScrollPosition )
815 // Guard against destruction during signal emission
816 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
817 Toolkit::TextView handle( GetOwner() );
819 DoSetScrollPosition( position );
821 // Check if the new scroll position has been trimmed.
822 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
826 const Vector2& TextView::GetScrollPosition() const
828 return mVisualParameters.mCameraScrollPosition;
831 bool TextView::IsScrollPositionTrimmed() const
833 return mVisualParameters.mScrollPositionTrimmed;
836 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
838 return mScrolledSignalV2;
841 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
843 Dali::BaseHandle handle( object );
845 bool connected( true );
846 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
848 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
850 textView.ScrolledSignal().Connect( tracker, functor );
854 // signalName does not match any signal
861 TextView::LayoutParameters::LayoutParameters()
862 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
863 mWidthExceedPolicy( Toolkit::TextView::Original ),
864 mHeightExceedPolicy( Toolkit::TextView::Original ),
865 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
866 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
867 mLineJustification( Toolkit::TextView::Left ),
868 mLineHeightOffset( 0.f ),
870 mMarkUpEnabled( false )
872 // Sets ellipsize text
873 MarkupProcessor::StyledTextArray styledEllipsize;
874 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
877 TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::MultilinePolicy multilinePolicy,
878 const Toolkit::TextView::ExceedPolicy widthExceedPolicy,
879 const Toolkit::TextView::ExceedPolicy heightExceedPolicy,
880 const Toolkit::Alignment::Type alignmentType,
881 const Toolkit::TextView::LineJustification lineJustification,
882 const float lineHeightOffset,
883 const std::string& ellipsizeText,
884 const bool markUpEnabled )
885 : mMultilinePolicy( multilinePolicy ),
886 mWidthExceedPolicy( widthExceedPolicy ),
887 mHeightExceedPolicy( heightExceedPolicy ),
888 mHorizontalAlignment(),
889 mVerticalAlignment(),
890 mLineJustification( lineJustification ),
891 mLineHeightOffset( lineHeightOffset ),
893 mMarkUpEnabled( markUpEnabled )
896 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
897 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
898 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
899 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
900 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
901 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
903 mHorizontalAlignment = horizontalAlignment;
904 mVerticalAlignment = verticalAlignment;
906 // Sets ellipsize text
907 MarkupProcessor::StyledTextArray styledEllipsize;
908 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
911 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
912 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
913 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
914 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
915 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
916 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
917 mLineJustification( layoutParameters.mLineJustification ),
918 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
919 mEllipsizeText( layoutParameters.mEllipsizeText ),
920 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
924 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
926 mMultilinePolicy = layoutParameters.mMultilinePolicy;
927 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
928 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
929 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
930 mVerticalAlignment = layoutParameters.mVerticalAlignment;
931 mLineJustification = layoutParameters.mLineJustification;
932 mLineHeightOffset = layoutParameters.mLineHeightOffset;
933 mEllipsizeText = layoutParameters.mEllipsizeText;
934 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
939 TextView::VisualParameters::VisualParameters()
941 mSortModifier( 0.f ),
942 mCameraScrollPosition( 0.f, 0.f ),
943 mSnapshotModeEnabled( false ),
944 mScrollEnabled( false ),
945 mScrollPositionTrimmed( false )
949 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
950 : mFadeBoundary( visualParameters.mFadeBoundary ),
951 mSortModifier( visualParameters.mSortModifier ),
952 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
953 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
954 mScrollEnabled( visualParameters.mScrollEnabled ),
955 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
959 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
961 mFadeBoundary = visualParameters.mFadeBoundary;
962 mSortModifier = visualParameters.mSortModifier;
963 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
964 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
965 mScrollEnabled = visualParameters.mScrollEnabled;
966 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
971 TextView::RelayoutData::RelayoutData()
973 mShrinkFactor( 1.f ),
975 mCharacterLogicalToVisualMap(),
976 mCharacterVisualToLogicalMap(),
978 mCharacterLayoutInfoTable(),
980 mTextSizeForRelayoutOption()
984 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
985 : mTextViewSize( relayoutData.mTextViewSize ),
986 mShrinkFactor( relayoutData.mShrinkFactor ),
987 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
988 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
989 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
990 mGlyphActors( relayoutData.mGlyphActors ),
991 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
992 mLines( relayoutData.mLines ),
993 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
997 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
999 mTextViewSize = relayoutData.mTextViewSize;
1000 mShrinkFactor = relayoutData.mShrinkFactor;
1001 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
1002 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
1003 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
1004 mGlyphActors = relayoutData.mGlyphActors;
1005 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1006 mLines = relayoutData.mLines;
1007 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1012 TextView::TextView()
1013 : ControlImpl( false ), // doesn't require touch events
1014 mCurrentStyledText(),
1015 mTextViewProcessorOperations(),
1016 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1017 Toolkit::TextView::Original,
1018 Toolkit::TextView::Original,
1019 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1020 Toolkit::TextView::Left,
1022 std::string( "..." ),
1024 mVisualParameters(),
1026 mRelayoutOperations( NO_RELAYOUT ),
1027 mOffscreenRootActor(),
1028 mOffscreenImageActor(),
1029 mOffscreenCameraActor(),
1030 mCurrentOffscreenSize(),
1031 mFrameBufferImage(),
1033 mPanGestureDetector(),
1034 mLockPreviousSnapshotMode( false ),
1035 mPreviousSnapshotModeEnabled( false ),
1036 mMarkUpEnabled( false )
1038 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1039 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1042 TextView::~TextView()
1044 // Destroys offscreen rendering resources.
1045 DestroyOffscreenRenderingResources();
1047 // Destroys scroll pan gesture detector.
1048 if( mPanGestureDetector )
1050 mPanGestureDetector.Reset();
1054 Vector3 TextView::GetNaturalSize()
1056 if( !mTextViewProcessorOperations.empty() )
1058 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1060 if( !mRelayoutData.mGlyphActors.empty() )
1062 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1063 // add them to the text-actor cache.
1064 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1065 mRelayoutData.mGlyphActors.clear();
1067 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1068 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1071 PerformTextViewProcessorOperations();
1074 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1077 float TextView::GetHeightForWidth( float width )
1081 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1082 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1083 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1085 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1086 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1087 height = GetNaturalSize().height;
1091 // Check if the given width is different than the current one.
1092 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1094 // Check if the text-view has glyph-actors.
1095 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1097 // Check which layout operations need to be done.
1098 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1100 if( relayoutSizeAndPositionNeeded )
1102 if( hasGlyphActors )
1104 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1105 // add them to the text-actor cache.
1106 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1107 mRelayoutData.mGlyphActors.clear();
1110 // Use the given width.
1111 const Vector2 textViewSize( width, GetControlSize().height );
1113 // Relays-out but doesn't add glyph-actors to the text-view.
1114 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1117 // Retrieve the text height after relayout the text.
1118 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1120 if( differentWidth )
1122 // Revert the relayout operation mask
1123 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1126 if( hasGlyphActors )
1128 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1129 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1132 if( differentWidth || hasGlyphActors )
1141 float TextView::GetWidthForHeight( float height )
1143 // TODO: Needs implementing properly, for now just return the natural width.
1144 return GetNaturalSize().width;
1148 void TextView::OnInitialize()
1153 void TextView::OnStyleChange( StyleChange change )
1155 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1156 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1157 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1159 SetText( mCurrentStyledText );
1162 void TextView::OnControlSizeSet( const Vector3& size )
1164 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1166 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1167 mRelayoutOperations = RELAYOUT_ALL;
1169 // Request to be relaid out
1174 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1176 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1178 // Not worth to relayout if width or height is equal to zero.
1182 if( size != mRelayoutData.mTextViewSize )
1184 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1185 if( RELAYOUT_ALL != mRelayoutOperations )
1187 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1188 RELAYOUT_REMOVE_TEXT_ACTORS |
1189 RELAYOUT_SIZE_POSITION |
1190 RELAYOUT_ALIGNMENT |
1191 RELAYOUT_VISIBILITY |
1192 RELAYOUT_TEXT_ACTOR_UPDATE |
1193 RELAYOUT_INSERT_TO_TEXT_VIEW |
1194 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1198 // Remove glyph-actors from text-view
1199 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1201 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1202 mRelayoutData.mGlyphActors.clear();
1205 if( NO_RELAYOUT != mRelayoutOperations )
1207 // Relays-out and add glyph-actors to the text-view.
1208 DoRelayOut( size, mRelayoutOperations );
1209 ProcessSnapshot( size );
1212 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1213 mRelayoutData.mTextActorCache.ClearTexts();
1216 void TextView::PerformTextViewProcessorOperations()
1218 // Traverse the relayout operation vector ...
1220 // Optimizes some operations.
1221 OptimizeTextViewProcessorOperations();
1223 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1225 const TextViewProcessorMetadata& relayoutMetadata( *it );
1227 switch( relayoutMetadata.mType )
1229 case TextView::TextSet:
1231 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1236 case TextView::TextInserted:
1238 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1239 relayoutMetadata.mText,
1244 case TextView::TextReplaced:
1246 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1247 relayoutMetadata.mNumberOfCharacters,
1248 relayoutMetadata.mText,
1253 case TextView::TextRemoved:
1255 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1256 relayoutMetadata.mNumberOfCharacters,
1259 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1262 case TextView::NewLineHeight:
1264 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1265 mRelayoutData.mTextLayoutInfo );
1268 case TextView::NewStyle:
1270 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1271 relayoutMetadata.mStyleMask,
1278 // Clear all operations when they are done.
1279 mTextViewProcessorOperations.clear();
1282 void TextView::OptimizeTextViewProcessorOperations()
1284 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1286 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1287 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1288 // use the cache without clearing the text-actors.
1290 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1292 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1294 const TextViewProcessorMetadata& relayoutMetadata( *it );
1296 switch( relayoutMetadata.mType )
1298 case TextView::TextRemoved:
1300 bool optimizationDone = false;
1302 if( it + 1 != endIt )
1304 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1305 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1307 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1309 optimizationDone = true;
1310 TextViewProcessorMetadata newRelayoutMetadata;
1311 newRelayoutMetadata.mType = TextView::TextReplaced;
1312 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1313 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1314 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1315 textViewProcessorOperations.push_back( newRelayoutMetadata );
1317 // do not access the TextInserted operation in next iteration.
1323 if( !optimizationDone )
1325 textViewProcessorOperations.push_back( relayoutMetadata );
1331 textViewProcessorOperations.push_back( relayoutMetadata );
1336 mTextViewProcessorOperations = textViewProcessorOperations;
1339 void TextView::DoRelayOut( const Size& textViewSize, const RelayoutOperationMask relayoutOperationMask )
1341 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1342 if( !mTextViewProcessorOperations.empty() )
1344 PerformTextViewProcessorOperations();
1347 CombineExceedPolicies();
1350 if( mVisualParameters.mSnapshotModeEnabled )
1352 rootActor = mOffscreenRootActor;
1359 mRelayoutData.mTextViewSize = textViewSize;
1360 switch( mLayoutParameters.mMultilinePolicy )
1362 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1364 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1366 } // SplitByNewLineChar
1368 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1370 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1374 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1376 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1379 } // switch( mMultilinePolicy )
1381 // Remove done operations from the mask.
1382 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1385 void TextView::ProcessSnapshot( const Size& textViewSize )
1387 if( mVisualParameters.mSnapshotModeEnabled )
1389 // If layout options change, it's needed generate a new image.
1391 if( mOffscreenRootActor )
1393 // Set the root actor visible.
1394 // The root actor is set to non visible after the render task is processed.
1395 mOffscreenRootActor.SetVisible( true );
1397 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1398 mOffscreenRootActor.SetSize( textViewSize );
1401 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1402 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1404 // Set the image actor visible.
1405 // The image actor is set to non visible if there is no text to render.
1406 mOffscreenImageActor.SetVisible( true );
1408 // Calculates the offscreen image's size. It takes into account different points:
1409 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1410 // * There is a maximum texture size the graphic subsystem can load on the memory.
1411 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1413 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1414 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1415 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1416 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1418 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1422 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1423 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1424 offscreenSize.height,
1427 // Stores current text-view size to avoid create new Dali resources if text changes.
1428 mCurrentOffscreenSize = offscreenSize;
1430 if( !mOffscreenCameraActor )
1432 // Creates a new camera actor.
1433 mOffscreenCameraActor = CameraActor::New();
1434 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1435 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1436 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1438 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1440 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1443 // Calculate camera parameters for current text size.
1444 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1447 if( mVisualParameters.mScrollEnabled )
1449 // Updates the offscreen camera position with the new scroll offset.
1450 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1451 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1455 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1456 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1461 // Creates a new render task.
1462 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1464 mRenderTask.SetSourceActor( mOffscreenRootActor );
1465 mRenderTask.SetInputEnabled( false );
1466 mRenderTask.SetClearColor( Color::TRANSPARENT );
1467 mRenderTask.SetClearEnabled( true );
1468 mRenderTask.SetExclusive( true );
1470 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1471 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1476 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1477 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1480 // Process the render task only once every time the text changes or the text-view's size canges.
1481 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1485 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1486 mOffscreenImageActor.SetVisible( false );
1491 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1493 float xPosition = 0.f;
1494 float yPosition = 0.f;
1495 Vector3 parentOrigin = ParentOrigin::CENTER;
1496 Vector3 anchorPoint = AnchorPoint::CENTER;
1498 switch( mLayoutParameters.mHorizontalAlignment )
1500 case Toolkit::Alignment::HorizontalLeft:
1502 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1503 parentOrigin.x = 0.f;
1504 anchorPoint.x = 0.f;
1507 case Toolkit::Alignment::HorizontalCenter:
1512 case Toolkit::Alignment::HorizontalRight:
1514 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1515 parentOrigin.x = 1.f;
1516 anchorPoint.x = 1.f;
1521 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1525 switch( mLayoutParameters.mVerticalAlignment )
1527 case Toolkit::Alignment::VerticalTop:
1529 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1530 parentOrigin.y = 0.f;
1531 anchorPoint.y = 0.f;
1534 case Toolkit::Alignment::VerticalCenter:
1539 case Toolkit::Alignment::VerticalBottom:
1541 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1542 parentOrigin.y = 1.f;
1543 anchorPoint.y = 1.f;
1548 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1552 mOffscreenCameraActor.SetX( xPosition );
1553 mOffscreenCameraActor.SetY( yPosition );
1555 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1556 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1559 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1561 // not to process the offscreen root actor by setting its visibility to false.
1562 mOffscreenRootActor.SetVisible( false );
1564 // Sets the new size and the new frame buffer to the image actor.
1565 // Image actor must have same size as text. Otherwise text can be truncated.
1566 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1567 mOffscreenImageActor.SetImage( mFrameBufferImage );
1570 void TextView::DestroyOffscreenRenderingResources()
1574 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1576 if( Stage::IsInstalled() )
1578 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1581 mRenderTask.Reset();
1584 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1585 if( mOffscreenCameraActor )
1587 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1589 mOffscreenCameraActor.Reset();
1592 if( mOffscreenRootActor )
1594 mOffscreenRootActor.Reset();
1597 if( mOffscreenImageActor )
1599 mOffscreenImageActor.Reset();
1602 mCurrentOffscreenSize = Size( 0.f, 0.f );
1604 if( mFrameBufferImage )
1606 mFrameBufferImage.Reset();
1610 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1612 if( 1u == gesture.numberOfTouches )
1614 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1618 void TextView::TrimScrollPosition()
1620 const Vector3& textViewSize = GetControlSize();
1622 // Before use the text's size, relayout the text is needed to get the actual text size.
1623 GetTextLayoutInfo();
1625 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1626 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1627 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1628 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1629 float minVerticalDisplacement = -maxVerticalDisplacement;
1631 // Updates the range if the text is aligned on the right or left.
1632 switch( mLayoutParameters.mHorizontalAlignment )
1634 case Toolkit::Alignment::HorizontalLeft:
1636 maxHorizontalDisplacement *= 2.f;
1637 minHorizontalDisplacement = 0.f;
1640 case Toolkit::Alignment::HorizontalCenter:
1645 case Toolkit::Alignment::HorizontalRight:
1647 maxHorizontalDisplacement = 0.f;
1648 minHorizontalDisplacement *= 2.f;
1653 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1657 // Updates the range if the text is aligned on the top or bottom.
1658 switch( mLayoutParameters.mVerticalAlignment )
1660 case Toolkit::Alignment::VerticalTop:
1662 maxVerticalDisplacement *= 2.f;
1663 minVerticalDisplacement = 0.f;
1666 case Toolkit::Alignment::VerticalCenter:
1671 case Toolkit::Alignment::VerticalBottom:
1673 maxVerticalDisplacement = 0.f;
1674 minVerticalDisplacement *= 2.f;
1679 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1683 // Trims the scroll position to be within the range.
1684 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1685 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1687 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1688 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1691 void TextView::DoSetScrollPosition( const Vector2& position )
1693 // Stores old scroll position.
1694 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1696 // Updates the scroll position
1697 mVisualParameters.mCameraScrollPosition = position;
1699 // Ensures the text-view is covered with text.
1700 TrimScrollPosition();
1702 // Calculate the difference with the previous scroll position
1703 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1704 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1706 if( mOffscreenRootActor )
1708 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1710 mOffscreenRootActor.SetVisible( true );
1713 if( mOffscreenCameraActor )
1715 // Update the offscreen camera with the new scroll position.
1716 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1717 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1722 // Refresh the render-task.
1723 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1727 Toolkit::TextView handle( GetOwner() );
1728 mScrolledSignalV2.Emit( handle, delta );
1731 void TextView::CombineExceedPolicies()
1733 // Calculates the combination of exceed policies.
1735 switch( mLayoutParameters.mWidthExceedPolicy )
1737 case Toolkit::TextView::Original:
1739 switch( mLayoutParameters.mHeightExceedPolicy )
1741 case Toolkit::TextView::Original:
1743 mLayoutParameters.mExceedPolicy = Original;
1746 case Toolkit::TextView::Fade:
1748 mLayoutParameters.mExceedPolicy = OriginalFade;
1751 case Toolkit::TextView::ShrinkToFit:
1753 mLayoutParameters.mExceedPolicy = OriginalShrink;
1758 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1763 case Toolkit::TextView::Split:
1765 switch( mLayoutParameters.mHeightExceedPolicy )
1767 case Toolkit::TextView::Original:
1769 mLayoutParameters.mExceedPolicy = SplitOriginal;
1772 case Toolkit::TextView::Fade:
1774 mLayoutParameters.mExceedPolicy = SplitFade;
1777 case Toolkit::TextView::ShrinkToFit:
1779 mLayoutParameters.mExceedPolicy = SplitShrink;
1784 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1789 case Toolkit::TextView::Fade:
1791 switch( mLayoutParameters.mHeightExceedPolicy )
1793 case Toolkit::TextView::Original:
1795 mLayoutParameters.mExceedPolicy = FadeOriginal;
1798 case Toolkit::TextView::Fade:
1800 mLayoutParameters.mExceedPolicy = Fade;
1805 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1810 case Toolkit::TextView::ShrinkToFit:
1812 switch( mLayoutParameters.mHeightExceedPolicy )
1814 case Toolkit::TextView::Original:
1816 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1819 case Toolkit::TextView::Fade:
1821 mLayoutParameters.mExceedPolicy = ShrinkFade;
1824 case Toolkit::TextView::ShrinkToFit:
1826 mLayoutParameters.mExceedPolicy = Shrink;
1831 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1836 case Toolkit::TextView::EllipsizeEnd:
1838 switch( mLayoutParameters.mHeightExceedPolicy )
1840 case Toolkit::TextView::Original:
1842 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1845 case Toolkit::TextView::EllipsizeEnd:
1847 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1852 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1859 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1864 Actor TextView::GetRootActor() const
1866 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1870 if( mVisualParameters.mSnapshotModeEnabled )
1872 rootActor = mOffscreenRootActor;
1882 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1884 bool newValue( propertyValue.Get<bool>() );
1885 if( newValue != IsMarkupProcessingEnabled() )
1887 SetMarkupProcessingEnabled( newValue );
1890 // If markup processing has been enabled, Ensure current text is reprocessed.
1891 const std::string& currentText( GetText() );
1892 if( ! currentText.empty() )
1894 SetText( currentText );
1900 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1902 std::string policyName( propertyValue.Get<std::string>() );
1903 if(policyName == "SplitByNewLineChar")
1905 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1907 else if(policyName == "SplitByWord")
1909 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1911 else if(policyName == "SplitByChar")
1913 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1917 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1921 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1923 std::string policyName( propertyValue.Get<std::string>() );
1924 if(policyName == "Original")
1926 SetWidthExceedPolicy(Toolkit::TextView::Original);
1928 else if(policyName == "Truncate")
1930 SetWidthExceedPolicy(Toolkit::TextView::Truncate);
1932 else if(policyName == "Fade")
1934 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1936 else if(policyName == "Split")
1938 SetWidthExceedPolicy(Toolkit::TextView::Split);
1940 else if(policyName == "ShrinkToFit")
1942 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1944 else if(policyName == "EllipsizeEnd")
1946 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1950 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1954 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1956 std::string policyName( propertyValue.Get<std::string>() );
1957 if(policyName == "Original")
1959 SetHeightExceedPolicy(Toolkit::TextView::Original);
1961 else if(policyName == "Truncate")
1963 SetHeightExceedPolicy(Toolkit::TextView::Truncate);
1965 else if(policyName == "Fade")
1967 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1969 else if(policyName == "Split")
1971 SetHeightExceedPolicy(Toolkit::TextView::Split);
1973 else if(policyName == "ShrinkToFit")
1975 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1979 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1983 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1985 std::string policyName( propertyValue.Get<std::string>() );
1986 if(policyName == "Left")
1988 SetLineJustification(Toolkit::TextView::Left);
1990 else if(policyName == "Center")
1992 SetLineJustification(Toolkit::TextView::Center);
1994 else if(policyName == "Right")
1996 SetLineJustification(Toolkit::TextView::Right);
1998 else if(policyName == "Justified")
2000 SetLineJustification(Toolkit::TextView::Justified);
2004 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2008 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
2010 Vector4 value( propertyValue.Get<Vector4>() );
2011 DALI_ASSERT_ALWAYS( value.x >= 0 && value.y >= 0 && value.z >= 0 && value.w >= 0
2012 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2014 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2015 PixelSize( static_cast<unsigned int>( value.y ) ),
2016 PixelSize( static_cast<unsigned int>( value.z ) ),
2017 PixelSize( static_cast<unsigned int>( value.w ) ) );
2019 SetFadeBoundary( fadeBoundary );
2022 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2024 std::string value( propertyValue.Get<std::string>() );
2026 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2028 if(value == "HorizontalLeft")
2030 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2032 else if( value == "HorizontalCenter")
2034 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2036 else if( value == "HorizontalRight")
2038 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2042 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2045 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2047 if( value == "VerticalTop" )
2049 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2051 else if( value == "VerticalCenter")
2053 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2055 else if( value == "VerticalBottom")
2057 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2061 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2067 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2068 if( RELAYOUT_ALL != mRelayoutOperations )
2070 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2071 RELAYOUT_TEXT_ACTOR_UPDATE |
2072 RELAYOUT_ALIGNMENT |
2073 RELAYOUT_VISIBILITY );
2077 std::string TextView::OnHorizontalAlignmentPropertyGet()
2079 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2081 return "HorizontalLeft";
2083 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2085 return "HorizontalCenter";
2087 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2089 return "HorizontalRight";
2093 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2097 std::string TextView::OnVerticalAlignmentPropertyGet()
2099 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2101 return "VerticalTop";
2103 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2105 return "VerticalCenter";
2107 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2109 return "VerticalBottom";
2113 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2117 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2119 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2123 TextView& textViewImpl( GetImpl( textView ) );
2126 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2128 textViewImpl.OnMarkupEnabledPeopertySet( value );
2131 case Toolkit::TextView::PROPERTY_TEXT:
2133 textViewImpl.SetText( value.Get<std::string>() );
2136 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2138 textViewImpl.OnMultilinePolicyPropertySet( value );
2141 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2143 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2146 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2148 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2151 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2153 textViewImpl.OnLineJustificationPropertySet( value );
2156 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2158 textViewImpl.OnFadeBoundaryPropertySet( value );
2161 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2163 Dali::PointSize pointSize( value.Get<float>() );
2164 textViewImpl.SetLineHeightOffset(pointSize);
2167 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2168 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2170 textViewImpl.OnAlignmentPropertySet( index, value );
2177 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2179 Property::Value value;
2181 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2185 TextView& textViewImpl( GetImpl( textView ) );
2188 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2190 value = textViewImpl.IsMarkupProcessingEnabled();
2193 case Toolkit::TextView::PROPERTY_TEXT:
2195 value = textViewImpl.GetText();
2198 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2200 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2203 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2205 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2208 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2210 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2213 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2215 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2218 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2220 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2221 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2222 static_cast<float>( boundary.mRight.value ),
2223 static_cast<float>( boundary.mTop.value ),
2224 static_cast<float>( boundary.mBottom.value ) );
2227 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2229 value = textViewImpl.GetLineHeightOffset().value;
2232 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2234 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2237 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2239 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2247 } // namespace Internal
2249 } // namespace Toolkit