2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "text-view-impl.h"
22 #include "split-by-new-line-char-policies.h"
23 #include "split-by-word-policies.h"
24 #include "split-by-char-policies.h"
25 #include "text-view-processor.h"
26 #include "text-view-word-processor.h"
27 #include "relayout-utilities.h"
28 #include "text-view-processor-dbg.h"
36 const Property::Index TextView::PROPERTY_MARKUP_ENABLED( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX );
37 const Property::Index TextView::PROPERTY_TEXT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 1 );
38 const Property::Index TextView::PROPERTY_MULTILINE_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 2 );
39 const Property::Index TextView::PROPERTY_WIDTH_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 3 );
40 const Property::Index TextView::PROPERTY_HEIGHT_EXCEED_POLICY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 4 );
41 const Property::Index TextView::PROPERTY_LINE_JUSTIFICATION( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 5 );
42 const Property::Index TextView::PROPERTY_FADE_BOUNDARY( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 6 );
43 const Property::Index TextView::PROPERTY_LINE_HEIGHT_OFFSET( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 7 );
44 const Property::Index TextView::PROPERTY_HORIZONTAL_ALIGNMENT( Internal::TextView::TEXTVIEW_PROPERTY_START_INDEX + 8 );
45 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 // Disables by default the offscreen rendering.
144 textView->SetSnapshotModeEnabled( false );
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( 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( std::size_t position, 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( std::size_t position, 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( std::size_t position, 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( 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, 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 );
715 mOffscreenImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
716 BlendingFactor::ONE, BlendingFactor::ONE );
719 self.Add( mOffscreenRootActor );
720 self.Add( mOffscreenImageActor );
721 mOffscreenImageActor.SetScale( Vector3( 1.f, -1.f, 1.f ) );
727 if( mOffscreenRootActor )
729 self.Remove( mOffscreenRootActor );
732 if( mOffscreenImageActor )
734 self.Remove( mOffscreenImageActor );
737 DestroyOffscreenRenderingResources();
740 if( RELAYOUT_ALL != mRelayoutOperations )
742 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
743 RELAYOUT_REMOVE_TEXT_ACTORS |
744 RELAYOUT_TEXT_ACTOR_UPDATE |
745 RELAYOUT_INSERT_TO_TEXT_VIEW |
746 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
752 bool TextView::IsSnapshotModeEnabled() const
754 return mVisualParameters.mSnapshotModeEnabled;
757 void TextView::SetMarkupProcessingEnabled( bool enable )
759 mMarkUpEnabled = enable;
762 bool TextView::IsMarkupProcessingEnabled() const
764 return mMarkUpEnabled;
767 void TextView::SetScrollEnabled( bool enable )
769 if( enable != mVisualParameters.mScrollEnabled )
771 mVisualParameters.mScrollEnabled = enable;
773 if( mVisualParameters.mScrollEnabled )
775 // Offscreen rendering is needed to enable text scroll.
777 // Stores previous value of the snapshot mode.
778 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
781 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
782 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
783 Lock lock( mLockPreviousSnapshotMode );
784 SetSnapshotModeEnabled( true );
787 // Creates the pan gesture detector and attach the text-view.
788 mPanGestureDetector = PanGestureDetector::New();
789 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
790 mPanGestureDetector.Attach( Self() );
794 // Removes the pan gesture detector.
795 if( mPanGestureDetector )
797 mPanGestureDetector.Detach( Self() );
798 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
799 mPanGestureDetector.Reset();
802 // Restores the previous state for snapshot mode.
803 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
808 bool TextView::IsScrollEnabled() const
810 return mVisualParameters.mScrollEnabled;
813 void TextView::SetScrollPosition( const Vector2& position )
815 if( position != mVisualParameters.mCameraScrollPosition )
817 // Guard against destruction during signal emission
818 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
819 Toolkit::TextView handle( GetOwner() );
821 DoSetScrollPosition( position );
823 // Check if the new scroll position has been trimmed.
824 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
828 const Vector2& TextView::GetScrollPosition() const
830 return mVisualParameters.mCameraScrollPosition;
833 bool TextView::IsScrollPositionTrimmed() const
835 return mVisualParameters.mScrollPositionTrimmed;
838 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
840 return mScrolledSignalV2;
843 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
845 Dali::BaseHandle handle( object );
847 bool connected( true );
848 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
850 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
852 textView.ScrolledSignal().Connect( tracker, functor );
856 // signalName does not match any signal
863 TextView::LayoutParameters::LayoutParameters()
864 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
865 mWidthExceedPolicy( Toolkit::TextView::Original ),
866 mHeightExceedPolicy( Toolkit::TextView::Original ),
867 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
868 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
869 mLineJustification( Toolkit::TextView::Left ),
870 mLineHeightOffset( 0.f ),
872 mMarkUpEnabled( false )
874 // Sets ellipsize text
875 MarkupProcessor::StyledTextArray styledEllipsize;
876 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
879 TextView::LayoutParameters::LayoutParameters( Toolkit::TextView::MultilinePolicy multilinePolicy,
880 Toolkit::TextView::ExceedPolicy widthExceedPolicy,
881 Toolkit::TextView::ExceedPolicy heightExceedPolicy,
882 Toolkit::Alignment::Type alignmentType,
883 Toolkit::TextView::LineJustification lineJustification,
884 float lineHeightOffset,
885 const std::string& ellipsizeText,
887 : mMultilinePolicy( multilinePolicy ),
888 mWidthExceedPolicy( widthExceedPolicy ),
889 mHeightExceedPolicy( heightExceedPolicy ),
890 mHorizontalAlignment(),
891 mVerticalAlignment(),
892 mLineJustification( lineJustification ),
893 mLineHeightOffset( lineHeightOffset ),
895 mMarkUpEnabled( markUpEnabled )
898 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
899 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
900 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
901 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
902 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
903 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
905 mHorizontalAlignment = horizontalAlignment;
906 mVerticalAlignment = verticalAlignment;
908 // Sets ellipsize text
909 MarkupProcessor::StyledTextArray styledEllipsize;
910 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
913 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
914 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
915 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
916 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
917 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
918 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
919 mLineJustification( layoutParameters.mLineJustification ),
920 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
921 mEllipsizeText( layoutParameters.mEllipsizeText ),
922 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
926 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
928 mMultilinePolicy = layoutParameters.mMultilinePolicy;
929 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
930 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
931 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
932 mVerticalAlignment = layoutParameters.mVerticalAlignment;
933 mLineJustification = layoutParameters.mLineJustification;
934 mLineHeightOffset = layoutParameters.mLineHeightOffset;
935 mEllipsizeText = layoutParameters.mEllipsizeText;
936 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
941 TextView::VisualParameters::VisualParameters()
943 mSortModifier( 0.f ),
944 mCameraScrollPosition( 0.f, 0.f ),
945 mSnapshotModeEnabled( false ),
946 mScrollEnabled( false ),
947 mScrollPositionTrimmed( false )
951 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
952 : mFadeBoundary( visualParameters.mFadeBoundary ),
953 mSortModifier( visualParameters.mSortModifier ),
954 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
955 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
956 mScrollEnabled( visualParameters.mScrollEnabled ),
957 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
961 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
963 mFadeBoundary = visualParameters.mFadeBoundary;
964 mSortModifier = visualParameters.mSortModifier;
965 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
966 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
967 mScrollEnabled = visualParameters.mScrollEnabled;
968 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
973 TextView::RelayoutData::RelayoutData()
975 mShrinkFactor( 1.f ),
977 mCharacterLogicalToVisualMap(),
978 mCharacterVisualToLogicalMap(),
980 mCharacterLayoutInfoTable(),
982 mTextSizeForRelayoutOption()
986 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
987 : mTextViewSize( relayoutData.mTextViewSize ),
988 mShrinkFactor( relayoutData.mShrinkFactor ),
989 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
990 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
991 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
992 mGlyphActors( relayoutData.mGlyphActors ),
993 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
994 mLines( relayoutData.mLines ),
995 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
999 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
1001 mTextViewSize = relayoutData.mTextViewSize;
1002 mShrinkFactor = relayoutData.mShrinkFactor;
1003 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
1004 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
1005 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
1006 mGlyphActors = relayoutData.mGlyphActors;
1007 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1008 mLines = relayoutData.mLines;
1009 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1014 TextView::TextView()
1015 : Control( REQUIRES_STYLE_CHANGE_SIGNALS ),
1016 mCurrentStyledText(),
1017 mTextViewProcessorOperations(),
1018 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1019 Toolkit::TextView::Original,
1020 Toolkit::TextView::Original,
1021 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1022 Toolkit::TextView::Left,
1024 std::string( "..." ),
1026 mVisualParameters(),
1028 mRelayoutOperations( NO_RELAYOUT ),
1029 mOffscreenRootActor(),
1030 mOffscreenImageActor(),
1031 mOffscreenCameraActor(),
1032 mCurrentOffscreenSize(),
1033 mFrameBufferImage(),
1035 mPanGestureDetector(),
1036 mLockPreviousSnapshotMode( false ),
1037 mPreviousSnapshotModeEnabled( false ),
1038 mMarkUpEnabled( false )
1040 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1041 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1044 TextView::~TextView()
1046 // Destroys offscreen rendering resources.
1047 DestroyOffscreenRenderingResources();
1049 // Destroys scroll pan gesture detector.
1050 if( mPanGestureDetector )
1052 mPanGestureDetector.Reset();
1056 Vector3 TextView::GetNaturalSize()
1058 if( !mTextViewProcessorOperations.empty() )
1060 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1062 if( !mRelayoutData.mGlyphActors.empty() )
1064 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1065 // add them to the text-actor cache.
1066 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1067 mRelayoutData.mGlyphActors.clear();
1069 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1070 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1073 PerformTextViewProcessorOperations();
1076 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1079 float TextView::GetHeightForWidth( float width )
1083 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1084 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1085 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1087 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1088 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1089 height = GetNaturalSize().height;
1093 // Check if the given width is different than the current one.
1094 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1096 // Check if the text-view has glyph-actors.
1097 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1099 // Check which layout operations need to be done.
1100 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1102 if( relayoutSizeAndPositionNeeded )
1104 if( hasGlyphActors )
1106 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1107 // add them to the text-actor cache.
1108 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1109 mRelayoutData.mGlyphActors.clear();
1112 // Use the given width.
1113 const Vector2 textViewSize( width, GetControlSize().height );
1115 // Relays-out but doesn't add glyph-actors to the text-view.
1116 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1119 // Retrieve the text height after relayout the text.
1120 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1122 if( differentWidth )
1124 // Revert the relayout operation mask
1125 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1128 if( hasGlyphActors )
1130 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1131 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1134 if( differentWidth || hasGlyphActors )
1143 float TextView::GetWidthForHeight( float height )
1145 // TODO: Needs implementing properly, for now just return the natural width.
1146 return GetNaturalSize().width;
1150 void TextView::OnInitialize()
1155 void TextView::OnFontChange( bool defaultFontChange, bool defaultFontSizeChange )
1157 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1158 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1159 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1161 SetText( mCurrentStyledText );
1164 void TextView::OnControlSizeSet( const Vector3& size )
1166 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1168 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1169 mRelayoutOperations = RELAYOUT_ALL;
1171 // Request to be relaid out
1176 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1178 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1180 // Not worth to relayout if width or height is equal to zero.
1184 if( size != mRelayoutData.mTextViewSize )
1186 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1187 if( RELAYOUT_ALL != mRelayoutOperations )
1189 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1190 RELAYOUT_REMOVE_TEXT_ACTORS |
1191 RELAYOUT_SIZE_POSITION |
1192 RELAYOUT_ALIGNMENT |
1193 RELAYOUT_VISIBILITY |
1194 RELAYOUT_TEXT_ACTOR_UPDATE |
1195 RELAYOUT_INSERT_TO_TEXT_VIEW |
1196 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1200 // Remove glyph-actors from text-view
1201 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1203 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1204 mRelayoutData.mGlyphActors.clear();
1207 if( NO_RELAYOUT != mRelayoutOperations )
1209 // Relays-out and add glyph-actors to the text-view.
1210 DoRelayOut( size, mRelayoutOperations );
1211 ProcessSnapshot( size );
1214 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1215 mRelayoutData.mTextActorCache.ClearTexts();
1218 void TextView::PerformTextViewProcessorOperations()
1220 // Traverse the relayout operation vector ...
1222 // Optimizes some operations.
1223 OptimizeTextViewProcessorOperations();
1225 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1227 const TextViewProcessorMetadata& relayoutMetadata( *it );
1229 switch( relayoutMetadata.mType )
1231 case TextView::TextSet:
1233 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1238 case TextView::TextInserted:
1240 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1241 relayoutMetadata.mText,
1246 case TextView::TextReplaced:
1248 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1249 relayoutMetadata.mNumberOfCharacters,
1250 relayoutMetadata.mText,
1255 case TextView::TextRemoved:
1257 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1258 relayoutMetadata.mNumberOfCharacters,
1261 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1264 case TextView::NewLineHeight:
1266 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1267 mRelayoutData.mTextLayoutInfo );
1270 case TextView::NewStyle:
1272 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1273 relayoutMetadata.mStyleMask,
1280 // Clear all operations when they are done.
1281 mTextViewProcessorOperations.clear();
1284 void TextView::OptimizeTextViewProcessorOperations()
1286 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1288 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1289 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1290 // use the cache without clearing the text-actors.
1292 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1294 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1296 const TextViewProcessorMetadata& relayoutMetadata( *it );
1298 switch( relayoutMetadata.mType )
1300 case TextView::TextRemoved:
1302 bool optimizationDone = false;
1304 if( it + 1 != endIt )
1306 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1307 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1309 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1311 optimizationDone = true;
1312 TextViewProcessorMetadata newRelayoutMetadata;
1313 newRelayoutMetadata.mType = TextView::TextReplaced;
1314 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1315 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1316 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1317 textViewProcessorOperations.push_back( newRelayoutMetadata );
1319 // do not access the TextInserted operation in next iteration.
1325 if( !optimizationDone )
1327 textViewProcessorOperations.push_back( relayoutMetadata );
1333 textViewProcessorOperations.push_back( relayoutMetadata );
1338 mTextViewProcessorOperations = textViewProcessorOperations;
1341 void TextView::DoRelayOut( const Size& textViewSize, RelayoutOperationMask relayoutOperationMask )
1343 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1344 if( !mTextViewProcessorOperations.empty() )
1346 PerformTextViewProcessorOperations();
1349 CombineExceedPolicies();
1352 if( mVisualParameters.mSnapshotModeEnabled )
1354 rootActor = mOffscreenRootActor;
1361 mRelayoutData.mTextViewSize = textViewSize;
1362 switch( mLayoutParameters.mMultilinePolicy )
1364 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1366 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1368 } // SplitByNewLineChar
1370 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1372 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1376 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1378 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1381 } // switch( mMultilinePolicy )
1383 // Remove done operations from the mask.
1384 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1387 void TextView::ProcessSnapshot( const Size& textViewSize )
1389 if( mVisualParameters.mSnapshotModeEnabled )
1391 // If layout options change, it's needed generate a new image.
1393 if( mOffscreenRootActor )
1395 // Set the root actor visible.
1396 // The root actor is set to non visible after the render task is processed.
1397 mOffscreenRootActor.SetVisible( true );
1399 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1400 mOffscreenRootActor.SetSize( textViewSize );
1403 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1404 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1406 // Set the image actor visible.
1407 // The image actor is set to non visible if there is no text to render.
1408 mOffscreenImageActor.SetVisible( true );
1410 // Calculates the offscreen image's size. It takes into account different points:
1411 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1412 // * There is a maximum texture size the graphic subsystem can load on the memory.
1413 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1415 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1416 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1417 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1418 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1420 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1424 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1425 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1426 offscreenSize.height,
1429 // Stores current text-view size to avoid create new Dali resources if text changes.
1430 mCurrentOffscreenSize = offscreenSize;
1432 if( !mOffscreenCameraActor )
1434 // Creates a new camera actor.
1435 mOffscreenCameraActor = CameraActor::New();
1436 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1437 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1438 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1440 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1442 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1445 // Calculate camera parameters for current text size.
1446 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1449 if( mVisualParameters.mScrollEnabled )
1451 // Updates the offscreen camera position with the new scroll offset.
1452 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1453 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1457 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1458 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1463 // Creates a new render task.
1464 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1466 mRenderTask.SetSourceActor( mOffscreenRootActor );
1467 mRenderTask.SetInputEnabled( false );
1468 mRenderTask.SetClearColor( Color::TRANSPARENT );
1469 mRenderTask.SetClearEnabled( true );
1470 mRenderTask.SetExclusive( true );
1472 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1473 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1478 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1479 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1482 // Process the render task only once every time the text changes or the text-view's size canges.
1483 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1487 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1488 mOffscreenImageActor.SetVisible( false );
1493 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1495 float xPosition = 0.f;
1496 float yPosition = 0.f;
1497 Vector3 parentOrigin = ParentOrigin::CENTER;
1498 Vector3 anchorPoint = AnchorPoint::CENTER;
1500 switch( mLayoutParameters.mHorizontalAlignment )
1502 case Toolkit::Alignment::HorizontalLeft:
1504 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1505 parentOrigin.x = 0.f;
1506 anchorPoint.x = 0.f;
1509 case Toolkit::Alignment::HorizontalCenter:
1514 case Toolkit::Alignment::HorizontalRight:
1516 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1517 parentOrigin.x = 1.f;
1518 anchorPoint.x = 1.f;
1523 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1527 switch( mLayoutParameters.mVerticalAlignment )
1529 case Toolkit::Alignment::VerticalTop:
1531 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1532 parentOrigin.y = 0.f;
1533 anchorPoint.y = 0.f;
1536 case Toolkit::Alignment::VerticalCenter:
1541 case Toolkit::Alignment::VerticalBottom:
1543 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1544 parentOrigin.y = 1.f;
1545 anchorPoint.y = 1.f;
1550 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1554 mOffscreenCameraActor.SetX( xPosition );
1555 mOffscreenCameraActor.SetY( yPosition );
1557 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1558 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1561 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1563 // not to process the offscreen root actor by setting its visibility to false.
1564 mOffscreenRootActor.SetVisible( false );
1566 // Sets the new size and the new frame buffer to the image actor.
1567 // Image actor must have same size as text. Otherwise text can be truncated.
1568 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1569 mOffscreenImageActor.SetImage( mFrameBufferImage );
1572 void TextView::DestroyOffscreenRenderingResources()
1576 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1578 if( Stage::IsInstalled() )
1580 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1583 mRenderTask.Reset();
1586 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1587 if( mOffscreenCameraActor )
1589 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1591 mOffscreenCameraActor.Reset();
1594 if( mOffscreenRootActor )
1596 mOffscreenRootActor.Reset();
1599 if( mOffscreenImageActor )
1601 mOffscreenImageActor.Reset();
1604 mCurrentOffscreenSize = Size( 0.f, 0.f );
1606 if( mFrameBufferImage )
1608 mFrameBufferImage.Reset();
1612 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1614 if( 1u == gesture.numberOfTouches )
1616 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1620 void TextView::TrimScrollPosition()
1622 const Vector3& textViewSize = GetControlSize();
1624 // Before use the text's size, relayout the text is needed to get the actual text size.
1625 GetTextLayoutInfo();
1627 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1628 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1629 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1630 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1631 float minVerticalDisplacement = -maxVerticalDisplacement;
1633 // Updates the range if the text is aligned on the right or left.
1634 switch( mLayoutParameters.mHorizontalAlignment )
1636 case Toolkit::Alignment::HorizontalLeft:
1638 maxHorizontalDisplacement *= 2.f;
1639 minHorizontalDisplacement = 0.f;
1642 case Toolkit::Alignment::HorizontalCenter:
1647 case Toolkit::Alignment::HorizontalRight:
1649 maxHorizontalDisplacement = 0.f;
1650 minHorizontalDisplacement *= 2.f;
1655 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1659 // Updates the range if the text is aligned on the top or bottom.
1660 switch( mLayoutParameters.mVerticalAlignment )
1662 case Toolkit::Alignment::VerticalTop:
1664 maxVerticalDisplacement *= 2.f;
1665 minVerticalDisplacement = 0.f;
1668 case Toolkit::Alignment::VerticalCenter:
1673 case Toolkit::Alignment::VerticalBottom:
1675 maxVerticalDisplacement = 0.f;
1676 minVerticalDisplacement *= 2.f;
1681 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1685 // Trims the scroll position to be within the range.
1686 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1687 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1689 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1690 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1693 void TextView::DoSetScrollPosition( const Vector2& position )
1695 // Stores old scroll position.
1696 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1698 // Updates the scroll position
1699 mVisualParameters.mCameraScrollPosition = position;
1701 // Ensures the text-view is covered with text.
1702 TrimScrollPosition();
1704 // Calculate the difference with the previous scroll position
1705 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1706 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1708 if( mOffscreenRootActor )
1710 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1712 mOffscreenRootActor.SetVisible( true );
1715 if( mOffscreenCameraActor )
1717 // Update the offscreen camera with the new scroll position.
1718 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1719 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1724 // Refresh the render-task.
1725 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1729 Toolkit::TextView handle( GetOwner() );
1730 mScrolledSignalV2.Emit( handle, delta );
1733 void TextView::CombineExceedPolicies()
1735 // Calculates the combination of exceed policies.
1737 switch( mLayoutParameters.mWidthExceedPolicy )
1739 case Toolkit::TextView::Original:
1741 switch( mLayoutParameters.mHeightExceedPolicy )
1743 case Toolkit::TextView::Original:
1745 mLayoutParameters.mExceedPolicy = Original;
1748 case Toolkit::TextView::Fade:
1750 mLayoutParameters.mExceedPolicy = OriginalFade;
1753 case Toolkit::TextView::ShrinkToFit:
1755 mLayoutParameters.mExceedPolicy = OriginalShrink;
1760 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1765 case Toolkit::TextView::Split:
1767 switch( mLayoutParameters.mHeightExceedPolicy )
1769 case Toolkit::TextView::Original:
1771 mLayoutParameters.mExceedPolicy = SplitOriginal;
1774 case Toolkit::TextView::Fade:
1776 mLayoutParameters.mExceedPolicy = SplitFade;
1779 case Toolkit::TextView::ShrinkToFit:
1781 mLayoutParameters.mExceedPolicy = SplitShrink;
1784 case Toolkit::TextView::EllipsizeEnd:
1786 mLayoutParameters.mExceedPolicy = SplitEllipsizeEnd;
1791 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1796 case Toolkit::TextView::Fade:
1798 switch( mLayoutParameters.mHeightExceedPolicy )
1800 case Toolkit::TextView::Original:
1802 mLayoutParameters.mExceedPolicy = FadeOriginal;
1805 case Toolkit::TextView::Fade:
1807 mLayoutParameters.mExceedPolicy = Fade;
1812 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1817 case Toolkit::TextView::ShrinkToFit:
1819 switch( mLayoutParameters.mHeightExceedPolicy )
1821 case Toolkit::TextView::Original:
1823 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1826 case Toolkit::TextView::Fade:
1828 mLayoutParameters.mExceedPolicy = ShrinkFade;
1831 case Toolkit::TextView::ShrinkToFit:
1833 mLayoutParameters.mExceedPolicy = Shrink;
1838 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1843 case Toolkit::TextView::EllipsizeEnd:
1845 switch( mLayoutParameters.mHeightExceedPolicy )
1847 case Toolkit::TextView::Original:
1849 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1852 case Toolkit::TextView::EllipsizeEnd:
1854 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1859 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1866 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1871 Actor TextView::GetRootActor() const
1873 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1877 if( mVisualParameters.mSnapshotModeEnabled )
1879 rootActor = mOffscreenRootActor;
1889 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1891 bool newValue( propertyValue.Get<bool>() );
1892 if( newValue != IsMarkupProcessingEnabled() )
1894 SetMarkupProcessingEnabled( newValue );
1897 // If markup processing has been enabled, Ensure current text is reprocessed.
1898 const std::string& currentText( GetText() );
1899 if( ! currentText.empty() )
1901 SetText( currentText );
1907 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1909 std::string policyName( propertyValue.Get<std::string>() );
1910 if(policyName == "SplitByNewLineChar")
1912 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1914 else if(policyName == "SplitByWord")
1916 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1918 else if(policyName == "SplitByChar")
1920 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1924 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1928 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1930 std::string policyName( propertyValue.Get<std::string>() );
1931 if(policyName == "Original")
1933 SetWidthExceedPolicy(Toolkit::TextView::Original);
1935 else if(policyName == "Fade")
1937 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1939 else if(policyName == "Split")
1941 SetWidthExceedPolicy(Toolkit::TextView::Split);
1943 else if(policyName == "ShrinkToFit")
1945 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1947 else if(policyName == "EllipsizeEnd")
1949 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1953 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1957 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1959 std::string policyName( propertyValue.Get<std::string>() );
1960 if(policyName == "Original")
1962 SetHeightExceedPolicy(Toolkit::TextView::Original);
1964 else if(policyName == "Fade")
1966 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1968 else if(policyName == "Split")
1970 SetHeightExceedPolicy(Toolkit::TextView::Split);
1972 else if(policyName == "ShrinkToFit")
1974 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1978 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1982 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1984 std::string policyName( propertyValue.Get<std::string>() );
1985 if(policyName == "Left")
1987 SetLineJustification(Toolkit::TextView::Left);
1989 else if(policyName == "Center")
1991 SetLineJustification(Toolkit::TextView::Center);
1993 else if(policyName == "Right")
1995 SetLineJustification(Toolkit::TextView::Right);
1997 else if(policyName == "Justified")
1999 SetLineJustification(Toolkit::TextView::Justified);
2003 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2007 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
2009 Vector4 value( propertyValue.Get<Vector4>() );
2010 DALI_ASSERT_ALWAYS( value.x >= 0 && value.y >= 0 && value.z >= 0 && value.w >= 0
2011 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2013 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2014 PixelSize( static_cast<unsigned int>( value.y ) ),
2015 PixelSize( static_cast<unsigned int>( value.z ) ),
2016 PixelSize( static_cast<unsigned int>( value.w ) ) );
2018 SetFadeBoundary( fadeBoundary );
2021 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2023 std::string value( propertyValue.Get<std::string>() );
2025 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2027 if(value == "HorizontalLeft")
2029 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2031 else if( value == "HorizontalCenter")
2033 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2035 else if( value == "HorizontalRight")
2037 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2041 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2044 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2046 if( value == "VerticalTop" )
2048 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2050 else if( value == "VerticalCenter")
2052 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2054 else if( value == "VerticalBottom")
2056 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2060 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2066 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2067 if( RELAYOUT_ALL != mRelayoutOperations )
2069 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2070 RELAYOUT_TEXT_ACTOR_UPDATE |
2071 RELAYOUT_ALIGNMENT |
2072 RELAYOUT_VISIBILITY );
2076 std::string TextView::OnHorizontalAlignmentPropertyGet()
2078 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2080 return "HorizontalLeft";
2082 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2084 return "HorizontalCenter";
2086 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2088 return "HorizontalRight";
2092 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2096 std::string TextView::OnVerticalAlignmentPropertyGet()
2098 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2100 return "VerticalTop";
2102 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2104 return "VerticalCenter";
2106 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2108 return "VerticalBottom";
2112 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2116 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2118 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2122 TextView& textViewImpl( GetImpl( textView ) );
2125 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2127 textViewImpl.OnMarkupEnabledPeopertySet( value );
2130 case Toolkit::TextView::PROPERTY_TEXT:
2132 textViewImpl.SetText( value.Get<std::string>() );
2135 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2137 textViewImpl.OnMultilinePolicyPropertySet( value );
2140 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2142 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2145 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2147 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2150 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2152 textViewImpl.OnLineJustificationPropertySet( value );
2155 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2157 textViewImpl.OnFadeBoundaryPropertySet( value );
2160 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2162 Dali::PointSize pointSize( value.Get<float>() );
2163 textViewImpl.SetLineHeightOffset(pointSize);
2166 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2167 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2169 textViewImpl.OnAlignmentPropertySet( index, value );
2176 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2178 Property::Value value;
2180 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2184 TextView& textViewImpl( GetImpl( textView ) );
2187 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2189 value = textViewImpl.IsMarkupProcessingEnabled();
2192 case Toolkit::TextView::PROPERTY_TEXT:
2194 value = textViewImpl.GetText();
2197 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2199 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2202 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2204 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2207 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2209 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2212 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2214 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2217 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2219 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2220 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2221 static_cast<float>( boundary.mRight.value ),
2222 static_cast<float>( boundary.mTop.value ),
2223 static_cast<float>( boundary.mBottom.value ) );
2226 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2228 value = textViewImpl.GetLineHeightOffset().value;
2231 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2233 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2236 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2238 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2246 } // namespace Internal
2248 } // namespace Toolkit