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 );
54 const char* MULTILINE_POLICY_NAME[] = {"SplitByNewLineChar", "SplitByWord", "SplitByChar"};
55 const char* EXCEED_POLICY_NAME[] = {"Original", "Truncate", "Fade", "Split","ShrinkToFit","EllipsizeEnd"};
56 const char* LINE_JUSTIFICATION_NAME[] = {"Left","Center","Right","Justified"};
58 // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
59 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
64 return Toolkit::TextView::New();
67 TypeRegistration typeRegistration( typeid(Toolkit::TextView), typeid(Toolkit::Control), Create );
69 SignalConnectorType signalConnector1( typeRegistration, Toolkit::TextView::SIGNAL_TEXT_SCROLLED , &TextView::DoConnectSignal );
71 PropertyRegistration property1( typeRegistration, "markup-enabled", Toolkit::TextView::PROPERTY_MARKUP_ENABLED, Property::BOOLEAN, &TextView::SetProperty, &TextView::GetProperty );
72 PropertyRegistration property2( typeRegistration, "text", Toolkit::TextView::PROPERTY_TEXT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
73 PropertyRegistration property3( typeRegistration, "multiline-policy", Toolkit::TextView::PROPERTY_MULTILINE_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
74 PropertyRegistration property4( typeRegistration, "width-exceed-policy", Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
75 PropertyRegistration property5( typeRegistration, "height-exceed-policy", Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
76 PropertyRegistration property6( typeRegistration, "line-justification", Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
77 PropertyRegistration property7( typeRegistration, "fade-boundary", Toolkit::TextView::PROPERTY_FADE_BOUNDARY, Property::VECTOR4, &TextView::SetProperty, &TextView::GetProperty );
78 PropertyRegistration property8( typeRegistration, "line-height-offset", Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET, Property::FLOAT, &TextView::SetProperty, &TextView::GetProperty );
79 PropertyRegistration property9( typeRegistration, "horizontal-alignment", Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
80 PropertyRegistration property10( typeRegistration, "vertical-alignment", Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT, Property::STRING, &TextView::SetProperty, &TextView::GetProperty );
83 * Whether the text-view-processor operation sets, inserts, replaces, removes text.
85 * @param[in] metadata The text-view-processor operation.
87 * @return \e true if the given text-view-processor operation is modifying the text.
89 bool IsTextViewProcessorRelayoutOperation( const TextView::TextViewProcessorMetadata& metadata )
91 return ( ( metadata.mType == TextView::TextSet ) ||
92 ( metadata.mType == TextView::TextInserted ) ||
93 ( metadata.mType == TextView::TextReplaced ) ||
94 ( metadata.mType == TextView::TextRemoved ) ||
95 ( metadata.mType == TextView::NewStyle ));
99 * Whether the text-view-processor operation sets a new line height offset.
101 * @param[in] metadata The text-view-processor operation.
103 * @return \e true if the given text-view-processor operation sets a new line height offset.
105 bool IsTextViewProcessorLineHeightOffsetOperation( const TextView::TextViewProcessorMetadata& metadata )
107 return ( metadata.mType == TextView::NewLineHeight );
111 * Whether the text-view-processor operation sets a new style.
113 * @param[in] metadata The text-view-processor operation.
115 * @return \e true if the given text-view-processor operation sets a new style.
117 bool IsTextViewProcessorNewStyleOperation( const TextView::TextViewProcessorMetadata& metadata )
119 return ( metadata.mType == TextView::NewStyle );
124 TextView::TextViewProcessorMetadata::TextViewProcessorMetadata()
125 : mType( TextView::TextSet ),
127 mNumberOfCharacters( 0 ),
132 Toolkit::TextView TextView::New()
134 // Create the implementation, temporarily owned on stack
135 IntrusivePtr<TextView> textView = new TextView();
137 // Pass ownership to CustomActor
138 Toolkit::TextView handle( *textView );
140 // Second-phase init of the implementation
141 // This can only be done after the CustomActor connection has been made...
142 textView->Initialize();
144 // Enables by default the offscreen rendering.
145 textView->SetSnapshotModeEnabled( false ); /// @note Temporary disabled due to some issues with text quality and glyph loading.
150 void TextView::SetText( const std::string& text )
152 // Creates a styled text with the markup or plain string.
153 MarkupProcessor::StyledTextArray styledText;
154 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
156 // Calls SetText() with the styled text array.
157 SetText( styledText );
160 void TextView::SetText( const MarkupProcessor::StyledTextArray& text )
162 // mTextViewProcessorOperations stores the InsertTextAt and RemoveTextFrom operations to transform the initial text to mCurrentStyledText.
163 // Once again, if a new text is set, any previous call to InsertTextAt or RemoveTextFrom can be discarted.
165 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorRelayoutOperation );
166 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
168 // Creates metadata with the Set operation.
169 TextViewProcessorMetadata metadata;
170 metadata.mType = TextView::TextSet;
171 metadata.mText = text;
174 mTextViewProcessorOperations.push_back( metadata );
176 // Updates current styled text.
177 mCurrentStyledText = text;
179 // Request to be relaid out
182 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
183 mRelayoutOperations = RELAYOUT_ALL;
186 void TextView::InsertTextAt( std::size_t position, const std::string& text )
188 // Creates a styled text with the markup or plain string.
189 MarkupProcessor::StyledTextArray styledText;
190 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
192 // Calls InsertTextAt() with the styled text array.
193 InsertTextAt( position, styledText );
196 void TextView::InsertTextAt( const std::size_t position, const MarkupProcessor::StyledTextArray& text )
198 // Creates metadata with the Insert operation.
199 TextViewProcessorMetadata metadata;
200 metadata.mType = TextView::TextInserted;
201 metadata.mPosition = position;
202 metadata.mText = text;
205 mTextViewProcessorOperations.push_back( metadata );
207 // Updates current styled text.
208 mCurrentStyledText.insert( mCurrentStyledText.begin() + position, text.begin(), text.end() );
210 // Request to be relaid out
213 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
214 mRelayoutOperations = RELAYOUT_ALL;
217 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const std::string& text )
219 // Creates a styled text with the markup or plain string.
220 MarkupProcessor::StyledTextArray styledText;
221 MarkupProcessor::GetStyledTextArray( text, styledText, IsMarkupProcessingEnabled() );
223 // Calls ReplaceTextFromTo() with the styled text array.
224 ReplaceTextFromTo( position, numberOfCharacters, styledText );
227 void TextView::ReplaceTextFromTo( const std::size_t position, const std::size_t numberOfCharacters, const MarkupProcessor::StyledTextArray& text )
229 // Creates metadata with the Insert operation.
230 TextViewProcessorMetadata metadata;
231 metadata.mType = TextView::TextReplaced;
232 metadata.mPosition = position;
233 metadata.mNumberOfCharacters = numberOfCharacters;
234 metadata.mText = text;
237 mTextViewProcessorOperations.push_back( metadata );
239 // Updates current styled text.
240 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
241 mCurrentStyledText.erase( it, it + numberOfCharacters );
242 it = mCurrentStyledText.begin() + position;
243 mCurrentStyledText.insert( it, text.begin(), text.end() );
245 // Request to be relaid out
248 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
249 mRelayoutOperations = RELAYOUT_ALL;
252 void TextView::RemoveTextFrom( const std::size_t position, const std::size_t numberOfCharacters )
254 // Creates metadata with the Remove operation.
255 TextViewProcessorMetadata metadata;
256 metadata.mType = TextView::TextRemoved;
257 metadata.mPosition = position;
258 metadata.mNumberOfCharacters = numberOfCharacters;
261 mTextViewProcessorOperations.push_back( metadata );
263 // Updates current styled text.
264 MarkupProcessor::StyledTextArray::iterator it = mCurrentStyledText.begin() + position;
265 mCurrentStyledText.erase( it, it + numberOfCharacters );
267 // Request to be relaid out
270 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
271 mRelayoutOperations = RELAYOUT_ALL;
274 std::string TextView::GetText() const
276 // Traverses the styled text array getting only the text.
277 // Note that for some languages a 'character' could be represented by more than one 'char'
280 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); it != endIt; ++it )
282 text.append( (*it).mText.GetText() );
288 void TextView::SetLineHeightOffset( const PointSize offset )
290 if( fabsf( mLayoutParameters.mLineHeightOffset - offset ) > Math::MACHINE_EPSILON_1000 )
292 // Removes any previous operation which modifies the line height offset.
293 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorLineHeightOffsetOperation );
294 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
296 // Creates metadata with the new line height operation.
297 TextViewProcessorMetadata metadata;
298 metadata.mType = TextView::NewLineHeight;
300 mTextViewProcessorOperations.push_back( metadata );
302 // Updates line height offset.
303 mLayoutParameters.mLineHeightOffset = offset;
307 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
308 if( RELAYOUT_ALL != mRelayoutOperations )
310 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
311 RELAYOUT_REMOVE_TEXT_ACTORS |
312 RELAYOUT_SIZE_POSITION |
314 RELAYOUT_VISIBILITY |
315 RELAYOUT_TEXT_ACTOR_UPDATE |
316 RELAYOUT_INSERT_TO_TEXT_VIEW |
317 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
322 PointSize TextView::GetLineHeightOffset() const
324 return PointSize( mLayoutParameters.mLineHeightOffset );
327 void TextView::SetStyleToCurrentText( const TextStyle& style, const TextStyle::Mask mask )
329 if( !mCurrentStyledText.empty() )
331 const bool checkFontName = mask & TextStyle::FONT;
332 const bool checkFontSize = mask & TextStyle::SIZE;
333 const bool checkFontStyle = mask & TextStyle::STYLE;
335 // Check first if metrics have changed.
336 bool metricsChanged = false;
337 for( MarkupProcessor::StyledTextArray::const_iterator it = mCurrentStyledText.begin(), endIt = mCurrentStyledText.end(); ( it != endIt ) && !metricsChanged; ++it )
339 const MarkupProcessor::StyledText& styledText( *it );
341 metricsChanged = ( checkFontName && ( styledText.mStyle.GetFontName() != style.GetFontName() ) ) ||
342 ( checkFontStyle && ( styledText.mStyle.GetFontStyle() != style.GetFontStyle() ) ) ||
343 ( checkFontSize && ( fabsf( styledText.mStyle.GetFontPointSize() - style.GetFontPointSize() ) > Math::MACHINE_EPSILON_1000 ) );
348 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
350 // If metrics change, new text measurements are needed.
351 SetText( mCurrentStyledText );
355 // Deletes any previous operation which sets a new style.
356 std::vector<TextViewProcessorMetadata>::iterator it = std::remove_if( mTextViewProcessorOperations.begin(), mTextViewProcessorOperations.end(), IsTextViewProcessorNewStyleOperation );
357 mTextViewProcessorOperations.erase( it, mTextViewProcessorOperations.end() );
359 // Creates metadata with the new style operation.
360 TextViewProcessorMetadata metadata;
361 metadata.mType = TextView::NewStyle;
363 MarkupProcessor::StyledText text;
365 metadata.mText.push_back( text );
366 metadata.mStyleMask = mask;
368 mTextViewProcessorOperations.push_back( metadata );
370 MarkupProcessor::SetTextStyle( mCurrentStyledText, style, mask );
374 if( RELAYOUT_ALL != mRelayoutOperations )
376 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
377 RELAYOUT_TEXT_ACTOR_UPDATE );
382 // Sets the new style to the ellipsize text
383 if( !mLayoutParameters.mEllipsizeText.empty() )
385 for( MarkupProcessor::StyledTextArray::iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
387 (*it).mStyle.Copy( style, mask );
390 SetEllipsizeText( mLayoutParameters.mEllipsizeText );
394 void TextView::SetTextAlignment( Toolkit::Alignment::Type align )
396 if( align != ( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment ) )
398 Toolkit::Alignment::Type horizontalAlignment( ( align & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
399 ( align & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
400 ( align & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
401 Toolkit::Alignment::Type verticalAlignment( ( align & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
402 ( align & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
403 ( align & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
405 mLayoutParameters.mHorizontalAlignment = horizontalAlignment;
406 mLayoutParameters.mVerticalAlignment = verticalAlignment;
410 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
411 if( RELAYOUT_ALL != mRelayoutOperations )
413 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
414 RELAYOUT_TEXT_ACTOR_UPDATE |
416 RELAYOUT_VISIBILITY );
421 Toolkit::Alignment::Type TextView::GetTextAlignment() const
423 return static_cast<Toolkit::Alignment::Type>( mLayoutParameters.mHorizontalAlignment | mLayoutParameters.mVerticalAlignment );
426 void TextView::SetMultilinePolicy( Toolkit::TextView::MultilinePolicy policy )
428 if( policy != mLayoutParameters.mMultilinePolicy )
430 mLayoutParameters.mMultilinePolicy = policy;
432 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed on order to retrieve the right values.
433 mRelayoutOperations = RELAYOUT_ALL;
439 Toolkit::TextView::MultilinePolicy TextView::GetMultilinePolicy() const
441 return mLayoutParameters.mMultilinePolicy;
444 void TextView::SetWidthExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
446 // The layout info could be invalid depending on the current exceed policy and the new one.
447 // i.e. if the current policy is Split and the new one is ShrinkToFit then
448 // the layout info generated for each char is not needed.
449 if( policy != mLayoutParameters.mWidthExceedPolicy )
451 mLayoutParameters.mWidthExceedPolicy = policy;
453 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
454 mRelayoutOperations = RELAYOUT_ALL;
460 Toolkit::TextView::ExceedPolicy TextView::GetWidthExceedPolicy() const
462 return mLayoutParameters.mWidthExceedPolicy;
465 void TextView::SetHeightExceedPolicy( Toolkit::TextView::ExceedPolicy policy )
467 if( policy != mLayoutParameters.mHeightExceedPolicy )
469 mLayoutParameters.mHeightExceedPolicy = policy;
473 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
474 if( RELAYOUT_ALL != mRelayoutOperations )
476 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
477 RELAYOUT_REMOVE_TEXT_ACTORS |
478 RELAYOUT_SIZE_POSITION |
480 RELAYOUT_VISIBILITY |
481 RELAYOUT_TEXT_ACTOR_UPDATE |
482 RELAYOUT_INSERT_TO_TEXT_VIEW |
483 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
488 Toolkit::TextView::ExceedPolicy TextView::GetHeightExceedPolicy() const
490 return mLayoutParameters.mHeightExceedPolicy;
493 void TextView::SetLineJustification( Toolkit::TextView::LineJustification justification )
495 if( justification != mLayoutParameters.mLineJustification )
497 mLayoutParameters.mLineJustification = justification;
501 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
502 if( RELAYOUT_ALL != mRelayoutOperations )
504 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
505 RELAYOUT_REMOVE_TEXT_ACTORS |
506 RELAYOUT_SIZE_POSITION |
508 RELAYOUT_VISIBILITY |
509 RELAYOUT_TEXT_ACTOR_UPDATE |
510 RELAYOUT_INSERT_TO_TEXT_VIEW |
511 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
516 Toolkit::TextView::LineJustification TextView::GetLineJustification() const
518 return mLayoutParameters.mLineJustification;
521 void TextView::SetFadeBoundary( const Toolkit::TextView::FadeBoundary& fadeBoundary )
523 if( ( fadeBoundary.mLeft != mVisualParameters.mFadeBoundary.mLeft ) ||
524 ( fadeBoundary.mRight != mVisualParameters.mFadeBoundary.mRight ) ||
525 ( fadeBoundary.mTop != mVisualParameters.mFadeBoundary.mTop ) ||
526 ( fadeBoundary.mBottom != mVisualParameters.mFadeBoundary.mBottom ) )
528 mVisualParameters.mFadeBoundary = fadeBoundary;
532 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
533 if( RELAYOUT_ALL != mRelayoutOperations )
535 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
536 RELAYOUT_REMOVE_TEXT_ACTORS |
537 RELAYOUT_VISIBILITY |
538 RELAYOUT_TEXT_ACTOR_UPDATE |
539 RELAYOUT_INSERT_TO_TEXT_VIEW |
540 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
545 const Toolkit::TextView::FadeBoundary& TextView::GetFadeBoundary() const
547 return mVisualParameters.mFadeBoundary;
550 void TextView::SetEllipsizeText( const std::string& ellipsizeText )
552 // Creates a styled text with the markup or plain string.
553 MarkupProcessor::StyledTextArray styledText;
554 MarkupProcessor::GetStyledTextArray( ellipsizeText, styledText, IsMarkupProcessingEnabled() );
556 SetEllipsizeText( styledText );
559 void TextView::SetEllipsizeText( const MarkupProcessor::StyledTextArray& ellipsizeText )
561 mLayoutParameters.mEllipsizeText = ellipsizeText;
563 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
565 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
566 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
568 // Request to be relaid out
571 mRelayoutOperations = RELAYOUT_ALL;
574 std::string TextView::GetEllipsizeText() const
577 for( MarkupProcessor::StyledTextArray::const_iterator it = mLayoutParameters.mEllipsizeText.begin(), endIt = mLayoutParameters.mEllipsizeText.end(); it != endIt; ++it )
579 text.append( (*it).mText.GetText() );
585 void TextView::GetTextLayoutInfo()
587 const bool relayoutSizeAndPositionNeeded = mRelayoutOperations & RELAYOUT_SIZE_POSITION;
588 const bool relayoutAlignmentNeeded = mRelayoutOperations & RELAYOUT_ALIGNMENT;
589 const bool relayoutVisibilityNeeded = mRelayoutOperations & RELAYOUT_VISIBILITY;
591 if( relayoutSizeAndPositionNeeded || relayoutAlignmentNeeded || relayoutVisibilityNeeded )
593 Vector3 textViewSize = GetControlSize();
595 if( ( ( textViewSize.width < Math::MACHINE_EPSILON_1000 ) ||
596 ( textViewSize.height < Math::MACHINE_EPSILON_1000 ) ) &&
597 ( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
598 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
599 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) ) )
601 // In case the control size is not set but the layout settings are the default (split by new line character and original exceed policies)
602 // the text natural size can be used.
603 textViewSize = GetNaturalSize();
606 if( ( textViewSize.width > Math::MACHINE_EPSILON_1000 ) &&
607 ( textViewSize.height > Math::MACHINE_EPSILON_1000 ) )
609 // Check if the text-view has glyph-actors.
610 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
612 RelayoutOperationMask mask = NO_RELAYOUT;
613 if( relayoutSizeAndPositionNeeded )
615 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_SIZE_POSITION );
617 if( relayoutAlignmentNeeded )
619 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_ALIGNMENT );
621 if( relayoutVisibilityNeeded )
623 mask = static_cast<RelayoutOperationMask>( mask | RELAYOUT_VISIBILITY );
628 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
629 // add them to the text-actor cache.
630 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
631 mRelayoutData.mGlyphActors.clear();
634 // Relays-out but doesn't add glyph-actors to the text-view.
635 DoRelayOut( textViewSize.GetVectorXY(), mask );
639 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
640 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
647 void TextView::GetTextLayoutInfo( Toolkit::TextView::TextLayoutInfo& textLayoutInfo )
651 textLayoutInfo.mCharacterLayoutInfoTable = mRelayoutData.mCharacterLayoutInfoTable;
652 textLayoutInfo.mLines = mRelayoutData.mLines;
654 textLayoutInfo.mCharacterLogicalToVisualMap = mRelayoutData.mCharacterLogicalToVisualMap;
655 textLayoutInfo.mCharacterVisualToLogicalMap = mRelayoutData.mCharacterVisualToLogicalMap;
657 textLayoutInfo.mTextSize = mRelayoutData.mTextSizeForRelayoutOption;
659 textLayoutInfo.mScrollOffset = mVisualParameters.mCameraScrollPosition;
662 void TextView::SetSortModifier( float depthOffset )
664 mVisualParameters.mSortModifier = depthOffset;
666 for( std::vector<RenderableActor>::iterator it = mRelayoutData.mGlyphActors.begin(), endIt = mRelayoutData.mGlyphActors.end();
670 ( *it ).SetSortModifier( depthOffset );
673 if( mOffscreenImageActor )
675 mOffscreenImageActor.SetSortModifier( depthOffset );
679 void TextView::SetSnapshotModeEnabled( bool enable )
681 if( enable != mVisualParameters.mSnapshotModeEnabled )
683 // Remove first all glyph-actors
684 if( !mRelayoutData.mGlyphActors.empty() )
686 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
689 mVisualParameters.mSnapshotModeEnabled = enable;
690 if( !mLockPreviousSnapshotMode )
692 // mPreviousSnapshotModeEnabled stores the snapshot mode value before SetScrollEnabled( true ) is
693 // called. However, if SetSnapshotModeEnabled() is called after SetScrollEnabled() then the stored value
695 // As SetSnapshotModeEnabled() is also called from SetScrollEnabled(), the mLockPreviousSnapshotMode prevents
696 // to smash the stored value.
697 mPreviousSnapshotModeEnabled = enable;
700 if( mVisualParameters.mSnapshotModeEnabled )
702 // Create a root actor and an image actor for offscreen rendering.
703 mOffscreenRootActor = Layer::New();
704 mOffscreenImageActor = ImageActor::New();
706 mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
707 mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
708 mOffscreenRootActor.SetInheritRotation( false );
709 mOffscreenRootActor.SetInheritScale( false );
710 mOffscreenRootActor.SetDepthTestDisabled( true );
712 mOffscreenRootActor.SetPosition( 0.f, 0.f, 0.f );
714 mOffscreenImageActor.SetAnchorPoint( ParentOrigin::CENTER );
715 mOffscreenImageActor.SetParentOrigin( ParentOrigin::CENTER );
718 self.Add( mOffscreenRootActor );
719 self.Add( mOffscreenImageActor );
720 mOffscreenImageActor.SetScale(Vector3(1.f, -1.f, 1.f));
726 if( mOffscreenRootActor )
728 self.Remove( mOffscreenRootActor );
731 if( mOffscreenImageActor )
733 self.Remove( mOffscreenImageActor );
736 DestroyOffscreenRenderingResources();
739 if( RELAYOUT_ALL != mRelayoutOperations )
741 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
742 RELAYOUT_REMOVE_TEXT_ACTORS |
743 RELAYOUT_TEXT_ACTOR_UPDATE |
744 RELAYOUT_INSERT_TO_TEXT_VIEW |
745 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
751 bool TextView::IsSnapshotModeEnabled() const
753 return mVisualParameters.mSnapshotModeEnabled;
756 void TextView::SetMarkupProcessingEnabled( bool enable )
758 mMarkUpEnabled = enable;
761 bool TextView::IsMarkupProcessingEnabled() const
763 return mMarkUpEnabled;
766 void TextView::SetScrollEnabled( const bool enable )
768 if( enable != mVisualParameters.mScrollEnabled )
770 mVisualParameters.mScrollEnabled = enable;
772 if( mVisualParameters.mScrollEnabled )
774 // Offscreen rendering is needed to enable text scroll.
776 // Stores previous value of the snapshot mode.
777 mPreviousSnapshotModeEnabled = IsSnapshotModeEnabled();
780 // SetSnapshotModeEnabled() modifies the mPreviousSnapshotModeEnabled just in case it's called after SetScrollEnabled(),
781 // this lock prevents to modify the mPreviousSnapshotModeEnabled when SetSnapshotModeEnabled() from this method.
782 Lock lock( mLockPreviousSnapshotMode );
783 SetSnapshotModeEnabled( true );
786 // Creates the pan gesture detector and attach the text-view.
787 mPanGestureDetector = PanGestureDetector::New();
788 mPanGestureDetector.DetectedSignal().Connect( this, &TextView::OnTextPan );
789 mPanGestureDetector.Attach( Self() );
793 // Removes the pan gesture detector.
794 if( mPanGestureDetector )
796 mPanGestureDetector.Detach( Self() );
797 mPanGestureDetector.DetectedSignal().Disconnect( this, &TextView::OnTextPan );
798 mPanGestureDetector.Reset();
801 // Restores the previous state for snapshot mode.
802 SetSnapshotModeEnabled( mPreviousSnapshotModeEnabled );
807 bool TextView::IsScrollEnabled() const
809 return mVisualParameters.mScrollEnabled;
812 void TextView::SetScrollPosition( const Vector2& position )
814 if( position != mVisualParameters.mCameraScrollPosition )
816 // Guard against destruction during signal emission
817 // Note that Emit() methods are called indirectly from within DoSetScrollPosition()
818 Toolkit::TextView handle( GetOwner() );
820 DoSetScrollPosition( position );
822 // Check if the new scroll position has been trimmed.
823 mVisualParameters.mScrollPositionTrimmed = ( position != mVisualParameters.mCameraScrollPosition );
827 const Vector2& TextView::GetScrollPosition() const
829 return mVisualParameters.mCameraScrollPosition;
832 bool TextView::IsScrollPositionTrimmed() const
834 return mVisualParameters.mScrollPositionTrimmed;
837 Toolkit::TextView::ScrolledSignalV2& TextView::ScrolledSignal()
839 return mScrolledSignalV2;
842 bool TextView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
844 Dali::BaseHandle handle( object );
846 bool connected( true );
847 Toolkit::TextView textView = Toolkit::TextView::DownCast(handle);
849 if( Dali::Toolkit::TextView::SIGNAL_TEXT_SCROLLED == signalName )
851 textView.ScrolledSignal().Connect( tracker, functor );
855 // signalName does not match any signal
862 TextView::LayoutParameters::LayoutParameters()
863 : mMultilinePolicy( Toolkit::TextView::SplitByNewLineChar ),
864 mWidthExceedPolicy( Toolkit::TextView::Original ),
865 mHeightExceedPolicy( Toolkit::TextView::Original ),
866 mHorizontalAlignment( Toolkit::Alignment::HorizontalCenter ),
867 mVerticalAlignment( Toolkit::Alignment::VerticalCenter ),
868 mLineJustification( Toolkit::TextView::Left ),
869 mLineHeightOffset( 0.f ),
871 mMarkUpEnabled( false )
873 // Sets ellipsize text
874 MarkupProcessor::StyledTextArray styledEllipsize;
875 MarkupProcessor::GetStyledTextArray( std::string( "..." ), mEllipsizeText, false );
878 TextView::LayoutParameters::LayoutParameters( const Toolkit::TextView::MultilinePolicy multilinePolicy,
879 const Toolkit::TextView::ExceedPolicy widthExceedPolicy,
880 const Toolkit::TextView::ExceedPolicy heightExceedPolicy,
881 const Toolkit::Alignment::Type alignmentType,
882 const Toolkit::TextView::LineJustification lineJustification,
883 const float lineHeightOffset,
884 const std::string& ellipsizeText,
885 const bool markUpEnabled )
886 : mMultilinePolicy( multilinePolicy ),
887 mWidthExceedPolicy( widthExceedPolicy ),
888 mHeightExceedPolicy( heightExceedPolicy ),
889 mHorizontalAlignment(),
890 mVerticalAlignment(),
891 mLineJustification( lineJustification ),
892 mLineHeightOffset( lineHeightOffset ),
894 mMarkUpEnabled( markUpEnabled )
897 Toolkit::Alignment::Type horizontalAlignment( ( alignmentType & Toolkit::Alignment::HorizontalLeft ? Toolkit::Alignment::HorizontalLeft :
898 ( alignmentType & Toolkit::Alignment::HorizontalCenter ? Toolkit::Alignment::HorizontalCenter :
899 ( alignmentType & Toolkit::Alignment::HorizontalRight ? Toolkit::Alignment::HorizontalRight : Toolkit::Alignment::HorizontalCenter ) ) ) );
900 Toolkit::Alignment::Type verticalAlignment( ( alignmentType & Toolkit::Alignment::VerticalTop ? Toolkit::Alignment::VerticalTop :
901 ( alignmentType & Toolkit::Alignment::VerticalCenter ? Toolkit::Alignment::VerticalCenter :
902 ( alignmentType & Toolkit::Alignment::VerticalBottom ? Toolkit::Alignment::VerticalBottom : Toolkit::Alignment::VerticalCenter ) ) ) );
904 mHorizontalAlignment = horizontalAlignment;
905 mVerticalAlignment = verticalAlignment;
907 // Sets ellipsize text
908 MarkupProcessor::StyledTextArray styledEllipsize;
909 MarkupProcessor::GetStyledTextArray( ellipsizeText, mEllipsizeText, mMarkUpEnabled );
912 TextView::LayoutParameters::LayoutParameters( const TextView::LayoutParameters& layoutParameters )
913 : mMultilinePolicy( layoutParameters.mMultilinePolicy ),
914 mWidthExceedPolicy( layoutParameters.mWidthExceedPolicy ),
915 mHeightExceedPolicy( layoutParameters.mHeightExceedPolicy ),
916 mHorizontalAlignment( layoutParameters.mHorizontalAlignment ),
917 mVerticalAlignment( layoutParameters.mVerticalAlignment ),
918 mLineJustification( layoutParameters.mLineJustification ),
919 mLineHeightOffset( layoutParameters.mLineHeightOffset ),
920 mEllipsizeText( layoutParameters.mEllipsizeText ),
921 mMarkUpEnabled( layoutParameters.mMarkUpEnabled )
925 TextView::LayoutParameters& TextView::LayoutParameters::operator=( const TextView::LayoutParameters& layoutParameters )
927 mMultilinePolicy = layoutParameters.mMultilinePolicy;
928 mWidthExceedPolicy = layoutParameters.mWidthExceedPolicy;
929 mHeightExceedPolicy = layoutParameters.mHeightExceedPolicy;
930 mHorizontalAlignment = layoutParameters.mHorizontalAlignment;
931 mVerticalAlignment = layoutParameters.mVerticalAlignment;
932 mLineJustification = layoutParameters.mLineJustification;
933 mLineHeightOffset = layoutParameters.mLineHeightOffset;
934 mEllipsizeText = layoutParameters.mEllipsizeText;
935 mMarkUpEnabled = layoutParameters.mMarkUpEnabled;
940 TextView::VisualParameters::VisualParameters()
942 mSortModifier( 0.f ),
943 mCameraScrollPosition( 0.f, 0.f ),
944 mSnapshotModeEnabled( false ),
945 mScrollEnabled( false ),
946 mScrollPositionTrimmed( false )
950 TextView::VisualParameters::VisualParameters( const VisualParameters& visualParameters )
951 : mFadeBoundary( visualParameters.mFadeBoundary ),
952 mSortModifier( visualParameters.mSortModifier ),
953 mCameraScrollPosition( visualParameters.mCameraScrollPosition ),
954 mSnapshotModeEnabled( visualParameters.mSnapshotModeEnabled ),
955 mScrollEnabled( visualParameters.mScrollEnabled ),
956 mScrollPositionTrimmed( visualParameters.mScrollPositionTrimmed )
960 TextView::VisualParameters& TextView::VisualParameters::operator=( const TextView::VisualParameters& visualParameters )
962 mFadeBoundary = visualParameters.mFadeBoundary;
963 mSortModifier = visualParameters.mSortModifier;
964 mCameraScrollPosition = visualParameters.mCameraScrollPosition;
965 mSnapshotModeEnabled = visualParameters.mSnapshotModeEnabled;
966 mScrollEnabled = visualParameters.mScrollEnabled;
967 mScrollPositionTrimmed = visualParameters.mScrollPositionTrimmed;
972 TextView::RelayoutData::RelayoutData()
974 mShrinkFactor( 1.f ),
976 mCharacterLogicalToVisualMap(),
977 mCharacterVisualToLogicalMap(),
979 mCharacterLayoutInfoTable(),
981 mTextSizeForRelayoutOption()
985 TextView::RelayoutData::RelayoutData( const TextView::RelayoutData& relayoutData )
986 : mTextViewSize( relayoutData.mTextViewSize ),
987 mShrinkFactor( relayoutData.mShrinkFactor ),
988 mTextLayoutInfo( relayoutData.mTextLayoutInfo ),
989 mCharacterLogicalToVisualMap( relayoutData.mCharacterLogicalToVisualMap ),
990 mCharacterVisualToLogicalMap( relayoutData.mCharacterVisualToLogicalMap ),
991 mGlyphActors( relayoutData.mGlyphActors ),
992 mCharacterLayoutInfoTable( relayoutData.mCharacterLayoutInfoTable ),
993 mLines( relayoutData.mLines ),
994 mTextSizeForRelayoutOption( relayoutData.mTextSizeForRelayoutOption )
998 TextView::RelayoutData& TextView::RelayoutData::operator=( const TextView::RelayoutData& relayoutData )
1000 mTextViewSize = relayoutData.mTextViewSize;
1001 mShrinkFactor = relayoutData.mShrinkFactor;
1002 mTextLayoutInfo = relayoutData.mTextLayoutInfo;
1003 mCharacterLogicalToVisualMap = relayoutData.mCharacterLogicalToVisualMap;
1004 mCharacterVisualToLogicalMap = relayoutData.mCharacterVisualToLogicalMap;
1005 mGlyphActors = relayoutData.mGlyphActors;
1006 mCharacterLayoutInfoTable = relayoutData.mCharacterLayoutInfoTable;
1007 mLines = relayoutData.mLines;
1008 mTextSizeForRelayoutOption = relayoutData.mTextSizeForRelayoutOption;
1013 TextView::TextView()
1014 : ControlImpl( false ), // doesn't require touch events
1015 mCurrentStyledText(),
1016 mTextViewProcessorOperations(),
1017 mLayoutParameters( Toolkit::TextView::SplitByNewLineChar,
1018 Toolkit::TextView::Original,
1019 Toolkit::TextView::Original,
1020 static_cast<Toolkit::Alignment::Type>( Toolkit::Alignment::HorizontalCenter | Toolkit::Alignment::VerticalCenter ),
1021 Toolkit::TextView::Left,
1023 std::string( "..." ),
1025 mVisualParameters(),
1027 mRelayoutOperations( NO_RELAYOUT ),
1028 mOffscreenRootActor(),
1029 mOffscreenImageActor(),
1030 mOffscreenCameraActor(),
1031 mCurrentOffscreenSize(),
1032 mFrameBufferImage(),
1034 mPanGestureDetector(),
1035 mLockPreviousSnapshotMode( false ),
1036 mPreviousSnapshotModeEnabled( false ),
1037 mMarkUpEnabled( false )
1039 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1040 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1043 TextView::~TextView()
1045 // Destroys offscreen rendering resources.
1046 DestroyOffscreenRenderingResources();
1048 // Destroys scroll pan gesture detector.
1049 if( mPanGestureDetector )
1051 mPanGestureDetector.Reset();
1055 Vector3 TextView::GetNaturalSize()
1057 if( !mTextViewProcessorOperations.empty() )
1059 // There are SetText, Inserts or Removes to do. It means the current layout info is not updated.
1061 if( !mRelayoutData.mGlyphActors.empty() )
1063 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1064 // add them to the text-actor cache.
1065 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1066 mRelayoutData.mGlyphActors.clear();
1068 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1069 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1072 PerformTextViewProcessorOperations();
1075 return Vector3( mRelayoutData.mTextLayoutInfo.mWholeTextSize.width, mRelayoutData.mTextLayoutInfo.mWholeTextSize.height, 0.f );
1078 float TextView::GetHeightForWidth( float width )
1082 if( ( Toolkit::TextView::SplitByNewLineChar == mLayoutParameters.mMultilinePolicy ) &&
1083 ( Toolkit::TextView::Original == mLayoutParameters.mWidthExceedPolicy ) &&
1084 ( Toolkit::TextView::Original == mLayoutParameters.mHeightExceedPolicy ) )
1086 // If multiline and exceed policies are 'SplitByNewLineChar' and 'Original' is better get the height from the
1087 // natural size. GetNaturalSize() for this configuration is faster than DoRelayOut().
1088 height = GetNaturalSize().height;
1092 // Check if the given width is different than the current one.
1093 const bool differentWidth = ( fabsf( width - mRelayoutData.mTextViewSize.width ) > Math::MACHINE_EPSILON_1000 );
1095 // Check if the text-view has glyph-actors.
1096 const bool hasGlyphActors = !mRelayoutData.mGlyphActors.empty();
1098 // Check which layout operations need to be done.
1099 const bool relayoutSizeAndPositionNeeded = ( mRelayoutOperations & RELAYOUT_SIZE_POSITION ) || differentWidth;
1101 if( relayoutSizeAndPositionNeeded )
1103 if( hasGlyphActors )
1105 // Remove glyph-actors from the text-view as some text-operation like CreateTextInfo()
1106 // add them to the text-actor cache.
1107 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1108 mRelayoutData.mGlyphActors.clear();
1111 // Use the given width.
1112 const Vector2 textViewSize( width, GetControlSize().height );
1114 // Relays-out but doesn't add glyph-actors to the text-view.
1115 DoRelayOut( textViewSize, RELAYOUT_SIZE_POSITION );
1118 // Retrieve the text height after relayout the text.
1119 height = mRelayoutData.mTextSizeForRelayoutOption.height;
1121 if( differentWidth )
1123 // Revert the relayout operation mask
1124 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_SIZE_POSITION );
1127 if( hasGlyphActors )
1129 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_VIEW );
1130 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations | RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1133 if( differentWidth || hasGlyphActors )
1142 float TextView::GetWidthForHeight( float height )
1144 // TODO: Needs implementing properly, for now just return the natural width.
1145 return GetNaturalSize().width;
1149 void TextView::OnInitialize()
1154 void TextView::OnStyleChange( StyleChange change )
1156 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo = TextViewProcessor::WordLayoutInfo();
1157 TextViewProcessor::CreateWordTextInfo( mLayoutParameters.mEllipsizeText,
1158 mRelayoutData.mTextLayoutInfo.mEllipsizeLayoutInfo );
1160 SetText( mCurrentStyledText );
1163 void TextView::OnControlSizeSet( const Vector3& size )
1165 if( size.GetVectorXY() != mRelayoutData.mTextViewSize )
1167 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
1168 mRelayoutOperations = RELAYOUT_ALL;
1170 // Request to be relaid out
1175 void TextView::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
1177 if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
1179 // Not worth to relayout if width or height is equal to zero.
1183 if( size != mRelayoutData.mTextViewSize )
1185 // if new size is different than the prevoius one, set positions and maybe sizes of all glyph-actor is needed.
1186 if( RELAYOUT_ALL != mRelayoutOperations )
1188 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
1189 RELAYOUT_REMOVE_TEXT_ACTORS |
1190 RELAYOUT_SIZE_POSITION |
1191 RELAYOUT_ALIGNMENT |
1192 RELAYOUT_VISIBILITY |
1193 RELAYOUT_TEXT_ACTOR_UPDATE |
1194 RELAYOUT_INSERT_TO_TEXT_VIEW |
1195 RELAYOUT_INSERT_TO_TEXT_ACTOR_LIST );
1199 // Remove glyph-actors from text-view
1200 if( !mRelayoutData.mGlyphActors.empty() && ( mRelayoutOperations & RELAYOUT_REMOVE_TEXT_ACTORS ) )
1202 TextViewRelayout::RemoveGlyphActors( GetRootActor(), mRelayoutData.mGlyphActors );
1203 mRelayoutData.mGlyphActors.clear();
1206 if( NO_RELAYOUT != mRelayoutOperations )
1208 // Relays-out and add glyph-actors to the text-view.
1209 DoRelayOut( size, mRelayoutOperations );
1210 ProcessSnapshot( size );
1213 // Quite likely the texts of the text-actors are not going to be reused, so clear them.
1214 mRelayoutData.mTextActorCache.ClearTexts();
1217 void TextView::PerformTextViewProcessorOperations()
1219 // Traverse the relayout operation vector ...
1221 // Optimizes some operations.
1222 OptimizeTextViewProcessorOperations();
1224 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1226 const TextViewProcessorMetadata& relayoutMetadata( *it );
1228 switch( relayoutMetadata.mType )
1230 case TextView::TextSet:
1232 TextViewProcessor::CreateTextInfo( relayoutMetadata.mText,
1237 case TextView::TextInserted:
1239 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1240 relayoutMetadata.mText,
1245 case TextView::TextReplaced:
1247 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1248 relayoutMetadata.mNumberOfCharacters,
1249 relayoutMetadata.mText,
1254 case TextView::TextRemoved:
1256 TextViewProcessor::UpdateTextInfo( relayoutMetadata.mPosition,
1257 relayoutMetadata.mNumberOfCharacters,
1260 TextViewProcessor::CLEAR_TEXT ); // clears the text of the text-actors.
1263 case TextView::NewLineHeight:
1265 TextViewProcessor::UpdateTextInfo( mLayoutParameters.mLineHeightOffset,
1266 mRelayoutData.mTextLayoutInfo );
1269 case TextView::NewStyle:
1271 TextViewProcessor::UpdateTextInfo( ( *relayoutMetadata.mText.begin() ).mStyle,
1272 relayoutMetadata.mStyleMask,
1279 // Clear all operations when they are done.
1280 mTextViewProcessorOperations.clear();
1283 void TextView::OptimizeTextViewProcessorOperations()
1285 // TODO: check if some operation can be discarted. i.e. InsertTextAt( 0, "a" ); RemoveTextFrom( 0, 1 );
1287 // At the moment it only replaces a 'remove 1 character' followed by 'insert 1 character' in the same position by a 'replace' operation.
1288 // This sequence is used by text-input with predictive text. Change this two operations by a replace allows the text-view processor to
1289 // use the cache without clearing the text-actors.
1291 std::vector<TextViewProcessorMetadata> textViewProcessorOperations;
1293 for( std::vector<TextViewProcessorMetadata>::const_iterator it = mTextViewProcessorOperations.begin(), endIt = mTextViewProcessorOperations.end(); it != endIt; ++it )
1295 const TextViewProcessorMetadata& relayoutMetadata( *it );
1297 switch( relayoutMetadata.mType )
1299 case TextView::TextRemoved:
1301 bool optimizationDone = false;
1303 if( it + 1 != endIt )
1305 const TextViewProcessorMetadata& nextRelayoutMetadata( *( it + 1 ) );
1306 if( TextView::TextInserted == nextRelayoutMetadata.mType )
1308 if( relayoutMetadata.mPosition == nextRelayoutMetadata.mPosition )
1310 optimizationDone = true;
1311 TextViewProcessorMetadata newRelayoutMetadata;
1312 newRelayoutMetadata.mType = TextView::TextReplaced;
1313 newRelayoutMetadata.mPosition = relayoutMetadata.mPosition;
1314 newRelayoutMetadata.mNumberOfCharacters = relayoutMetadata.mNumberOfCharacters;
1315 newRelayoutMetadata.mText = nextRelayoutMetadata.mText;
1316 textViewProcessorOperations.push_back( newRelayoutMetadata );
1318 // do not access the TextInserted operation in next iteration.
1324 if( !optimizationDone )
1326 textViewProcessorOperations.push_back( relayoutMetadata );
1332 textViewProcessorOperations.push_back( relayoutMetadata );
1337 mTextViewProcessorOperations = textViewProcessorOperations;
1340 void TextView::DoRelayOut( const Size& textViewSize, const RelayoutOperationMask relayoutOperationMask )
1342 // Traverse the relayout operation vector. It fills the natural size, layout and glyph-actor data structures.
1343 if( !mTextViewProcessorOperations.empty() )
1345 PerformTextViewProcessorOperations();
1348 CombineExceedPolicies();
1351 if( mVisualParameters.mSnapshotModeEnabled )
1353 rootActor = mOffscreenRootActor;
1360 mRelayoutData.mTextViewSize = textViewSize;
1361 switch( mLayoutParameters.mMultilinePolicy )
1363 case Toolkit::TextView::SplitByNewLineChar: // multiline policy == SplitByNewLineChar.
1365 SplitByNewLineChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1367 } // SplitByNewLineChar
1369 case Toolkit::TextView::SplitByWord: // multiline policy == SplitByWord.
1371 SplitByWord::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1375 case Toolkit::TextView::SplitByChar: // multiline policy == SplitByChar.
1377 SplitByChar::Relayout( rootActor, relayoutOperationMask, mLayoutParameters, mVisualParameters, mRelayoutData );
1380 } // switch( mMultilinePolicy )
1382 // Remove done operations from the mask.
1383 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations & ~relayoutOperationMask );
1386 void TextView::ProcessSnapshot( const Size& textViewSize )
1388 if( mVisualParameters.mSnapshotModeEnabled )
1390 // If layout options change, it's needed generate a new image.
1392 if( mOffscreenRootActor )
1394 // Set the root actor visible.
1395 // The root actor is set to non visible after the render task is processed.
1396 mOffscreenRootActor.SetVisible( true );
1398 // The offscreen root actor must have same size as text view. Otherwise, text alignment won't work.
1399 mOffscreenRootActor.SetSize( textViewSize );
1402 if( ( mRelayoutData.mTextSizeForRelayoutOption.width > Math::MACHINE_EPSILON_1000 ) &&
1403 ( mRelayoutData.mTextSizeForRelayoutOption.height > Math::MACHINE_EPSILON_1000 ) )
1405 // Set the image actor visible.
1406 // The image actor is set to non visible if there is no text to render.
1407 mOffscreenImageActor.SetVisible( true );
1409 // Calculates the offscreen image's size. It takes into account different points:
1410 // * If text has italics, add a small offset is needed in order to not to cut the text next to the right edge.
1411 // * There is a maximum texture size the graphic subsystem can load on the memory.
1412 // * If the scroll is enabled, the offscreen image's size is never bigger than the text-view's size.
1414 const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1415 mVisualParameters.mScrollEnabled ? textViewSize.width : std::max( mRelayoutData.mTextSizeForRelayoutOption.width, textViewSize.width ) + mRelayoutData.mTextLayoutInfo.mMaxItalicsOffset ),
1416 std::min( MAX_OFFSCREEN_RENDERING_SIZE,
1417 mVisualParameters.mScrollEnabled ? textViewSize.height : std::max( mRelayoutData.mTextSizeForRelayoutOption.height, textViewSize.height ) ) );
1419 const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
1423 // Creates a frame buffer for offscreen rendering when the size is negotiated.
1424 mFrameBufferImage = FrameBufferImage::New( offscreenSize.width,
1425 offscreenSize.height,
1428 // Stores current text-view size to avoid create new Dali resources if text changes.
1429 mCurrentOffscreenSize = offscreenSize;
1431 if( !mOffscreenCameraActor )
1433 // Creates a new camera actor.
1434 mOffscreenCameraActor = CameraActor::New();
1435 mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
1436 mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
1437 mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
1439 mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
1441 mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
1444 // Calculate camera parameters for current text size.
1445 mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
1448 if( mVisualParameters.mScrollEnabled )
1450 // Updates the offscreen camera position with the new scroll offset.
1451 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1452 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1456 // Text's size could be bigger than text-view's size. In that case the camera must be aligned to cover the whole text.
1457 AlignOffscreenCameraActor( textViewSize, offscreenSize );
1462 // Creates a new render task.
1463 mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
1465 mRenderTask.SetSourceActor( mOffscreenRootActor );
1466 mRenderTask.SetInputEnabled( false );
1467 mRenderTask.SetClearColor( Color::TRANSPARENT );
1468 mRenderTask.SetClearEnabled( true );
1469 mRenderTask.SetExclusive( true );
1471 // Connects the signal to the TextView::RenderTaskFinished method in order to make the root actor non visible when the render task is processed.
1472 mRenderTask.FinishedSignal().Connect( this, &TextView::RenderTaskFinished );
1477 mRenderTask.SetCameraActor( mOffscreenCameraActor );
1478 mRenderTask.SetTargetFrameBuffer( mFrameBufferImage );
1481 // Process the render task only once every time the text changes or the text-view's size canges.
1482 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1486 // If there is no text just make any previous generated image invisible instead to process a render task with no text.
1487 mOffscreenImageActor.SetVisible( false );
1492 void TextView::AlignOffscreenCameraActor( const Size& textViewSize, const Size& offscreenSize )
1494 float xPosition = 0.f;
1495 float yPosition = 0.f;
1496 Vector3 parentOrigin = ParentOrigin::CENTER;
1497 Vector3 anchorPoint = AnchorPoint::CENTER;
1499 switch( mLayoutParameters.mHorizontalAlignment )
1501 case Toolkit::Alignment::HorizontalLeft:
1503 xPosition = 0.5f * ( offscreenSize.width - textViewSize.width );
1504 parentOrigin.x = 0.f;
1505 anchorPoint.x = 0.f;
1508 case Toolkit::Alignment::HorizontalCenter:
1513 case Toolkit::Alignment::HorizontalRight:
1515 xPosition = 0.5f * ( textViewSize.width - offscreenSize.width );
1516 parentOrigin.x = 1.f;
1517 anchorPoint.x = 1.f;
1522 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1526 switch( mLayoutParameters.mVerticalAlignment )
1528 case Toolkit::Alignment::VerticalTop:
1530 yPosition = 0.5f * ( offscreenSize.height - textViewSize.height );
1531 parentOrigin.y = 0.f;
1532 anchorPoint.y = 0.f;
1535 case Toolkit::Alignment::VerticalCenter:
1540 case Toolkit::Alignment::VerticalBottom:
1542 yPosition = 0.5f * ( textViewSize.height - offscreenSize.height );
1543 parentOrigin.y = 1.f;
1544 anchorPoint.y = 1.f;
1549 DALI_ASSERT_ALWAYS( !"TextView::AlignOffscreenCameraActor: Invalid alignment option." )
1553 mOffscreenCameraActor.SetX( xPosition );
1554 mOffscreenCameraActor.SetY( yPosition );
1556 mOffscreenImageActor.SetParentOrigin( parentOrigin );
1557 mOffscreenImageActor.SetAnchorPoint( anchorPoint );
1560 void TextView::RenderTaskFinished( Dali::RenderTask& renderTask )
1562 // not to process the offscreen root actor by setting its visibility to false.
1563 mOffscreenRootActor.SetVisible( false );
1565 // Sets the new size and the new frame buffer to the image actor.
1566 // Image actor must have same size as text. Otherwise text can be truncated.
1567 mOffscreenImageActor.SetSize( mCurrentOffscreenSize );
1568 mOffscreenImageActor.SetImage( mFrameBufferImage );
1571 void TextView::DestroyOffscreenRenderingResources()
1575 mRenderTask.FinishedSignal().Disconnect( this, &TextView::RenderTaskFinished );
1577 if( Stage::IsInstalled() )
1579 Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
1582 mRenderTask.Reset();
1585 // Remove and reset the root actor, image actor and camera actor as text-view is not rendering offscreen.
1586 if( mOffscreenCameraActor )
1588 mOffscreenRootActor.Remove( mOffscreenCameraActor );
1590 mOffscreenCameraActor.Reset();
1593 if( mOffscreenRootActor )
1595 mOffscreenRootActor.Reset();
1598 if( mOffscreenImageActor )
1600 mOffscreenImageActor.Reset();
1603 mCurrentOffscreenSize = Size( 0.f, 0.f );
1605 if( mFrameBufferImage )
1607 mFrameBufferImage.Reset();
1611 void TextView::OnTextPan( Actor actor, PanGesture gesture )
1613 if( 1u == gesture.numberOfTouches )
1615 DoSetScrollPosition( mVisualParameters.mCameraScrollPosition - gesture.displacement );
1619 void TextView::TrimScrollPosition()
1621 const Vector3& textViewSize = GetControlSize();
1623 // Before use the text's size, relayout the text is needed to get the actual text size.
1624 GetTextLayoutInfo();
1626 // Calculates the range within the text could be scrolled. (When the text is aligned in the center).
1627 float maxHorizontalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.width - textViewSize.width ) );
1628 float maxVerticalDisplacement = std::max( 0.f, 0.5f * ( mRelayoutData.mTextSizeForRelayoutOption.height - textViewSize.height ) );
1629 float minHorizontalDisplacement = -maxHorizontalDisplacement;
1630 float minVerticalDisplacement = -maxVerticalDisplacement;
1632 // Updates the range if the text is aligned on the right or left.
1633 switch( mLayoutParameters.mHorizontalAlignment )
1635 case Toolkit::Alignment::HorizontalLeft:
1637 maxHorizontalDisplacement *= 2.f;
1638 minHorizontalDisplacement = 0.f;
1641 case Toolkit::Alignment::HorizontalCenter:
1646 case Toolkit::Alignment::HorizontalRight:
1648 maxHorizontalDisplacement = 0.f;
1649 minHorizontalDisplacement *= 2.f;
1654 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1658 // Updates the range if the text is aligned on the top or bottom.
1659 switch( mLayoutParameters.mVerticalAlignment )
1661 case Toolkit::Alignment::VerticalTop:
1663 maxVerticalDisplacement *= 2.f;
1664 minVerticalDisplacement = 0.f;
1667 case Toolkit::Alignment::VerticalCenter:
1672 case Toolkit::Alignment::VerticalBottom:
1674 maxVerticalDisplacement = 0.f;
1675 minVerticalDisplacement *= 2.f;
1680 DALI_ASSERT_ALWAYS( !"TextView::TrimScrollPosition: Invalid alignment option." )
1684 // Trims the scroll position to be within the range.
1685 mVisualParameters.mCameraScrollPosition.x = std::min( maxHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1686 mVisualParameters.mCameraScrollPosition.x = std::max( minHorizontalDisplacement, mVisualParameters.mCameraScrollPosition.x );
1688 mVisualParameters.mCameraScrollPosition.y = std::min( maxVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1689 mVisualParameters.mCameraScrollPosition.y = std::max( minVerticalDisplacement, mVisualParameters.mCameraScrollPosition.y );
1692 void TextView::DoSetScrollPosition( const Vector2& position )
1694 // Stores old scroll position.
1695 Vector2 delta( mVisualParameters.mCameraScrollPosition );
1697 // Updates the scroll position
1698 mVisualParameters.mCameraScrollPosition = position;
1700 // Ensures the text-view is covered with text.
1701 TrimScrollPosition();
1703 // Calculate the difference with the previous scroll position
1704 delta.x = mVisualParameters.mCameraScrollPosition.x - delta.x;
1705 delta.y = mVisualParameters.mCameraScrollPosition.y - delta.y;
1707 if( mOffscreenRootActor )
1709 // If there is a render-task it needs to be refreshed. Therefore glyph-actors need to be
1711 mOffscreenRootActor.SetVisible( true );
1714 if( mOffscreenCameraActor )
1716 // Update the offscreen camera with the new scroll position.
1717 mOffscreenCameraActor.SetX( mVisualParameters.mCameraScrollPosition.x );
1718 mOffscreenCameraActor.SetY( mVisualParameters.mCameraScrollPosition.y );
1723 // Refresh the render-task.
1724 mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
1728 Toolkit::TextView handle( GetOwner() );
1729 mScrolledSignalV2.Emit( handle, delta );
1732 void TextView::CombineExceedPolicies()
1734 // Calculates the combination of exceed policies.
1736 switch( mLayoutParameters.mWidthExceedPolicy )
1738 case Toolkit::TextView::Original:
1740 switch( mLayoutParameters.mHeightExceedPolicy )
1742 case Toolkit::TextView::Original:
1744 mLayoutParameters.mExceedPolicy = Original;
1747 case Toolkit::TextView::Fade:
1749 mLayoutParameters.mExceedPolicy = OriginalFade;
1752 case Toolkit::TextView::ShrinkToFit:
1754 mLayoutParameters.mExceedPolicy = OriginalShrink;
1759 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1764 case Toolkit::TextView::Split:
1766 switch( mLayoutParameters.mHeightExceedPolicy )
1768 case Toolkit::TextView::Original:
1770 mLayoutParameters.mExceedPolicy = SplitOriginal;
1773 case Toolkit::TextView::Fade:
1775 mLayoutParameters.mExceedPolicy = SplitFade;
1778 case Toolkit::TextView::ShrinkToFit:
1780 mLayoutParameters.mExceedPolicy = SplitShrink;
1785 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1790 case Toolkit::TextView::Fade:
1792 switch( mLayoutParameters.mHeightExceedPolicy )
1794 case Toolkit::TextView::Original:
1796 mLayoutParameters.mExceedPolicy = FadeOriginal;
1799 case Toolkit::TextView::Fade:
1801 mLayoutParameters.mExceedPolicy = Fade;
1806 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1811 case Toolkit::TextView::ShrinkToFit:
1813 switch( mLayoutParameters.mHeightExceedPolicy )
1815 case Toolkit::TextView::Original:
1817 mLayoutParameters.mExceedPolicy = ShrinkOriginal;
1820 case Toolkit::TextView::Fade:
1822 mLayoutParameters.mExceedPolicy = ShrinkFade;
1825 case Toolkit::TextView::ShrinkToFit:
1827 mLayoutParameters.mExceedPolicy = Shrink;
1832 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1837 case Toolkit::TextView::EllipsizeEnd:
1839 switch( mLayoutParameters.mHeightExceedPolicy )
1841 case Toolkit::TextView::Original:
1843 mLayoutParameters.mExceedPolicy = EllipsizeEndOriginal;
1846 case Toolkit::TextView::EllipsizeEnd:
1848 mLayoutParameters.mExceedPolicy = EllipsizeEnd;
1853 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width and height exceed policies combination" );
1860 DALI_ASSERT_ALWAYS( !"TextView::CombineExceedPolicies() Invalid width exceed policy" );
1865 Actor TextView::GetRootActor() const
1867 // Get the root actor, if text-view was rendering offscreen, or the text-view itself.
1871 if( mVisualParameters.mSnapshotModeEnabled )
1873 rootActor = mOffscreenRootActor;
1883 void TextView::OnMarkupEnabledPeopertySet( Property::Value propertyValue )
1885 bool newValue( propertyValue.Get<bool>() );
1886 if( newValue != IsMarkupProcessingEnabled() )
1888 SetMarkupProcessingEnabled( newValue );
1891 // If markup processing has been enabled, Ensure current text is reprocessed.
1892 const std::string& currentText( GetText() );
1893 if( ! currentText.empty() )
1895 SetText( currentText );
1901 void TextView::OnMultilinePolicyPropertySet( Property::Value propertyValue )
1903 std::string policyName( propertyValue.Get<std::string>() );
1904 if(policyName == "SplitByNewLineChar")
1906 SetMultilinePolicy(Toolkit::TextView::SplitByNewLineChar);
1908 else if(policyName == "SplitByWord")
1910 SetMultilinePolicy(Toolkit::TextView::SplitByWord);
1912 else if(policyName == "SplitByChar")
1914 SetMultilinePolicy(Toolkit::TextView::SplitByChar);
1918 DALI_ASSERT_ALWAYS( !"TextView::OnMultilinePolicyPropertySet(). Invalid Property value." );
1922 void TextView::OnWidthExceedPolicyPropertySet( Property::Value propertyValue )
1924 std::string policyName( propertyValue.Get<std::string>() );
1925 if(policyName == "Original")
1927 SetWidthExceedPolicy(Toolkit::TextView::Original);
1929 else if(policyName == "Truncate")
1931 SetWidthExceedPolicy(Toolkit::TextView::Truncate);
1933 else if(policyName == "Fade")
1935 SetWidthExceedPolicy(Toolkit::TextView::Fade);
1937 else if(policyName == "Split")
1939 SetWidthExceedPolicy(Toolkit::TextView::Split);
1941 else if(policyName == "ShrinkToFit")
1943 SetWidthExceedPolicy(Toolkit::TextView::ShrinkToFit);
1945 else if(policyName == "EllipsizeEnd")
1947 SetWidthExceedPolicy(Toolkit::TextView::EllipsizeEnd);
1951 DALI_ASSERT_ALWAYS( !"TextView::OnWidthExceedPolicyPropertySet(). Invalid Property value." );
1955 void TextView::OnHeightExceedPolicyPropertySet( Property::Value propertyValue )
1957 std::string policyName( propertyValue.Get<std::string>() );
1958 if(policyName == "Original")
1960 SetHeightExceedPolicy(Toolkit::TextView::Original);
1962 else if(policyName == "Truncate")
1964 SetHeightExceedPolicy(Toolkit::TextView::Truncate);
1966 else if(policyName == "Fade")
1968 SetHeightExceedPolicy(Toolkit::TextView::Fade);
1970 else if(policyName == "Split")
1972 SetHeightExceedPolicy(Toolkit::TextView::Split);
1974 else if(policyName == "ShrinkToFit")
1976 SetHeightExceedPolicy(Toolkit::TextView::ShrinkToFit);
1980 DALI_ASSERT_ALWAYS( !"TextView::OnHeightExceedPolicyPropertySet(). Invalid Property value." );
1984 void TextView::OnLineJustificationPropertySet( Property::Value propertyValue )
1986 std::string policyName( propertyValue.Get<std::string>() );
1987 if(policyName == "Left")
1989 SetLineJustification(Toolkit::TextView::Left);
1991 else if(policyName == "Center")
1993 SetLineJustification(Toolkit::TextView::Center);
1995 else if(policyName == "Right")
1997 SetLineJustification(Toolkit::TextView::Right);
1999 else if(policyName == "Justified")
2001 SetLineJustification(Toolkit::TextView::Justified);
2005 DALI_ASSERT_ALWAYS( !"TextView::OnLineJustificationPropertySet(). Invalid Property value." );
2009 void TextView::OnFadeBoundaryPropertySet( Property::Value propertyValue )
2011 Vector4 value( propertyValue.Get<Vector4>() );
2012 DALI_ASSERT_ALWAYS( value.x >= 0 && value.y >= 0 && value.z >= 0 && value.w >= 0
2013 && "TextView::OnFadeBoundaryPropertySet(). Negative value is invalid. " );
2015 Toolkit::TextView::FadeBoundary fadeBoundary( PixelSize( static_cast<unsigned int>( value.x ) ),
2016 PixelSize( static_cast<unsigned int>( value.y ) ),
2017 PixelSize( static_cast<unsigned int>( value.z ) ),
2018 PixelSize( static_cast<unsigned int>( value.w ) ) );
2020 SetFadeBoundary( fadeBoundary );
2023 void TextView::OnAlignmentPropertySet( Property::Index propertyIndex, Property::Value propertyValue )
2025 std::string value( propertyValue.Get<std::string>() );
2027 if( propertyIndex == Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT )
2029 if(value == "HorizontalLeft")
2031 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalLeft;
2033 else if( value == "HorizontalCenter")
2035 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalCenter;
2037 else if( value == "HorizontalRight")
2039 mLayoutParameters.mHorizontalAlignment = Toolkit::Alignment::HorizontalRight;
2043 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2046 else if( propertyIndex == Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT )
2048 if( value == "VerticalTop" )
2050 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalTop;
2052 else if( value == "VerticalCenter")
2054 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalCenter;
2056 else if( value == "VerticalBottom")
2058 mLayoutParameters.mVerticalAlignment = Toolkit::Alignment::VerticalBottom;
2062 DALI_ASSERT_ALWAYS( !"TextView::OnAlignmentPropertySet(). Invalid Property value." );
2068 // If a GetTextLayoutInfo() or GetHeightForWidth() arrives, relayout the text synchronously is needed in order to retrieve the right values.
2069 if( RELAYOUT_ALL != mRelayoutOperations )
2071 mRelayoutOperations = static_cast<RelayoutOperationMask>( mRelayoutOperations |
2072 RELAYOUT_TEXT_ACTOR_UPDATE |
2073 RELAYOUT_ALIGNMENT |
2074 RELAYOUT_VISIBILITY );
2078 std::string TextView::OnHorizontalAlignmentPropertyGet()
2080 if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalLeft )
2082 return "HorizontalLeft";
2084 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalCenter )
2086 return "HorizontalCenter";
2088 else if( mLayoutParameters.mHorizontalAlignment == Toolkit::Alignment::HorizontalRight )
2090 return "HorizontalRight";
2094 DALI_ASSERT_ALWAYS( !"TextView::OnHorizontalAlignmentPropertyGet(). Invalid value." );
2098 std::string TextView::OnVerticalAlignmentPropertyGet()
2100 if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalTop )
2102 return "VerticalTop";
2104 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalCenter )
2106 return "VerticalCenter";
2108 else if( mLayoutParameters.mVerticalAlignment == Toolkit::Alignment::VerticalBottom )
2110 return "VerticalBottom";
2114 DALI_ASSERT_ALWAYS( !"TextView::OnVerticalAlignmentPropertyGet(). Invalid value." );
2118 void TextView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
2120 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2124 TextView& textViewImpl( GetImpl( textView ) );
2127 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2129 textViewImpl.OnMarkupEnabledPeopertySet( value );
2132 case Toolkit::TextView::PROPERTY_TEXT:
2134 textViewImpl.SetText( value.Get<std::string>() );
2137 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2139 textViewImpl.OnMultilinePolicyPropertySet( value );
2142 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2144 textViewImpl.OnWidthExceedPolicyPropertySet( value );
2147 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2149 textViewImpl.OnHeightExceedPolicyPropertySet( value );
2152 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2154 textViewImpl.OnLineJustificationPropertySet( value );
2157 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2159 textViewImpl.OnFadeBoundaryPropertySet( value );
2162 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2164 Dali::PointSize pointSize( value.Get<float>() );
2165 textViewImpl.SetLineHeightOffset(pointSize);
2168 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2169 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2171 textViewImpl.OnAlignmentPropertySet( index, value );
2178 Property::Value TextView::GetProperty( BaseObject* object, Property::Index index )
2180 Property::Value value;
2182 Toolkit::TextView textView = Toolkit::TextView::DownCast( Dali::BaseHandle( object ) );
2186 TextView& textViewImpl( GetImpl( textView ) );
2189 case Toolkit::TextView::PROPERTY_MARKUP_ENABLED:
2191 value = textViewImpl.IsMarkupProcessingEnabled();
2194 case Toolkit::TextView::PROPERTY_TEXT:
2196 value = textViewImpl.GetText();
2199 case Toolkit::TextView::PROPERTY_MULTILINE_POLICY:
2201 value = MULTILINE_POLICY_NAME[ textViewImpl.GetMultilinePolicy() ];
2204 case Toolkit::TextView::PROPERTY_WIDTH_EXCEED_POLICY:
2206 value = EXCEED_POLICY_NAME[ textViewImpl.GetWidthExceedPolicy() ];
2209 case Toolkit::TextView::PROPERTY_HEIGHT_EXCEED_POLICY:
2211 value = EXCEED_POLICY_NAME[ textViewImpl.GetHeightExceedPolicy() ];
2214 case Toolkit::TextView::PROPERTY_LINE_JUSTIFICATION:
2216 value = LINE_JUSTIFICATION_NAME[ textViewImpl.GetLineJustification() ];
2219 case Toolkit::TextView::PROPERTY_FADE_BOUNDARY:
2221 Toolkit::TextView::FadeBoundary boundary = textViewImpl.GetFadeBoundary();
2222 value = Vector4( static_cast<float>( boundary.mLeft.value ),
2223 static_cast<float>( boundary.mRight.value ),
2224 static_cast<float>( boundary.mTop.value ),
2225 static_cast<float>( boundary.mBottom.value ) );
2228 case Toolkit::TextView::PROPERTY_LINE_HEIGHT_OFFSET:
2230 value = textViewImpl.GetLineHeightOffset().value;
2233 case Toolkit::TextView::PROPERTY_HORIZONTAL_ALIGNMENT:
2235 value = textViewImpl.OnHorizontalAlignmentPropertyGet();
2238 case Toolkit::TextView::PROPERTY_VERTICAL_ALIGNMENT:
2240 value = textViewImpl.OnVerticalAlignmentPropertyGet();
2248 } // namespace Internal
2250 } // namespace Toolkit